root/extras/htpasswd.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. strd
  2. getword
  3. my_getline
  4. putline
  5. to64
  6. getpass
  7. add_password
  8. usage
  9. interrupted
  10. main

   1 /*
   2  * htpasswd.c: simple program for manipulating password file for NCSA httpd
   3  *
   4  * Rob McCool
   5  */
   6 
   7 /* Modified 29aug97 by Jef Poskanzer to accept new password on stdin,
   8 ** if stdin is a pipe or file.  This is necessary for use from CGI.
   9 */
  10 
  11 #include <sys/types.h>
  12 #include <stdio.h>
  13 #include <string.h>
  14 #include <signal.h>
  15 #include <stdlib.h>
  16 #include <time.h>
  17 #include <unistd.h>
  18 
  19 #define LF 10
  20 #define CR 13
  21 
  22 #define MAX_STRING_LEN 256
  23 
  24 int tfd;
  25 char temp_template[] = "/tmp/htp.XXXXXX";
  26 
  27 void interrupted(int);
  28 
  29 static char * strd(char *s) {
  30     char *d;
  31 
  32     d=(char *)malloc(strlen(s) + 1);
  33     strcpy(d,s);
  34     return(d);
  35 }
  36 
  37 static void getword(char *word, char *line, char stop) {
  38     int x = 0,y;
  39 
  40     for(x=0;((line[x]) && (line[x] != stop));x++)
  41         word[x] = line[x];
  42 
  43     word[x] = '\0';
  44     if(line[x]) ++x;
  45     y=0;
  46 
  47     while((line[y++] = line[x++]));
  48 }
  49 
  50 static int my_getline(char *s, int n, FILE *f) {
  51     int i=0;
  52 
  53     while(1) {
  54         s[i] = (char)fgetc(f);
  55 
  56         if(s[i] == CR)
  57             s[i] = fgetc(f);
  58 
  59         if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
  60             s[i] = '\0';
  61             return (feof(f) ? 1 : 0);
  62         }
  63         ++i;
  64     }
  65 }
  66 
  67 static void putline(FILE *f,char *l) {
  68     int x;
  69 
  70     for(x=0;l[x];x++) fputc(l[x],f);
  71     fputc('\n',f);
  72 }
  73 
  74 
  75 /* From local_passwd.c (C) Regents of Univ. of California blah blah */
  76 static unsigned char itoa64[] =         /* 0 ... 63 => ascii - 64 */
  77         "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  78 
  79 static void to64(char *s, long v, int n) {
  80     while (--n >= 0) {
  81         *s++ = itoa64[v&0x3f];
  82         v >>= 6;
  83     }
  84 }
  85 
  86 #ifdef MPE
  87 /* MPE lacks getpass() and a way to suppress stdin echo.  So for now, just
  88 issue the prompt and read the results with echo.  (Ugh). */
  89 
  90 char *getpass(const char *prompt) {
  91 
  92 static char password[81];
  93 
  94 fputs(prompt,stderr);
  95 gets((char *)&password);
  96 
  97 if (strlen((char *)&password) > 8) {
  98   password[8]='\0';
  99 }
 100 
 101 return (char *)&password;
 102 }
 103 #endif
 104 
 105 static void
 106 add_password( char* user, FILE* f )
 107     {
 108     char pass[100];
 109     char* pw;
 110     char* cpw;
 111     char salt[3];
 112 
 113     if ( ! isatty( fileno( stdin ) ) )
 114         {
 115         (void) fgets( pass, sizeof(pass), stdin );
 116         if ( pass[strlen(pass) - 1] == '\n' )
 117             pass[strlen(pass) - 1] = '\0';
 118         pw = pass;
 119         }
 120     else
 121         {
 122         pw = strd( (char*) getpass( "New password:" ) );
 123         if ( strcmp( pw, (char*) getpass( "Re-type new password:" ) ) != 0 )
 124             {
 125             (void) fprintf( stderr, "They don't match, sorry.\n" );
 126             if ( tfd != -1 )
 127                 unlink( temp_template );
 128             exit( 1 );
 129             }
 130         }
 131     (void) srandom( (int) time( (time_t*) 0 ) );
 132     to64( &salt[0], random(), 2 );
 133     cpw = crypt( pw, salt );
 134     if (cpw)
 135         (void) fprintf( f, "%s:%s\n", user, cpw );
 136     else
 137         (void) fprintf( stderr, "crypt() returned NULL, sorry\n" );
 138     }
 139 
 140 static void usage(void) {
 141     fprintf(stderr,"Usage: htpasswd [-c] passwordfile username\n");
 142     fprintf(stderr,"The -c flag creates a new file.\n");
 143     exit(1);
 144 }
 145 
 146 void interrupted(int signo) {
 147     (void) signo; /* XXX: gcc */
 148 
 149     fprintf(stderr,"Interrupted.\n");
 150     if(tfd != -1) unlink(temp_template);
 151     exit(1);
 152 }
 153 
 154 int main(int argc, char *argv[]) {
 155     FILE *tfp,*f;
 156     char user[MAX_STRING_LEN];
 157     char line[MAX_STRING_LEN];
 158     char l[MAX_STRING_LEN];
 159     char w[MAX_STRING_LEN];
 160     char command[MAX_STRING_LEN];
 161     int found;
 162 
 163     tfd = -1;
 164     signal(SIGINT,(void (*)(int))interrupted);
 165     if(argc == 4) {
 166         if(strcmp(argv[1],"-c"))
 167             usage();
 168         if(!(tfp = fopen(argv[2],"w"))) {
 169             fprintf(stderr,"Could not open passwd file %s for writing.\n",
 170                     argv[2]);
 171             perror("fopen");
 172             exit(1);
 173         }
 174         printf("Adding password for %s.\n",argv[3]);
 175         add_password(argv[3],tfp);
 176         fclose(tfp);
 177         exit(0);
 178     } else if(argc != 3) usage();
 179 
 180     tfd = mkstemp(temp_template);
 181     if(!(tfp = fdopen(tfd,"w"))) {
 182         fprintf(stderr,"Could not open temp file.\n");
 183         exit(1);
 184     }
 185 
 186     if(!(f = fopen(argv[1],"r"))) {
 187         fprintf(stderr,
 188                 "Could not open passwd file %s for reading.\n",argv[1]);
 189         fprintf(stderr,"Use -c option to create new one.\n");
 190         exit(1);
 191     }
 192     strncpy(user,argv[2],sizeof(user)-1);
 193     user[sizeof(user)-1] = '\0';
 194 
 195     found = 0;
 196     while(!(my_getline(line,MAX_STRING_LEN,f))) {
 197         if(found || (line[0] == '#') || (!line[0])) {
 198             putline(tfp,line);
 199             continue;
 200         }
 201         strcpy(l,line);
 202         getword(w,l,':');
 203         if(strcmp(user,w)) {
 204             putline(tfp,line);
 205             continue;
 206         }
 207         else {
 208             printf("Changing password for user %s\n",user);
 209             add_password(user,tfp);
 210             found = 1;
 211         }
 212     }
 213     if(!found) {
 214         printf("Adding user %s\n",user);
 215         add_password(user,tfp);
 216     }
 217     fclose(f);
 218     fclose(tfp);
 219     sprintf(command,"cp %s %s",temp_template,argv[1]);
 220     system(command);
 221     unlink(temp_template);
 222     exit(0);
 223 }

/* [previous][next][first][last][top][bottom][index][help] */