1: /* popwrd.c - set password for a POP subscriber */ 2: 3: #include "../h/strings.h" 4: #include "../zotnet/bboards.h" 5: #include <errno.h> 6: #include <pwd.h> 7: #include <signal.h> 8: #include <stdio.h> 9: #include <sys/types.h> 10: #include <sys/file.h> 11: 12: 13: static char temp[] = "ptmp"; 14: static char home[BUFSIZ]; 15: 16: extern int errno; 17: 18: char *crypt (), *getpass (), *tail (); 19: 20: #define compar(s,t) (strcmp (s, t) ? s : "") 21: 22: /* */ 23: 24: /* ARGSUSED */ 25: 26: main (argc, argv) 27: int argc; 28: char **argv; 29: { 30: int i, 31: fd, 32: flags, 33: insist; 34: long salt; 35: char c, 36: *cp, 37: buffer[BUFSIZ], 38: saltc[2], 39: **ap; 40: struct bboard *bb, 41: *bp; 42: struct passwd *pw; 43: FILE * fp; 44: 45: if ((pw = getpwnam (POPUID)) == NULL) { 46: fprintf (stderr, "no entry for ~%s.\n", POPUID); 47: exit (1); 48: } 49: if (chdir (strcpy (home, pw -> pw_dir)) < 0) { 50: fprintf (stderr, "no home directory for ~%s.\n", POPUID); 51: exit (1); 52: } 53: if (!setpwinfo (pw, POPDB, 0)) { 54: fprintf (stderr, "setbbinfo(%s, %s, 0) failed -- %s.\n", 55: pw -> pw_name, POPDB, getbberr ()); 56: exit (1); 57: } 58: 59: if (argc != 2) { 60: fprintf (stderr, "usage: %s pop-subscriber\n", *argv); 61: exit (1); 62: } 63: if ((bb = getbbnam (argv[1])) == NULL 64: && (bb = getbbaka (argv[1])) == NULL) { 65: fprintf (stderr, "Permission denied.\n"); 66: exit (1); 67: } 68: 69: if (!ldrbb (bb) && getuid () && !ldrchk (bb)) 70: exit (1); 71: 72: if ((bp = getbbcpy (bb)) == NULL) { 73: fprintf (stderr, "getbbcpy loses.\n"); 74: exit (1); 75: } 76: 77: (void) endbbent (); 78: 79: #ifdef lint 80: flags = 0; 81: #endif lint 82: for (insist = 0; insist < 2; insist++) { 83: if (insist) 84: printf ("Please use %s.\n", 85: flags == 1 ? "at least one non-numeric character" 86: : "a longer password"); 87: 88: if ((i = strlen (strcpy (buffer, getpass ("New password:")))) == 0) { 89: fprintf (stderr, "Password unchanged.\n"); 90: exit (1); 91: } 92: 93: flags = 0; 94: for (cp = buffer; c = *cp++;) 95: if (c >= 'a' && c <= 'z') 96: flags |= 2; 97: else 98: if (c >= 'A' && c <= 'Z') 99: flags |= 4; 100: else 101: if (c >= '0' && c <= '9') 102: flags |= 1; 103: else 104: flags |= 8; 105: 106: if ((flags >= 7 && i >= 4) 107: || ((flags == 2 || flags == 4) && i >= 6) 108: || ((flags == 3 || flags == 5 || flags == 6) && i >= 5)) 109: break; 110: } 111: 112: if (strcmp (buffer, getpass ("Retype new password:"))) { 113: fprintf (stderr, "Mismatch - password unchanged.\n"); 114: exit (1); 115: } 116: 117: (void) time (&salt); 118: salt ^= 9 * getpid (); 119: saltc[0] = salt & 077; 120: saltc[1] = (salt >> 6) & 077; 121: for (i = 0; i < 2; i++) { 122: c = saltc[i] + '.'; 123: if (c > '9') 124: c += 7; 125: if (c > 'Z') 126: c += 6; 127: saltc[i] = c; 128: } 129: cp = crypt (buffer, saltc); 130: 131: (void) signal (SIGHUP, SIG_IGN); 132: (void) signal (SIGINT, SIG_IGN); 133: (void) signal (SIGQUIT, SIG_IGN); 134: 135: (void) umask (0); 136: if ((fd = open (temp, O_WRONLY | O_CREAT | O_EXCL, 0644)) < 0) { 137: switch (errno) { 138: case EEXIST: 139: fprintf (stderr, "POP file busy - try again later.\n"); 140: break; 141: 142: default: 143: perror (temp); 144: break; 145: } 146: exit (1); 147: } 148: 149: (void) signal (SIGTSTP, SIG_IGN); 150: if ((fp = fdopen (fd, "w")) == NULL) { 151: fprintf (stderr, "fdopen loses.\n"); 152: (void) unlink (temp); 153: exit (1); 154: } 155: 156: (void) setbbent (SB_STAY | SB_FAST); 157: while (bb = getbbent ()) { 158: if (strcmp (bb -> bb_name, bp -> bb_name) == 0) 159: bb -> bb_passwd = cp; 160: fprintf (fp, "%s:", bb -> bb_name); 161: if (ap = bb -> bb_aka) 162: for (; *ap; ap++) 163: fprintf (fp, "%s%s", ap != bb -> bb_aka ? "," : "", *ap); 164: fprintf (fp, ":%s:%s:", tail (bb -> bb_file), bb -> bb_passwd); 165: if ((ap = bb -> bb_leader) != NULL 166: && (strcmp (*ap, POPUID) != 0 || ap[1] != NULL)) 167: for (; *ap; ap++) 168: fprintf (fp, "%s%s", ap != bb -> bb_leader ? "," : "", *ap); 169: fprintf (fp, ":%s:%s:%s:", 170: compar (bb -> bb_addr, bb -> bb_name), 171: compar (bb -> bb_request, POPUID), 172: bb -> bb_relay); 173: if (ap = bb -> bb_dist) 174: for (; *ap; ap++) 175: fprintf (fp, "%s%s", ap != bb -> bb_dist ? "," : "", *ap); 176: fprintf (fp, ":%o\n", bb -> bb_flags); 177: } 178: (void) endbbent (); 179: 180: if (rename (temp, POPDB) < 0) { 181: perror ("rename"); 182: (void) unlink (temp); 183: exit (1); 184: } 185: (void) fclose (fp); 186: 187: exit (0); 188: } 189: 190: /* */ 191: 192: char *tail (s) 193: char *s; 194: { 195: int i; 196: char *cp; 197: 198: if (strncmp (s, home, i = strlen (home)) == 0 199: && *(cp = s + i) == '/' 200: && *++cp) 201: return cp; 202: 203: return s; 204: }