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