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