/* This program is used to non-interactivly change a user password It assumes a normal password changing sequence (the password is requested twice). The program is meant to be used like this echo new_password | passwd_chat user_account It receives the password from its standard input, not from its command line. This way, the new password can't be seen from the output of the ps command for example. It is using the normal passwd underneath. Note that the example above is using echo to pipe the new password, which is not a good idea since this will be visible from ps (unless you are using the builtin echo from bash). */ #include #include #include #include int main (int argc, char *argv[]) { int ret = -1; if (argc < 2){ fprintf (stderr,"passwd_chat: automate password changing\n" "\n" "This program is used to non-interactivly change a user password\n" "It assumes a normal password changing sequence (the password is requested\n" "twice).\n" "\n" "The program is meant to be used like this\n" "\n" "echo new_password | passwd_chat user_account\n" "\n" "It receives the password from its standard input, not from its\n" "command line. This way, the new password can't be seen from\n" "the output of the ps command for example.\n" "\n" "It is using the normal passwd underneath. Note that the example above\n" "is using echo to pipe the new password, which is not a good idea\n" "since this will be visible from ps (unless you are using the builtin\n" "echo from bash).\n"); }else{ int tbin[2],tbout[2]; if (pipe(tbin)!=-1 && pipe(tbout)!=-1){ int pid = fork(); if (pid == 0){ dup2 (tbout[1],1); dup2 (tbout[1],2); dup2 (tbin[0],0); close (tbout[1]); close (tbout[0]); close (tbin[1]); close (tbin[0]); argv[0] = (char*)"passwd"; execvp ("passwd",argv); _exit (-1); }else if (pid != -1){ char newpass[100]; int lenpass = read (0,newpass,sizeof(newpass)-1); if (lenpass > 0){ char buf[1000]; int status; //printf ("lenpass %d\n",lenpass); read (tbout[0],buf,sizeof(buf)); write (tbin[1],newpass,lenpass); read (tbout[0],buf,sizeof(buf)); write (tbin[1],newpass,lenpass); if (wait (&status) != -1){ ret = WEXITSTATUS(status); } } } } } return ret; }