]> diplodocus.org Git - nmh/blob - uip/conflict.c
Formatting cleanup.
[nmh] / uip / conflict.c
1
2 /*
3 * conflict.c -- check for conflicts in mail system
4 *
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
8 */
9
10 #include <h/mh.h>
11 #include <fcntl.h>
12 #include <h/aliasbr.h>
13 #include <h/mts.h>
14 #include <h/utils.h>
15 #include <grp.h>
16 #include <pwd.h>
17
18 /*
19 * maximum number of directories that can
20 * be specified using -search switch.
21 */
22 #define NDIRS 100
23
24 /*
25 * Add space for group names, 100 at a time
26 */
27 #define NGRPS 100
28
29 static struct swit switches[] = {
30 #define MAILSW 0
31 { "mail name", 0 },
32 #define SERCHSW 1
33 { "search directory", 0 },
34 #define VERSIONSW 2
35 { "version", 0 },
36 #define HELPSW 3
37 { "help", 0 },
38 { NULL, 0 }
39 };
40
41 static char *mail = NULL;
42 static char *dirs[NDIRS];
43 static FILE *out = NULL;
44
45 extern struct aka *akahead;
46 extern struct home *homehead;
47
48 /*
49 * prototypes
50 */
51 void alias_files (int, char **);
52 void pwd_names (void);
53 void grp_names (void);
54 void grp_members (void);
55 void grp_ids (void);
56 void maildrops (void);
57 void mdrop(char *);
58 int check (char *);
59 void setup (void);
60
61
62 int
63 main (int argc, char **argv)
64 {
65 int akp = 0, dp = 0;
66 char *cp, **argp, **arguments;
67 char buf[BUFSIZ], *akv[50];
68
69 #ifdef LOCALE
70 setlocale(LC_ALL, "");
71 #endif
72 invo_name = r1bindex (argv[0], '/');
73
74 /* foil search of user profile/context */
75 if (context_foil (NULL) == -1)
76 done (1);
77
78 mts_init (invo_name);
79 arguments = getarguments (invo_name, argc, argv, 0);
80 argp = arguments;
81
82 while ((cp = *argp++)) {
83 if (*cp == '-') {
84 switch (smatch (++cp, switches)) {
85 case AMBIGSW:
86 ambigsw (cp, switches);
87 done (1);
88 case UNKWNSW:
89 adios (NULL, "-%s unknown", cp);
90
91 case HELPSW:
92 snprintf (buf, sizeof(buf), "%s [switches] [aliasfiles ...]",
93 invo_name);
94 print_help (buf, switches, 0);
95 done (1);
96 case VERSIONSW:
97 print_version(invo_name);
98 done (1);
99
100 case MAILSW:
101 if (!(cp = *argp++) || *cp == '-')
102 adios (NULL, "missing argument to %s", argp[-2]);
103 if (mail)
104 adios (NULL, "mail to one address only");
105 else
106 mail = cp;
107 continue;
108
109 case SERCHSW:
110 if (!(cp = *argp++) || *cp == '-')
111 adios (NULL, "missing argument to %s", argp[-2]);
112 if (dp >= NDIRS)
113 adios (NULL, "more than %d directories", NDIRS);
114 dirs[dp++] = cp;
115 continue;
116 }
117 }
118 akv[akp++] = cp;
119 }
120
121 if (akp == 0)
122 akv[akp++] = AliasFile;
123 if (!homehead)
124 init_pw ();
125 if (!mail)
126 out = stdout;
127 dirs[dp] = NULL;
128
129 alias_files (akp, akv);
130 pwd_names ();
131 grp_names ();
132 grp_members ();
133 grp_ids ();
134 maildrops ();
135
136 done (0);
137 return 1;
138 }
139
140
141 void
142 alias_files (int akp, char **akv)
143 {
144 register int i, err;
145
146 for (i = 0; i < akp; i++)
147 if ((err = alias (akv[i])) != AK_OK) {
148 setup ();
149 fprintf (out, "aliasing error in %s - %s\n", akv[i], akerror (err));
150 }
151 else
152 if (out && !mail)
153 fprintf (out, "alias file %s is ok\n", akv[i]);
154 }
155
156
157 void
158 pwd_names (void)
159 {
160 int hit = 0;
161 register struct home *hm, *lm;
162
163 for (hm = homehead; hm; hm = hm->h_next)
164 for (lm = hm->h_next; lm; lm = lm->h_next)
165 if (strcmp (hm->h_name, lm->h_name) == 0) {
166 setup ();
167 fprintf (out, "duplicate user %s(uid=%d)\n",
168 lm->h_name, (int) lm->h_uid);
169 hit++;
170 }
171
172 if (!hit && out && !mail)
173 fprintf (out, "no duplicate users\n");
174 }
175
176
177 void
178 grp_names (void)
179 {
180 int numgroups, maxgroups;
181 int i, hit = 0;
182 char **grps;
183 struct group *gr;
184
185 /* allocate space NGRPS at a time */
186 numgroups = 0;
187 maxgroups = NGRPS;
188 grps = (char **) mh_xmalloc((size_t) (maxgroups * sizeof(*grps)));
189
190 setgrent ();
191 while ((gr = getgrent ())) {
192 for (i = 0; i < numgroups; i++)
193 if (!strcmp (grps[i], gr->gr_name)) {
194 setup ();
195 fprintf (out, "duplicate group %s(gid=%d)\n",
196 gr->gr_name, (int) gr->gr_gid);
197 hit++;
198 break;
199 }
200 if (i >= numgroups) {
201 if (numgroups >= maxgroups) {
202 maxgroups += NGRPS;
203 grps = (char **) mh_xrealloc(grps,
204 (size_t) (maxgroups * sizeof(*grps)));
205 }
206 grps[numgroups++] = getcpy (gr->gr_name);
207 }
208 }
209 endgrent ();
210
211 for (i = 0; i < numgroups; i++)
212 free (grps[i]);
213 free (grps);
214
215 if (!hit && out && !mail)
216 fprintf (out, "no duplicate groups\n");
217 }
218
219
220 void
221 grp_members (void)
222 {
223 register int hit = 0;
224 register char **cp, **dp;
225 register struct group *gr;
226 register struct home *hm;
227
228 setgrent ();
229 while ((gr = getgrent ())) {
230 for (cp = gr->gr_mem; *cp; cp++) {
231 for (hm = homehead; hm; hm = hm->h_next)
232 if (!strcmp (*cp, hm->h_name))
233 break;
234 if (hm == NULL) {
235 setup ();
236 fprintf (out, "group %s(gid=%d) has unknown member %s\n",
237 gr->gr_name, (int) gr->gr_gid, *cp);
238 hit++;
239 } else {
240 hm->h_ngrps++;
241 }
242
243 for (dp = cp + 1; *dp; dp++)
244 if (strcmp (*cp, *dp) == 0) {
245 setup ();
246 fprintf (out, "group %s(gid=%d) has duplicate member %s\n",
247 gr->gr_name, (int) gr->gr_gid, *cp);
248 hit++;
249 }
250 }
251 }
252 endgrent ();
253
254 for (hm = homehead; hm; hm = hm->h_next)
255 if (hm->h_ngrps > NGROUPS_MAX) {
256 setup ();
257 fprintf (out, "user %s is a member of %d groups (max %d)\n",
258 hm->h_name, hm->h_ngrps, NGROUPS_MAX);
259 hit++;
260 }
261
262 if (!hit && out && !mail)
263 fprintf (out, "all group members accounted for\n");
264 }
265
266
267 void
268 grp_ids (void)
269 { /* -DRAND not implemented at most places */
270 register int hit = 0;
271 register struct home *hm;
272
273 for (hm = homehead; hm; hm = hm->h_next)
274 if (getgrgid (hm->h_gid) == NULL) {
275 setup ();
276 fprintf (out, "user %s(uid=%d) has unknown group-id %d\n",
277 hm->h_name, (int) hm->h_uid, (int) hm->h_gid);
278 hit++;
279 }
280
281 if (!hit && out && !mail)
282 fprintf (out, "all group-id users accounted for\n");
283 }
284
285
286 void
287 maildrops (void)
288 {
289 register int i;
290
291 if (mmdfldir && *mmdfldir)
292 mdrop (mmdfldir);
293 if (uucpldir && *uucpldir)
294 mdrop (uucpldir);
295 for (i = 0; dirs[i]; i++)
296 mdrop (dirs[i]);
297 }
298
299
300 void
301 mdrop(char *drop)
302 {
303 register int hit = 0;
304 register struct dirent *dp;
305 register DIR *dd = opendir (drop);
306
307 if (!dd) {
308 setup ();
309 fprintf (out, "unable to open maildrop area %s\n", drop);
310 return;
311 }
312
313 while ((dp = readdir (dd)))
314 if (dp->d_name[0] != '.' && !check (dp->d_name)) {
315 setup ();
316 fprintf (out,
317 "there is a maildrop for the unknown user %s in %s\n",
318 dp->d_name, drop);
319 hit++;
320 }
321
322 closedir (dd);
323 if (!hit && out && !mail)
324 fprintf (out, "all maildrops accounted for in %s\n", drop);
325 }
326
327
328 int
329 check (char *s)
330 {
331 register struct home *hm;
332
333 for (hm = homehead; hm; hm = hm->h_next)
334 if (!strcmp (s, hm->h_name))
335 return 1;
336 return 0;
337 }
338
339 void
340 setup (void)
341 {
342 int fd, pd[2];
343
344 if (out)
345 return;
346
347 if (mail) {
348 if (pipe (pd) == NOTOK)
349 adios ("pipe", "unable to");
350
351 switch (fork ()) {
352 case NOTOK:
353 adios ("fork", "unable to");
354
355 case OK:
356 close (pd[1]);
357 if (pd[0] != 0) {
358 dup2 (pd[0], 0);
359 close (pd[0]);
360 }
361 if ((fd = open ("/dev/null", O_WRONLY)) != NOTOK)
362 if (fd != 1) {
363 dup2 (fd, 1);
364 close (fd);
365 }
366 execlp (mailproc, r1bindex (mailproc, '/'),
367 mail, "-subject", invo_name, NULL);
368 adios (mailproc, "unable to exec ");
369
370 default:
371 close (pd[0]);
372 out = fdopen (pd[1], "w");
373 fprintf (out, "%s: the following is suspicious\n\n",
374 invo_name);
375 }
376 }
377 }