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