home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1999 April / PCO0499.ISO / filesbbs / os2 / apach134.arj / APACH134.ZIP / src / support / htpasswd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-07-13  |  4.6 KB  |  229 lines

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