|
setpwd.c C-Language Source Code
/* Set a users password from the command line (AIX)
Name: setpwd.c
Compile using: cc -ls -o setpwd setpwd.c
chown root setpwd
chmod 0455 setpwd
Usage: setpwd [-c] -u userid -p passwd
where -c => clears all flags set in the /etc/security/passwd
file,
equivalent to "-c" flag of pwdadm command
if not specified, the user is forced to change
their
password the next time a login command or an su
command is given for the user
*/
#include
#include
#include
#include
#include
#define PW_CLEARFLG 0x0
/* Variables requried by getopt */
extern int optind;
/* extern char optopt; */
extern int opterr;
extern char *optarg;
int getopt(int argc, char **argv, char *option);
/* Encryption algorithm declaration */
extern char *crypt(char *,char *);
/* Possible characters for the SALT */
#define SALT "abcdefghijklmnopqrstuvwzyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
#define SALT_LENGTH (2)
/* ETC_PASSWD_FILE is the actual password database */
#define ETC_PASSWD_FILE "/etc/passwd"
/*
* Choose a random character from a string
*/
static char random_char(char *ch_list)
{
int no_of_chars;
int index;
no_of_chars = strlen(ch_list);
index = rand()%no_of_chars;
return ch_list[index];
}
/*
* Generate a salt of SALT_LENGTH characters returned as a null terminated
* string. The return code is overwritten on each call so save if required
*/
char *generate_salt()
{
int loop;
static char salt[SALT_LENGTH+1];
for (loop = 0;loop < SALT_LENGTH; loop++)
{
salt[loop]= random_char(SALT);
}
salt[SALT_LENGTH]= '\0';
return salt;
}
/*
* Initialize the random number generated based on the current time as a seed
*/
void initialize_generated_password()
{
time_t ltime;
time(<ime);
srand(ltime);
}
/*
* Encrypt a password using the salt.
*/
char *encrypt_password(password,salt)
char *password;
char *salt;
{
char *pwd;
pwd=crypt(password,salt);
return pwd;
}
/*
* Print a usage message and exit
*/
void usage()
{
fprintf(stderr,"setpwd: Usage: setpwd [-c] -u userid -p password\n");
exit(1);
}
/* Set the users password */
int main(int argc, char **argv)
{
int arg,pwflag=0;
char *user=NULL;
char *password=NULL;
struct userpw newpw;
struct userpw *oldpw;
char *salt;
char *pwd;
struct passwd *etcpasswd;
FILE *passwdfp;
char buffer[BUFSIZ];
char typ[BUFSIZ];
while (arg!=EOF)
{
arg=getopt(argc, argv, "cu:p:");
switch(arg)
{
default:
case '?':
usage();
break;
case 'u':
user=optarg; /* Set the user */
break;
case 'p':
password=optarg; /* Set the password text */
if (strcmp(password,"-")==0) /* Password from stdin ? */
{
fgets(buffer,sizeof(buffer)-1,stdin);
if (strlen(buffer)!=0)
buffer[strlen(buffer)-1]= '\0';
password=buffer;
}
break;
case 'c':
pwflag = 1;
break;
case EOF:
break;
}
}
if (user==NULL && password==NULL)
usage();
/*
* Check that both a user and a password are supplied
*/
if (user==NULL)
{
fprintf(stderr,"setpwd: you must supply a user id using the -u parameter\n");
exit(2);
}
if (password==NULL)
{
fprintf(stderr,"setpwd: you must supply a password using the -p parameter\n");
exit(3);
}
/*
* Now create the entry to update the password
*/
salt=generate_salt();
pwd=encrypt_password(password,salt); /* Encrypted password */
strcpy(newpw.upw_name,user);
newpw.upw_passwd=pwd;
time(&newpw.upw_lastupdate); /* Update time */
if (pwflag)
newpw.upw_flags=PW_CLEARFLG; /* Don't force password change */
else
newpw.upw_flags=PW_ADMCHG; /* Force user to change on next login */
/*
* Open the password database for writing
*/
if (setuserdb (S_WRITE))
{
perror("setuserdb");
fprintf(stderr,"setpwd: cannot open password database for writing\n");
exit(errno);
}
/*
* For a new user, the pasword entry in /etc/passwd is set to '*'
* This means password not set. This must be changed to a '!' to
* mean 'look in /etc/security/passwd'
*/
if (getuserattr (newpw.upw_name, S_PWD, typ, SEC_CHAR))
{
perror("getuserattr");
fprintf(stderr,"setpwd: cannot find user '%s' in password database\n",user);
exit(errno);
}
if (putuserattr (newpw.upw_name, S_PWD, "!", SEC_CHAR))
{
perror("putuserattr");
fprintf(stderr,"setpwd: cannot change password entry to !\n");
exit(errno);
}
if (putuserattr (newpw.upw_name, NULL,NULL, SEC_COMMIT))
{
perror("putuserattr");
fprintf(stderr,"setpwd: cannot commit change to password database\n");
exit(errno);
}
if (enduserdb ())
{
perror("enduserdb");
fprintf(stderr,"setpwd: cannot close password database\n");
exit(errno);
}
/*
* Open the security password database for writing
*/
if (setpwdb (S_WRITE))
{
perror("setpwdb");
fprintf(stderr,"setpwd: cannot open shadow password database for writing\n");
exit(errno);
}
if (putuserpw(&newpw)!=0) /* Enter the password */
{
perror("putuserpw");
fprintf(stderr,"setpwd: cannot set the password information for %s\n",user);
exit(errno);
}
if (endpwdb ())
{
perror("endpwdb");
fprintf(stderr,"setpwd: cannot close security password database\n");
exit(errno);
}
return 0; /* ALL OK */
}
|
|
|