1832765 Members
3273 Online
110045 Solutions
New Discussion

passwd c program

 
Andreas Tsamis
Advisor

passwd c program

I wanted to change a users password inside a C program. I tried the following source code i found on the net but HPUX doesnt use ioctl(TIOCNOTTY). Is there any other way i can do it. I work on HPUX 11i with PA Risc. I would like to avoid altering the password file.

#include
#include
#include
#include
#include
#include
#include

#define PASSWD "passwd"
#define SMBPASSWD "/usr/local/bin/smbpasswd"
#define PROMPT1 "Type a new password: "
#define PROMPT2 "Type the same password again: "
#define MINPWLEN 6
#define STRLEN 1024

int change(char *program, char *user, char *pwd, FILE *mystderr);

int main (int argc,char **argv)
{
int fd;
struct passwd *pwentry;
char name[STRLEN];
char newpw[STRLEN];
int reallyroot = 0;
char *cp;
FILE *mystderr;


/* do we have the appropriate permissions? */
if (geteuid() != 0)
{
fprintf(stderr, "This program cannot run unless it is SUID-root, exiting...\n");
exit(1);
}
if (getuid() == 0)
reallyroot = 1;


/* get the appropriate username */
if (argc > 1)
{
if (reallyroot)
{
/* if root, we can specify a username */
strncpy(name, *++argv, STRLEN);
}
else
{
fprintf(stderr, "Only the root user can specify a name, exiting...\n");
exit(1);
}
}
else
{
/* pick up the current user's username */
if ((pwentry = getpwuid(getuid())) == NULL)
{
fprintf(stderr, "Failed getting name entry for UID=%d, exiting...\n",getuid());
exit(1);
}
strncpy(name, pwentry->pw_name, STRLEN);
}


/* get a password and clean any cr/lf stuff */
if (isatty(0))
{
/* interactive, so use a no-echo prompt twice */
fprintf(stderr, "Changing password for user '%s'\n", name);
cp = getpass(PROMPT1);
strncpy(newpw, cp, STRLEN);
cp = getpass(PROMPT2);
if (strcmp(newpw, cp)) {
fprintf(stderr, "The two versions don't match, exiting...\n");
exit(1);
}
}
else
{
/* noninteractive, so just get it from stdin */
if (read(0, newpw, STRLEN) <= 0)
{
fprintf(stderr, "Failed to read a new password, exiting...\n");
exit(1);
}
}
cp=newpw;
if( *cp!='\n' && *cp!='\r' && cp-newpw<= 0)
{
fprintf(stderr, "No password entered, exiting...\n");
exit(1);
}
if ( ! reallyroot)
{
if (strlen(newpw) < MINPWLEN)
{
fprintf(stderr, "Password must be at least %d characters long, exiting...\n", MINPWLEN);
exit(1);
}
}


/* get a private stderr, then close stderr/stdout to silence pwd programs */
if ((fd = dup(2)) < 0)
{
fprintf(stderr, "Strange! Couldn't dup error-output fd, exiting...\n");
exit(1);
}
if ((mystderr = fdopen(fd, "w")) == NULL)
{
fprintf(stderr, "Strange! Couldn't fdopen new stderr fd, exiting...\n");
exit(1);
}
close(1);
close(2);


/* detach from controlling tty to get password programs to read stdin */
if ((fd = open("/dev/tty", O_RDWR | O_NOCTTY)) >= 0)
{
if (ioctl(fd, TIOCNOTTY) < 0)
{
fprintf(mystderr, "Failed to detach from /dev/tty: %s, exiting...\n",
strerror(errno));
exit(1);
}
close(fd);
}


/* shuffle UIDs for permissions - we know we are running SUID-root */
if (setuid(geteuid()) != 0)
{
fprintf(stderr, "Failed to properly set UID, exiting...\n");
exit(1);
}


/* change the Unix password */
if (isatty(0))
fprintf(mystderr, "Changing Unix password...\n");
if ( ! change(PASSWD, name, newpw, mystderr))
exit(1);
if (isatty(0))
fprintf(mystderr, "\tSuccessfully changed Unix password.\n");


/* change the SMB password */
if (isatty(0))
fprintf(mystderr, "Changing SMB/Windows password...\n");
if ( ! change(SMBPASSWD, name, newpw, mystderr))
exit(1);
if (isatty(0))
fprintf(mystderr, "\tSuccessfully changed SMB/Windows password.\n");


exit(0);
}


int change(char *program,char *user,char *pwd,FILE *mystderr)
{
char cmd[STRLEN];
FILE *cmdpipe;
int status;

/* open a pipe to and then feed the password program, slowly */
strncpy(cmd, program, STRLEN);
strncat(cmd, " ", STRLEN - 1);
strncat(cmd, user, STRLEN - strlen(cmd));
if ((cmdpipe = popen(cmd, "w")) == NULL)
{
fprintf(mystderr, "Failed to open pipe to '%s', exiting...\n", cmd);
return 0;
}
sleep(3);
fprintf(cmdpipe, "%s\n", pwd); fflush(cmdpipe); sleep(2);
fprintf(cmdpipe, "%s\n", pwd); fflush(cmdpipe); sleep(2);
if ((status = pclose(cmdpipe)) != 0)
{
fprintf(mystderr, "Program '%s' returned error code %d, exiting...\n",cmd, status);
return 0;
}

return 1;
}
1 REPLY 1
harry d brown jr
Honored Contributor

Re: passwd c program

Try: http://hpux.cs.utah.edu/hppd/hpux/Sysadmin/npasswd-1.2.4/

TIOCNOTTY is a linux or bsd thing. Do a google on

+TIOCNOTTY +iotcl +hp-ux

live free or die
harry d brown jr
Live Free or Die