/* * htpasswd.c: simple program for manipulating password file for NCSA httpd * * Rob McCool */ /* Modified 29aug97 by Jef Poskanzer to accept new password on stdin, ** if stdin is a pipe or file. This is necessary for use from CGI. */ #include #include #include #include #include #include #include extern char *crypt(const char *key, const char *setting); #define LF 10 #define CR 13 #define MAX_STRING_LEN 256 int tfd; char temp_template[] = "/tmp/htp.XXXXXX"; void interrupted(int); static char * strd(char *s) { char *d; d=(char *)malloc(strlen(s) + 1); strcpy(d,s); return(d); } static 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++])); } static int mygetline(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; } } static void putline(FILE *f,char *l) { int x; for(x=0;l[x];x++) fputc(l[x],f); fputc('\n',f); } /* From local_passwd.c (C) Regents of Univ. of California blah blah */ static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static void to64(register char *s, register long v, register int n) { while (--n >= 0) { *s++ = itoa64[v&0x3f]; v >>= 6; } } #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 static void add_password( char* user, char *pw,char *buf ) { char pass[100]; char* cpw; char salt[3]; (void) srandom( (int) time( (time_t*) 0 ) ); to64( &salt[0], random(), 2 ); cpw = crypt( pw, salt ); (void) sprintf( buf, "%s:%s\n", user, cpw ); } static void usage(void) { fprintf(stderr,"Usage: htpasswd -f filename [-a|-d] username password\n"); fprintf(stderr,"The -f user filename.\n"); fprintf(stderr,"The -a add a user.\n"); fprintf(stderr,"The -d delete a user.\n"); exit(1); } void interrupted(int signo) { fprintf(stderr,"Interrupted.\n"); if(tfd != -1) unlink(temp_template); exit(1); } int main(int argc, char *argv[]) { FILE *tfp,*f; char command[MAX_STRING_LEN]; char buf[4096]; char tmp[4096]; char *p = NULL,*q = NULL; if(argc < 5) usage(); else if(strcmp(argv[1],"-f") || (strcmp(argv[3],"-a") && strcmp(argv[3],"-d"))) usage(); printf("%s %s %s %s %s\n",argv[0],argv[1],argv[2],argv[3],argv[4]); if((f = fopen(argv[2],"r")) == NULL) { if((f = fopen(argv[2],"w")) == NULL) { perror("fopen"); exit(1); } else if((argc == 6) && !strcmp(argv[3],"-a")) { memset(command,0,sizeof(command)); add_password(argv[4],argv[5],command); fprintf(f,"%s",command); fclose(f); return 0; } } else if(!strcmp(argv[3],"-a")) { memset(buf,0,sizeof(buf)); fread(buf,sizeof(buf),1,f); fclose(f); if((p=strstr(buf,argv[4])) && ( *(p+strlen(argv[4])) == ':')) //if the user exist,modify it's password { memset(command,0,sizeof(command)); add_password(argv[4],argv[5],command); strcpy(p,command); } else { p = buf+strlen(buf); memset(command,0,sizeof(command)); add_password(argv[4],argv[5],command); strcpy(p,command); } if((f = fopen(argv[2],"w")) == NULL) { perror("fopen"); exit(1); } fprintf(f,"%s",buf); fclose(f); } else if(!strcmp(argv[3],"-d")) { memset(buf,0,sizeof(buf)); fread(buf,sizeof(buf),1,f); fclose(f); if((p=strstr(buf,argv[4]))) { q = strstr(p,"\n"); q++; memset(tmp,0,sizeof(tmp)); strncpy(tmp,buf,p-buf); if((f = fopen(argv[2],"w")) == NULL) { perror("fopen"); exit(1); } fprintf(f,"%s%s",tmp,q); fclose(f); } } return 0; }