/* * mailpasswd.c: cram-md5 password utility for uw-imapd * Remaked from htpasswd.c for Apache/NCSA httpd * by Takashi Yokoyama */ #include #include #include #ifdef MPE #include #else #include #endif #include #include #include #include #define LF 10 #define CR 13 #define MAX_STRING_LEN 256 char *tn; char *pwdfile = "/etc/cram-md5.pwd"; char *strd(char *s) { char *d; d=(char *)malloc(strlen(s) + 1); strcpy(d,s); return(d); } void getword(char *word, char *line, char stop) { int x = 0,y; for(x=0;((line[x]) && (line[x] != stop));x++) word[x] = line[x]; word[x] = '\0'; if(line[x]) ++x; y=0; while((line[y++] = line[x++])); } int getline(char *s, int n, FILE *f) { register int i=0; while(1) { s[i] = (char)fgetc(f); if(s[i] == CR) s[i] = fgetc(f); if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) { s[i] = '\0'; return (feof(f) ? 1 : 0); } ++i; } } void putline(FILE *f,char *l) { int x; for(x=0;l[x];x++) fputc(l[x],f); fputc('\n',f); } #ifdef MPE /* MPE lacks getpass() and a way to suppress stdin echo. So for now, just issue the prompt and read the results with echo. (Ugh). */ char *getpass(const char *prompt) { static char password[81]; fputs(prompt,stderr); gets((char *)&password); if (strlen((char *)&password) > 8) { password[8]='\0'; } return (char *)&password; } #endif void add_password(char *user, FILE *f) { char *pw; pw = strd((char *) getpass("New password:")); if(strcmp(pw,(char *) getpass("Re-type new password:"))) { fprintf(stderr,"They don't match, sorry.\n"); if(tn) unlink(tn); exit(1); } (void)srand((int)time((time_t *)NULL)); fprintf(f,"%s\t%s\n",user,pw); free(pw); } void interrupted() { fprintf(stderr,"Interrupted.\n"); if(tn) unlink(tn); exit(1); } int main() { FILE *tfp,*f; struct passwd *pwd; char user[MAX_STRING_LEN]; char line[MAX_STRING_LEN]; char l[MAX_STRING_LEN]; char w[MAX_STRING_LEN]; char command[MAX_STRING_LEN]; int found; tn = NULL; signal(SIGINT,(void (*)())interrupted); tn = tmpnam(NULL); if(!(tfp = fopen(tn,"w"))) { fprintf(stderr,"Could not open temp file.\n"); exit(1); } if(!(f = fopen(pwdfile,"r"))) { fprintf(stderr, "Could not open passwd file %s for reading.\n",pwdfile); exit(1); } pwd = getpwuid(getuid()); strcpy(user,pwd->pw_name); found = 0; while(!(getline(line,MAX_STRING_LEN,f))) { if(found || (line[0] == '#') || (!line[0])) { putline(tfp,line); continue; } strcpy(l,line); getword(w,l,'\t'); if(strcmp(user,w)) { putline(tfp,line); continue; } else { printf("Changing POP/APOP/IMAP password for user %s\n",user); add_password(user,tfp); found = 1; } } if(!found) { printf("Adding POP/APOP/IMAP user %s\n",user); add_password(user,tfp); } fclose(f); fclose(tfp); sprintf(command,"cp %s %s",tn,pwdfile); system(command); unlink(tn); }