Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

In need of a password change utility for many users

Status
Not open for further replies.

mitchymartell

IS-IT--Management
Mar 23, 2001
10
US
Does anyone know of a utility or a method of easily changing user account passwords once they have expired ? I have about 75 users on 20+ machines. I, as the admin, will generate new passwords for them every 4months but need a method of doing so other than just running passwd for each account. NIS and NIS+ are not an option for me to use at my site so forget about that.....

thanks for any insights.
 
I got this C source from a free list. I haven't tried it, but I kept it just in case. I'm not sure if it solves all your problems, but I hope it helps.

* Set's a users password from the command line
*
* To compile, run
*
* $ cc -o setpwd setpwd.c -ls
*
*
* History
*
* 6 Oct 93 Overwrite the argv[] entries for passwords to stop
* 'ps' snoopers
* 7 Oct 93 Add call to set the seed
*/
#include <stdio.h>
#include <userpw.h>
#include <usersec.h>
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>

/*
* Variables required by getopt
*/
extern int optind;
/*extern char optopt;*/
extern int opterr;
extern char *optarg;
int getopt(int argc, char **argv, char *option);

/*
* Encryption algorithm declarations
*/
extern char *crypt(char *,char *);

/*
* Possible characters for the salt
*/
#define SALT
&quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXRZ0123456789&quot;
#define SALT_LENGTH (2)

/*
* ETC_PASSWD_FILE is the actual password database
*/
#define ETC_PASSWD_FILE &quot;/etc/passwd&quot;

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

/*
* Initialise the random number generated based on the current time as
* a seed
*/
void initialise_generate_password()
{
time_t ltime;
time(&ltime);
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,&quot;setpwd: Usage setpwd -u userid -p password [-a][-e]\n&quot;);
fprintf(stderr,&quot; -a User not prompted for new
password on first login\n&quot;);
fprintf(stderr,&quot; If password is -, password
read from stdin\n&quot;);
fprintf(stderr,&quot; -e Password already
encypted\n&quot;);
exit(1);
}

/*
* Set the users password
*/
int main(int argc, char **argv)
{
int arg;
char *user=NULL;
char *password=NULL;
struct userpw newpw;
struct userpw *oldpw;
char *salt;
char *pwd;
struct passwd *etcpasswd;
FILE *passwdfp;
char buffer[BUFSIZ];
int noadmchg=FALSE; /* Force user to change when logs in */
int pwdencrypt=TRUE;
char *etc_passwd_entry=&quot;!&quot;;

initialise_generate_password(); /* Set the seed */

while (arg!=EOF)
{
arg=getopt(argc, argv, &quot;u:p:ae&quot;);
switch(arg)
{
default:
case '?':
usage();
break;
case 'u':
user=strdup(optarg); /* Set the user */
memset(argv[optind-1],'\0',strlen(argv[optind-1]));
break;
case 'p':
password=optarg; /* Set the password text */
if (strcmp(password,&quot;-&quot;)==0) /* Password from stdin ? */
{
fgets(buffer,sizeof(buffer)-1,stdin);
if (strlen(buffer)!=0)
buffer[strlen(buffer)-1]='\0';
password=buffer;
}
else
{
password=strdup(password);
memset(argv[optind-1],'\0',strlen(argv[optind-1]));
}
break;
case 'a':
noadmchg=TRUE;
break;
case 'e':
pwdencrypt=FALSE;
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,&quot;setpwd: you must supply a user id using the -u
parameter\n&quot;);
exit(2);
}
if (password==NULL)
{
fprintf(stderr,&quot;setpwd: you must supply a password using the -p
parameter\n&quot;);
exit(3);
}

/*
* Now create the entry to update the password. An empty password
* encrypts to the empty string.
*/
if (!pwdencrypt)
{
etc_passwd_entry=pwd=password;
}
else if (*password!='\0')
{
salt=generate_salt();
pwd=encrypt_password(password,salt); /* Encrypted password */
}
else
{
pwd=&quot;&quot;;
}
strcpy(newpw.upw_name,user);
newpw.upw_passwd=pwd;
time(&newpw.upw_lastupdate); /* Update time */
if (noadmchg)
newpw.upw_flags=0;
else
newpw.upw_flags=PW_ADMCHG; /* Force user to change when next login
*/
if (putuserpw(&newpw)!=0) /* Enter the password */
{
perror(&quot;putuserpw&quot;);
fprintf(stderr,&quot;setpwd: cannot set password information for %s\n&quot;,
user);
exit(errno);
}

/*
* For a new user, the password 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 (setuserdb (S_WRITE))
{
perror(&quot;setuserdb&quot;);
fprintf(stderr,&quot;setpwd: cannot open password database for writing\n&quot;);
exit(errno);
}

if (putuserattr (newpw.upw_name, S_PWD, etc_passwd_entry, SEC_CHAR))
{
perror(&quot;putuserattr&quot;);
fprintf(stderr,&quot;setpwd: cannot change password entry to
%s\n&quot;,etc_passwd_entry);
exit(errno);
}

if (putuserattr (newpw.upw_name, NULL, NULL, SEC_COMMIT))
{
perror(&quot;putuserattr&quot;);
fprintf(stderr,&quot;setpwd: cannot commit changed to password database\n&quot;);
exit(errno);
}

if (enduserdb())
{
perror(&quot;enduserdb&quot;);
fprintf(stderr,&quot;setpwd: cannot close password database\n&quot;);
exit(errno);
}
return 0; /* All o.k. */
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top