/* 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 */ }