--- ../3/poppassd.c 2007-01-16 19:59:06.000000000 +0530 +++ poppassd.c 2007-01-17 18:46:12.000000000 +0530 @@ -66,6 +66,7 @@ #include #include #include +#include #if !__GLIBC__ >= 2 #include #endif @@ -89,6 +90,8 @@ #define POP_NEWPASS 1 #define POP_SKIPASS 2 +char **pamstrings[2]; // 0 - oldpass, 1 - newpass + void WriteToClient (char *fmt, ...) { va_list ap; @@ -115,14 +118,77 @@ line[BUFSIZE-1] = '\0'; } +void showusage(int ret) +{ + if(ret != 0) + WriteToClient ("500 Invalid option given. Use -h option to get more help."); + else + WriteToClient ( +"Usage: poppassd [OPTION]...\n\ +\n\ +-o OLDPASS Add OLDPASS to the list of PAM messages for old password\n\ +-n NEWPASS Add NEWPASS to the list of PAM messages for new password\n\ +\n\ +-h Show this help message and exit\n\ +"); + exit(ret); +} + +void setstrings(int argc, char **argv) +{ + int old=0, new=0, c; + extern int opterr; + + opterr = 0; + while(1) + { + c = getopt(argc, argv, "n:o:h"); + if(c==-1) break; + else if (c=='o') old++; + else if (c=='n') new++; + else if (c=='h') showusage(0); + else showusage(1); + } + + if(argv[optind] != NULL) + showusage(1); + + pamstrings[POP_OLDPASS] = calloc(sizeof(*pamstrings[POP_OLDPASS]), old + 1); + pamstrings[POP_NEWPASS] = calloc(sizeof(*pamstrings[POP_NEWPASS]), new + 1); + if((pamstrings[POP_OLDPASS] == NULL) || (pamstrings[POP_NEWPASS] == NULL)) + { + WriteToClient("500 Could not allocate enough memory"); + exit(1); + } + optind = 1; + + while(1) + { + c = getopt(argc, argv, "n:o:"); + if(c==-1) break; + else if(c=='o') pamstrings[POP_OLDPASS][--old] = optarg; + else if(c=='n') pamstrings[POP_NEWPASS][--new] = optarg; + } +} + static inline int getstate(const char *msg) { + char **pammsg; + /* Interpret possible PAM messages (not including errors) */ + for(pammsg = pamstrings[POP_OLDPASS] ; *pammsg ; pammsg++) + if(!strcmp(msg, *pammsg)) + return POP_OLDPASS; + if(!strcmp(msg, "Password: ")) return POP_OLDPASS; if(!strcmp(msg, "Enter login(LDAP) password: ")) return POP_OLDPASS; + for(pammsg = pamstrings[POP_NEWPASS] ; *pammsg ; pammsg++) + if(!strcmp(msg, *pammsg)) + return POP_NEWPASS; + if(!strcmp(msg, "New password: ")) return POP_NEWPASS; if(!strcmp(msg, "Re-enter new password: ")) @@ -204,6 +270,8 @@ char user[BUFSIZE]; struct passwd *pw, *getpwnam(); pam_handle_t *pamh=NULL; + + setstrings(argc, argv); *user = *oldpass = *newpass = 0;