]> andersk Git - moira.git/blob - dbck/phase2.pc
Check object IDs for user sponsors.
[moira.git] / dbck / phase2.pc
1 /* $Id$
2  *
3  * (c) Copyright 1988-1998 by the Massachusetts Institute of Technology.
4  * For copying and distribution information, please see the file
5  * <mit-copyright.h>.
6  */
7
8 #include <mit-copyright.h>
9 #include <moira.h>
10 #include "dbck.h"
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15
16 EXEC SQL INCLUDE sqlca;
17
18 RCSID("$Header$");
19
20 EXEC SQL WHENEVER SQLERROR DO dbmserr();
21
22 int show_mcm_mach(void *id);
23 int show_mcm_clu(void *id);
24 int show_mcntmap_mach(void *id);
25 int show_mcntmap_cnt(void *id);
26 int show_hostalias(void *id);
27 int show_printer_mach(void *id);
28 int show_printer_server(void *id);
29 int show_printer_loghost(void *id);
30 int show_printer_spool(void *id);
31 int show_printer_quota(void *id);
32 int show_printer_ac(void *id);
33 int show_printer_lpc_acl(void *id);
34 void fix_printer_ac(void *id);
35 void fix_printer_lpc_acl(void *id);
36 void user_check(int id, void *user, void *hint);
37 void clear_user_sponsor(struct user *u);
38 int maybe_fixup_unref_string(int sid, int oid, char *oname, char *table,
39                              char *field, char *idfield);
40 int maybe_fixup_modby(int sid, int oid, char *oname, char *table,
41                       char *field, char *idfield);
42 int maybe_fixup_unref_string2(char *table, char *field, char *rowid, int sid);
43 int maybe_fixup_modby2(char *table, char *field, char *rowid, int id);
44 void pobox_check(int id, struct user *u);
45 void remove_pobox(int id);
46 void fix_smtp_pobox(int id, int sid);
47 void mach_check(int id, void *machine, void *hint);
48 void subnet_check(int id, void *subnet, void *hint);
49 void clear_subnet_owner(struct subnet *s);
50 void clear_mach_owner(struct machine *m);
51 void cluster_check(int id, void *cluster, void *hint);
52 int show_svc(void *id);
53 void list_check(int id, void *list, void *hint);
54 void fix_list_acl(int id);
55 void fix_list_memacl(int id);
56 int show_member_list(void *id);
57 int show_mem_user(void *id);
58 int show_mem_list(void *id);
59 int show_mem_str(void *id);
60 int show_mem_krb(void *id);
61 int show_mem_mach(void *id);
62 void del_mem_user(void *id);
63 void del_mem_list(void *id);
64 void del_mem_str(void *id);
65 void del_mem_krb(void *id);
66 void del_mem_mach(void *id);
67 int show_sh(void *id);
68 void del_sh_mach(void *id);
69 void fsmatch(int id, void *nfsphys, void *filesys);
70 void check_fs(int id, void *filesys, void *hint);
71 void check_nfsphys(int id, void *nfsphys, void *hint);
72 void check_ps(int id, void *printserver, void *hint);
73 void check_container(int id, void *container, void *hint);
74 void fix_container_acl(int id);
75 void fix_container_memacl(int id);
76 int show_fsg_missing(void *id);
77 int show_fsg_type(void *filesys);
78 void fix_fsg_type(void *filesys);
79 int show_fsg_nomember(void *id);
80 int show_quota_nouser(void *id);
81 int show_quota_nolist(void *id);
82 void fix_quota_nouser(void *id);
83 void fix_quota_nolist(void *id);
84 int show_quota_nofs(void *id);
85 void fix_quota_nofs(void *id);
86 int show_quota_wrongpid(void *id);
87 void fix_quota_physid(void *id);
88 int show_srv_user(void *id);
89 int show_srv_list(void *id);
90 void zero_srv_user(void *id);
91 void zero_srv_list(void *id);
92 int show_krb_usr(void *id);
93 int show_krb_str(void *id);
94 int show_pdm_mach(void *id);
95
96 int show_mcm_mach(void *id)
97 {
98   EXEC SQL BEGIN DECLARE SECTION;
99   int iid = (int)id, found = 1;
100   char name[CLUSTERS_NAME_SIZE];
101   EXEC SQL END DECLARE SECTION;
102
103   EXEC SQL DECLARE csr201 CURSOR FOR
104     SELECT clusters.name FROM clusters, mcmap
105     WHERE clusters.clu_id = mcmap.clu_id AND mcmap.mach_id = :iid;
106   EXEC SQL OPEN csr201;
107   while (1)
108     {
109       EXEC SQL FETCH csr201 INTO :name;
110       if (sqlca.sqlcode)
111         break;
112
113       strtrim(name);
114       found = 0;
115       printf("Cluster %s, non-existant machine %d in cluster map\n",
116              name, iid);
117     }
118   EXEC SQL CLOSE csr201;
119   return found;
120 }
121
122 int show_mcm_clu(void *id)
123 {
124   EXEC SQL BEGIN DECLARE SECTION;
125   int iid = (int)id, found = 1;
126   char name[MACHINE_NAME_SIZE];
127   EXEC SQL END DECLARE SECTION;
128
129   EXEC SQL DECLARE csr202 CURSOR FOR
130     SELECT machine.name FROM machine, mcmap
131     WHERE machine.mach_id = mcmap.mach_id AND mcmap.clu_id = :iid;
132   EXEC SQL OPEN csr202;
133   while (1)
134     {
135       EXEC SQL FETCH csr202 INTO :name;
136       if (sqlca.sqlcode)
137         break;
138
139       strtrim(name);
140
141       found = 0;
142       printf("Machine %s, non-existant cluster %d in cluster map\n",
143              name, iid);
144     }
145   EXEC SQL CLOSE csr202;
146   return found;
147 }
148
149 int show_mcntmap_mach(void *id)
150 {
151   EXEC SQL BEGIN DECLARE SECTION;
152   int iid = (int)id, found = 1;
153   char name[CONTAINERS_NAME_SIZE];
154   EXEC SQL END DECLARE SECTION;
155
156   EXEC SQL DECLARE csr_show_mcnt_mach CURSOR FOR
157     SELECT cnt.name FROM container cnt, mcntmap mc
158     WHERE cnt.cnt_id = mc.cnt_id AND mc.mach_id = :iid;
159   EXEC SQL OPEN csr_show_mcnt_mach;
160   while (1)
161     {
162       EXEC SQL FETCH csr_show_mcnt_mach INTO :name;
163       if (sqlca.sqlcode)
164         break;
165
166       strtrim(name);
167       found = 0;
168       printf("Container %s, non-existant machine %d in container map\n",
169              name, iid);
170     }
171   EXEC SQL CLOSE csr_show_mcnt_mach;
172   return found;
173 }
174
175 int show_mcntmap_cnt(void *id)
176 {
177   EXEC SQL BEGIN DECLARE SECTION;
178   int iid = (int)id, found = 1;
179   char name[MACHINE_NAME_SIZE];
180   EXEC SQL END DECLARE SECTION;
181
182   EXEC SQL DECLARE csr_show_mcnt_cnt CURSOR FOR
183     SELECT m.name FROM machine m, mcntmap mc
184     WHERE m.mach_id = mc.mach_id AND mc.cnt_id = :iid;
185   EXEC SQL OPEN csr_show_mcnt_cnt;
186   while (1)
187     {
188       EXEC SQL FETCH csr_show_mcnt_cnt INTO :name;
189       if (sqlca.sqlcode)
190         break;
191
192       strtrim(name);
193
194       found = 0;
195       printf("Machine %s, non-existant container %d in container map\n",
196              name, iid);
197     }
198   EXEC SQL CLOSE csr_show_mcnt_cnt;
199   return found;
200 }
201
202 int show_hostalias(void *id)
203 {
204   EXEC SQL BEGIN DECLARE SECTION;
205   int iid = (int)id, found = 1;
206   char name[HOSTALIAS_NAME_SIZE];
207   EXEC SQL END DECLARE SECTION;
208
209   EXEC SQL DECLARE csr234 CURSOR FOR
210     SELECT name FROM hostalias WHERE mach_id = :iid;
211   EXEC SQL OPEN csr234;
212   while (1)
213     {
214       EXEC SQL FETCH csr234 INTO :name;
215       if (sqlca.sqlcode)
216         break;
217
218       strtrim(name);
219
220       found = 0;
221       printf("Alias %s, non-existant machine %d in hostalias map\n",
222              name, iid);
223     }
224   EXEC SQL CLOSE csr234;
225   return found;
226 }
227
228 int show_printer_mach(void *id)
229 {
230   EXEC SQL BEGIN DECLARE SECTION;
231   int iid = (int)id, found = 1;
232   char name[PRINTERS_NAME_SIZE];
233   EXEC SQL END DECLARE SECTION;
234
235   EXEC SQL DECLARE csr235 CURSOR FOR
236     SELECT name FROM printers WHERE mach_id = :iid;
237   EXEC SQL OPEN csr235;
238   while (1)
239     {
240       EXEC SQL FETCH csr235 INTO :name;
241       if (sqlca.sqlcode)
242         break;
243
244       strtrim(name);
245
246       found = 0;
247       printf("Printer %s, non-existant machine %d in printers table\n",
248              name, iid);
249     }
250   EXEC SQL CLOSE csr235;
251   return found;
252 }
253
254 int show_printer_server(void *id)
255 {
256   EXEC SQL BEGIN DECLARE SECTION;
257   int iid = (int)id, found = 1;
258   char name[PRINTERS_NAME_SIZE];
259   EXEC SQL END DECLARE SECTION;
260
261   EXEC SQL DECLARE csr_sps CURSOR FOR
262     SELECT name FROM printers WHERE mach_id = :iid;
263   EXEC SQL OPEN csr_sps;
264   while (1)
265     {
266       EXEC SQL FETCH csr_sps INTO :name;
267       if (sqlca.sqlcode)
268         break;
269
270       strtrim(name);
271
272       found = 0;
273       printf("Printer %s, non-existant printserver %d in printers table\n",
274              name, iid);
275     }
276   EXEC SQL CLOSE csr_sps;
277   return found;
278 }
279
280 int show_printer_loghost(void *id)
281 {
282   EXEC SQL BEGIN DECLARE SECTION;
283   int iid = (int)id, found = 1;
284   char name[PRINTERS_NAME_SIZE];
285   EXEC SQL END DECLARE SECTION;
286
287   EXEC SQL DECLARE csr236 CURSOR FOR
288     SELECT name FROM printers WHERE loghost = :iid;
289   EXEC SQL OPEN csr236;
290   while (1)
291     {
292       EXEC SQL FETCH csr236 INTO :name;
293       if (sqlca.sqlcode)
294         break;
295
296       strtrim(name);
297
298       found = 0;
299       printf("Printer %s, non-existant spool machine %d in printers table\n",
300              name, iid);
301     }
302   EXEC SQL CLOSE csr236;
303   return found;
304 }
305
306 int show_printer_spool(void *id)
307 {
308   EXEC SQL BEGIN DECLARE SECTION;
309   int iid = (int)id, found = 1;
310   char name[PRINTERS_NAME_SIZE];
311   EXEC SQL END DECLARE SECTION;
312
313   EXEC SQL DECLARE csr237 CURSOR FOR
314     SELECT name FROM printers WHERE rm = :iid;
315   EXEC SQL OPEN csr237;
316   while (1)
317     {
318       EXEC SQL FETCH csr237 INTO :name;
319       if (sqlca.sqlcode)
320         break;
321
322       strtrim(name);
323
324       found = 0;
325       printf("Printer %s, non-existant spool machine %d in printers table\n",
326              name, iid);
327     }
328   EXEC SQL CLOSE csr237;
329   return found;
330 }
331
332 int show_printer_quota(void *id)
333 {
334   EXEC SQL BEGIN DECLARE SECTION;
335   int iid = (int)id, found = 1;
336   char name[PRINTERS_NAME_SIZE];
337   EXEC SQL END DECLARE SECTION;
338
339   EXEC SQL DECLARE csr238 CURSOR FOR
340     SELECT name FROM printers WHERE rq = :iid;
341   EXEC SQL OPEN csr238;
342   while (1)
343     {
344       EXEC SQL FETCH csr238 INTO :name;
345       if (sqlca.sqlcode)
346         break;
347
348       strtrim(name);
349
350       found = 0;
351       printf("Printer %s, non-existant quota server %d in printers table\n",
352              name, iid);
353     }
354   EXEC SQL CLOSE csr238;
355   return found;
356 }
357
358 int show_printer_ac(void *id)
359 {
360   EXEC SQL BEGIN DECLARE SECTION;
361   int iid = (int)id, found = 1;
362   char name[PRINTERS_NAME_SIZE];
363   EXEC SQL END DECLARE SECTION;
364
365   EXEC SQL DECLARE csr239 CURSOR FOR
366     SELECT name FROM printers WHERE ac = :iid;
367   EXEC SQL OPEN csr239;
368   while (1)
369     {
370       EXEC SQL FETCH csr239 INTO :name;
371       if (sqlca.sqlcode)
372         break;
373
374       strtrim(name);
375
376       found = 0;
377       printf("Printer %s, non-existant restrict list %d in printers table\n",
378              name, iid);
379     }
380   EXEC SQL CLOSE csr239;
381   return found;
382 }
383
384 int show_printer_lpc_acl(void *id)
385 {
386   EXEC SQL BEGIN DECLARE SECTION;
387   int iid = (int)id, found = 1;
388   char name[PRINTERS_NAME_SIZE];
389   EXEC SQL END DECLARE SECTION;
390
391   EXEC SQL DECLARE csr240 CURSOR FOR
392     SELECT name FROM printers WHERE lpc_acl = :iid;
393   EXEC SQL OPEN csr240;
394   while (1)
395     {
396       EXEC SQL FETCH csr240 INTO :name;
397       if (sqlca.sqlcode)
398         break;
399
400       strtrim(name);
401
402       found = 0;
403       printf("Printer %s, non-existant lpc ACL %d in printers table\n",
404              name, iid);
405     }
406   EXEC SQL CLOSE csr240;
407   return found;
408 }
409
410 void fix_printer_ac(void *id)
411 {
412   EXEC SQL BEGIN DECLARE SECTION;
413   int rowcount, iid = (int)id;
414   EXEC SQL END DECLARE SECTION;
415
416   EXEC SQL UPDATE printers SET ac = 0 WHERE ac = :iid;
417   rowcount = sqlca.sqlerrd[2];
418   if (rowcount > 0)
419     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
420   else
421     printf("Not fixed\n");
422   modified("printers");
423 }
424
425 void fix_printer_lpc_acl(void *id)
426 {
427   EXEC SQL BEGIN DECLARE SECTION;
428   int rowcount, iid = (int)id;
429   EXEC SQL END DECLARE SECTION;
430
431   EXEC SQL UPDATE printers SET lpc_acl = 0 WHERE lpc_acl = :iid;
432   rowcount = sqlca.sqlerrd[2];
433   if (rowcount > 0)
434     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
435   else
436     printf("Not fixed\n");
437   modified("printers");
438 }
439
440 void user_check(int id, void *user, void *hint)
441 {
442   struct user *u = user;
443
444   u->comment = maybe_fixup_unref_string(u->comment, id, u->login, "users",
445                                         "comments", "users_id");
446
447   u->modby = maybe_fixup_modby(u->modby, id, u->login, "users",
448                                "modby", "users_id");
449
450   u->fmodby = maybe_fixup_modby(u->fmodby, id, u->login, "users",
451                                 "fmodby", "users_id");
452
453   u->pmodby = maybe_fixup_modby(u->pmodby, id, u->login, "users",
454                                 "pmodby", "users_id");
455
456   u->sigwho = maybe_fixup_unref_string(u->sigwho, id, u->login, "users",
457                                        "sigwho", "users_id");
458
459   switch (u->sponsor_type)
460     {
461     case 'U':
462       if (!hash_lookup(users, u->sponsor_id))
463         {
464           printf("User %s has non-existant USER sponsor %d\n",
465                  u->login, u->sponsor_id);
466           if (single_fix("Set to no sponsor", 1))
467             clear_user_sponsor(u);
468         }
469       break;
470     case 'L':
471       if (!hash_lookup(lists, u->sponsor_id))
472         {
473           printf("User %s has non-existant LIST sponsor %d\n",
474                  u->login, u->sponsor_id);
475           if (single_fix("Set to no sponsor", 1))
476             clear_user_sponsor(u);
477         }
478       break;
479     case 'S':
480     case 'K':
481       if (u->sponsor_id)
482         u->sponsor_id = maybe_fixup_unref_string(u->sponsor_id, id, u->login,
483                                                "users", "sponsor_id",
484                                                "users_id");
485       if (u->sponsor_id == 0)
486         clear_user_sponsor(u);
487     }
488
489   pobox_check(id, u);
490 }
491
492 int maybe_fixup_unref_string(int sid, int oid, char *oname, char *table,
493                              char *field, char *idfield)
494 {
495   int ret = (sid < 0) ? -sid : sid, doit = 0, newid;
496   EXEC SQL BEGIN DECLARE SECTION;
497   int rowcount;
498   char stmt_buf[500];
499   EXEC SQL END DECLARE SECTION;
500
501   if ((newid = (int)hash_lookup(string_dups, ret)))
502     {
503       printf("%s entry %s(%d) has a %s with duplicate string %d\n",
504              table, oname, oid, field, ret);
505       if (single_fix("Replace duplicate", 0))
506         {
507           ret = newid;
508           doit = 1;
509         }
510       string_check(ret);
511     }
512   else if (!string_check(ret))
513     {
514       printf("%s entry %s(%d) has a %s with non-existant string %d\n",
515              table, oname, oid, field, ret);
516       if (single_fix("Delete", 1))
517         {
518           ret = 0;
519           doit = 1;
520         }
521     }
522
523   if (doit)
524     {
525       sprintf(stmt_buf, "UPDATE %s SET %s = %d WHERE %s = %d",
526               table, field, (sid < 0) ? -ret : ret, idfield, oid);
527       EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
528       rowcount = sqlca.sqlerrd[2];
529       if (rowcount == 1)
530         printf("Fixed\n");
531       else
532         printf("Not fixed, rowcount = %d\n", rowcount);
533       modified(table);
534     }
535
536   return (sid < 0) ? -ret : ret;
537 }
538
539 int maybe_fixup_modby(int sid, int oid, char *oname, char *table,
540                       char *field, char *idfield)
541 {
542   EXEC SQL BEGIN DECLARE SECTION;
543   char stmt_buf[500];
544   int rowcount;
545   EXEC SQL END DECLARE SECTION;
546
547   if (sid < 0)
548     return maybe_fixup_unref_string(sid, oid, oname, table, field, idfield);
549   else
550     {
551       if (!hash_lookup(users, sid))
552         {
553           printf("%s entry %s(%d) has a %s with non-existant user %d\n",
554                  table, oname, oid, field, sid);
555           if (single_fix("Delete", 1))
556             {
557               sprintf(stmt_buf, "UPDATE %s SET %s = 0 WHERE %s = %d",
558                       table, field, idfield, oid);
559               EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
560               rowcount = sqlca.sqlerrd[2];
561               if (rowcount == 1)
562                 printf("Fixed\n");
563               else
564                 printf("Not fixed, rowcount = %d\n", rowcount);
565               modified(table);
566             }
567           return 0;
568         }
569     }
570   return sid;
571 }
572
573 int maybe_fixup_unref_string2(char *table, char *field, char *rowid, int sid)
574 {
575   int ret = (sid < 0) ? -sid : sid, doit = 0, newid;
576   EXEC SQL BEGIN DECLARE SECTION;
577   int rowcount;
578   char stmt_buf[500];
579   EXEC SQL END DECLARE SECTION;
580
581   if ((newid = (int)hash_lookup(string_dups, ret)))
582     {
583       printf("%s entry has a %s with duplicate string %d\n",
584              table, field, ret);
585       if (single_fix("Replace duplicate", 0))
586         {
587           ret = newid;
588           doit = 1;
589         }
590       string_check(ret);
591     }
592   else if (!string_check(ret))
593     {
594       printf("%s entry has a %s with non-existant string %d\n",
595              table, field, ret);
596       if (single_fix("Clear", 1))
597         {
598           ret = 0;
599           doit = 1;
600         }
601     }
602
603   if (doit)
604     {
605       sprintf(stmt_buf, "UPDATE %s SET %s = %d WHERE rowid = '%s'",
606               table, field, (sid < 0) ? -ret : ret, rowid);
607       EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
608       rowcount = sqlca.sqlerrd[2];
609       if (rowcount == 1)
610         printf("Fixed\n");
611       else
612         printf("Not fixed, rowcount = %d\n", rowcount);
613       modified(table);
614     }
615   return (sid < 0) ? -ret : ret;
616 }
617
618 int maybe_fixup_modby2(char *table, char *field, char *rowid, int id)
619 {
620   EXEC SQL BEGIN DECLARE SECTION;
621   char stmt_buf[500];
622   int rowcount;
623   EXEC SQL END DECLARE SECTION;
624
625   if (id < 0)
626     return maybe_fixup_unref_string2(table, field, rowid, id);
627   else
628     {
629       if (!hash_lookup(users, id))
630         {
631           printf("%s entry has a %s with non-existant user %d\n",
632                  table, field, id);
633           if (single_fix("Clear", 1))
634             {
635               sprintf(stmt_buf, "UPDATE %s SET %s = 0 WHERE rowid = '%s'",
636                       table, field, rowid);
637               EXEC SQL EXECUTE IMMEDIATE :stmt_buf;
638               rowcount = sqlca.sqlerrd[2];
639               if (rowcount == 1)
640                 printf("Fixed\n");
641               else
642                 printf("Not fixed, rowcount = %d\n", rowcount);
643               modified(table);
644             }
645           return 0;
646         }
647     }
648   return 1;
649 }
650
651 void pobox_check(int id, struct user *u)
652 {
653   struct filesys *fs;
654
655   switch (u->potype)
656     {
657     case 'P':
658       if (!hash_lookup(machines, u->pobox_id))
659         {
660           printf("User %s(%s) has P.O.Box on non-existant machine %d\n",
661                  u->login, u->fullname, u->pobox_id);
662           if (single_fix("Delete", 0))
663             {
664               remove_pobox(u->users_id);
665               u->potype = 'N';
666             }
667         }
668       break;
669
670     case 'S':
671       if (hash_lookup(string_dups, u->pobox_id))
672         {
673           printf("User %s(%s) has P.O.Box with duplicate string %d\n",
674                  u->login, u->fullname, u->pobox_id);
675           if (single_fix("Update", 0))
676             {
677               printf("Replacing box_id dup string ID %d with %d\n",
678                      u->pobox_id,
679                      (int)hash_lookup(string_dups, u->pobox_id));
680               u->pobox_id = (int)hash_lookup(string_dups, u->pobox_id);
681               fix_smtp_pobox(u->users_id, u->pobox_id);
682               string_check(u->pobox_id);
683             }
684         }
685       else if (!string_check(u->pobox_id))
686         {
687           printf("User %s(%s) has P.O.Box with non-existant string %d\n",
688                  u->login, u->fullname, u->pobox_id);
689           if (single_fix("Delete", 0))
690             {
691               remove_pobox(u->users_id);
692               u->potype = 'N';
693             }
694         }
695       break;
696
697     case 'I':
698       fs = hash_lookup(filesys, u->pobox_id);
699       if (!fs)
700         {
701           printf("User %s(%s) has P.O.Box on non-existant filesystem %d\n",
702                  u->login, u->fullname, u->pobox_id);
703           if (single_fix("Delete", 0))
704             {
705               remove_pobox(u->users_id);
706               u->potype = 'N';
707             }
708         }
709       else if (fs->type != 'I')
710         {
711           printf("User %s(%s) has IMAP P.O.Box on non-IMAP filesystem %s\n",
712                  u->login, u->fullname, fs->name);
713           if (single_fix("Delete", 0))
714             {
715               remove_pobox(u->users_id);
716               u->potype = 'N';
717             }
718         }
719       break;
720
721     default:
722       ;
723     }
724 }
725
726
727 void remove_pobox(int id)
728 {
729   EXEC SQL BEGIN DECLARE SECTION;
730   int rowcount, iid = (int)id;
731   EXEC SQL END DECLARE SECTION;
732
733   EXEC SQL UPDATE users SET potype = 'NONE' WHERE users.users_id = :iid;
734   rowcount = sqlca.sqlerrd[2];
735   if (rowcount > 0)
736     printf("%d entr%s removed\n", rowcount, rowcount == 1 ? "y" : "ies");
737   else
738     printf("Not removed\n");
739   modified("users");
740 }
741
742 void fix_smtp_pobox(int id, int sid)
743 {
744   EXEC SQL BEGIN DECLARE SECTION;
745   int rowcount, iid = id, isid = sid;
746   EXEC SQL END DECLARE SECTION;
747
748   EXEC SQL UPDATE users SET box_id = :isid WHERE users.users_id = :iid;
749   rowcount = sqlca.sqlerrd[2];
750   if (rowcount > 0)
751     printf("%d entr%s updated\n", rowcount, rowcount == 1 ? "y" : "ies");
752   else
753     printf("Not updated\n");
754   modified("users");
755 }
756
757 void mach_check(int id, void *machine, void *hint)
758 {
759   struct machine *m = machine;
760
761   if (!hash_lookup(subnets, m->snet_id))
762     {
763       printf("Machine %s is on a non-existant subnet %d\n",
764              m->name, m->snet_id);
765       if (single_fix("Move to null-subnet", 1))
766         {
767           EXEC SQL BEGIN DECLARE SECTION;
768           int rowcount, iid = id;
769           EXEC SQL END DECLARE SECTION;
770
771           EXEC SQL UPDATE machine SET snet_id = 0 WHERE mach_id = :iid;
772           rowcount = sqlca.sqlerrd[2];
773           if (rowcount > 0)
774             printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
775           else
776             printf("Not fixed\n");
777           modified("machine");
778         }
779     }
780
781   switch (m->owner_type)
782     {
783     case 'U':
784       if (!hash_lookup(users, m->owner_id))
785         {
786           printf("Machine %s has non-existant USER owner %d\n",
787                  m->name, m->owner_id);
788           if (single_fix("Set to no owner", 1))
789             clear_mach_owner(m);
790         }
791       break;
792     case 'L':
793       if (!hash_lookup(lists, m->owner_id))
794         {
795           printf("Machine %s has non-existant LIST owner %d\n",
796                  m->name, m->owner_id);
797           if (single_fix("Set to no owner", 1))
798             clear_mach_owner(m);
799         }
800       break;
801     case 'S':
802     case 'K':
803       if (m->owner_id)
804         m->owner_id = maybe_fixup_unref_string(m->owner_id, id, m->name,
805                                                "machine", "owner_id",
806                                                "mach_id");
807       if (m->owner_id == 0)
808         clear_mach_owner(m);
809     }
810
811   if (m->acomment)
812     m->acomment = maybe_fixup_unref_string(m->acomment, id, m->name,
813                                            "machine", "acomment", "mach_id");
814   if (m->ocomment)
815     m->ocomment = maybe_fixup_unref_string(m->ocomment, id, m->name,
816                                            "machine", "ocomment", "mach_id");
817
818   m->creator = maybe_fixup_modby(m->creator, id, m->name, "machine",
819                                  "creator", "mach_id");
820   m->modby = maybe_fixup_modby(m->modby, id, m->name, "machine",
821                                "modby", "mach_id");
822 }
823
824 void subnet_check(int id, void *subnet, void *hint)
825 {
826   struct subnet *s = subnet;
827
828   switch (s->owner_type)
829     {
830     case 'U':
831       if (!hash_lookup(users, s->owner_id))
832         {
833           printf("Subnet %s has non-existant USER owner %d\n",
834                  s->name, s->owner_id);
835           if (single_fix("Set to no owner", 1))
836             clear_subnet_owner(s);
837         }
838       break;
839     case 'L':
840       if (!hash_lookup(lists, s->owner_id))
841         {
842           printf("Machine %s has non-existant LIST owner %d\n",
843                  s->name, s->owner_id);
844           if (single_fix("Set to no owner", 1))
845             clear_subnet_owner(s);
846         }
847       break;
848     case 'S':
849     case 'K':
850       if (s->owner_id)
851         s->owner_id = maybe_fixup_unref_string(s->owner_id, id, s->name,
852                                                "machine", "owner_id",
853                                                "mach_id");
854       if (s->owner_id == 0)
855         clear_subnet_owner(s);
856     }
857
858   s->modby = maybe_fixup_modby(s->modby, id, s->name, "subnet",
859                                "modby", "snet_id");
860 }
861
862 void clear_user_sponsor(struct user *u)
863 {
864   EXEC SQL BEGIN DECLARE SECTION;
865   int rowcount, id = u->users_id;
866   EXEC SQL END DECLARE SECTION;
867
868   EXEC SQL UPDATE users SET sponsor_type = 'NONE', sponsor_id = 0
869     WHERE users_id = :id;
870   rowcount = sqlca.sqlerrd[2];
871   if (rowcount > 0)
872     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
873   else
874     printf("Not fixed\n");
875   modified("users");
876 }
877
878 void clear_subnet_owner(struct subnet *s)
879 {
880   EXEC SQL BEGIN DECLARE SECTION;
881   int rowcount, id = s->snet_id;
882   EXEC SQL END DECLARE SECTION;
883
884   EXEC SQL UPDATE subnet SET owner_type = 'NONE', owner_id = 0
885     WHERE snet_id = :id;
886   rowcount = sqlca.sqlerrd[2];
887   if (rowcount > 0)
888     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
889   else
890     printf("Not fixed\n");
891   modified("subnet");
892 }
893
894 void clear_mach_owner(struct machine *m)
895 {
896   EXEC SQL BEGIN DECLARE SECTION;
897   int rowcount, id = m->mach_id;
898   EXEC SQL END DECLARE SECTION;
899
900   EXEC SQL UPDATE machine SET owner_type = 'NONE', owner_id = 0
901     WHERE mach_id = :id;
902   rowcount = sqlca.sqlerrd[2];
903   if (rowcount > 0)
904     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
905   else
906     printf("Not fixed\n");
907   modified("machine");
908 }
909
910 void cluster_check(int id, void *cluster, void *hint)
911 {
912   struct cluster *c = cluster;
913
914   c->modby = maybe_fixup_modby(c->modby, id, c->name, "clusters",
915                                "modby", "clu_id");
916 }
917
918 int show_svc(void *id)
919 {
920   EXEC SQL BEGIN DECLARE SECTION;
921   int iid = (int)id, found = 1;
922   char label[SVC_SERV_LABEL_SIZE], data[SVC_SERV_CLUSTER_SIZE];
923   EXEC SQL END DECLARE SECTION;
924
925   EXEC SQL DECLARE csr203 CURSOR FOR
926     SELECT serv_label, serv_cluster FROM svc
927     WHERE clu_id = :iid;
928   EXEC SQL OPEN csr203;
929   while (1)
930     {
931       EXEC SQL FETCH csr203 INTO :label, :data;
932       if (sqlca.sqlcode)
933         break;
934
935       strtrim(label);
936       strtrim(data);
937       found = 0;
938       printf("Cluster data [%s] %s for non-existant cluster %d\n",
939              label, data, iid);
940     }
941   EXEC SQL CLOSE csr203;
942   return found;
943 }
944
945 void list_check(int id, void *list, void *hint)
946 {
947   struct list *l = list;
948
949   l->modby = maybe_fixup_modby(l->modby, id, l->name, "list",
950                                "modby", "list_id");
951
952   switch (l->acl_type)
953     {
954     case 'L':
955       if (!hash_lookup(lists, l->acl_id))
956         {
957           printf("List %s has bad LIST acl %d\n", l->name, l->acl_id);
958           if (single_fix("Patch", 1))
959             fix_list_acl(l->list_id);
960         }
961       break;
962     case 'U':
963       if (!hash_lookup(users, l->acl_id))
964         {
965           printf("List %s has bad USER acl %d\n", l->name, l->acl_id);
966           if (single_fix("Patch", 1))
967             fix_list_acl(l->list_id);
968         }
969       break;
970     case 'K':
971       l->acl_id = maybe_fixup_unref_string(l->acl_id, id, l->name,
972                                            "list", "acl_id", "list_id");
973       if (!l->acl_id)
974         {
975           printf("List %s has bad KERBEROS acl %d\n", l->name, l->acl_id);
976           if (single_fix("Patch", 1))
977             fix_list_acl(l->list_id);
978         }
979       break;
980     }
981
982   switch (l->memacl_type)
983     {
984     case 'L':
985       if (!hash_lookup(lists, l->memacl_id))
986         {
987           printf("List %s has bad LIST memacl %d\n", l->name, l->memacl_id);
988           if (single_fix("Patch", 1))
989             fix_list_memacl(l->list_id);
990         }
991       break;
992     case 'U':
993       if (!hash_lookup(users, l->memacl_id))
994         {
995           printf("List %s has bad USER acl %d\n", l->name, l->memacl_id);
996           if (single_fix("Patch", 1))
997             fix_list_memacl(l->list_id);
998         }
999       break;
1000     case 'K':
1001       l->memacl_id = maybe_fixup_unref_string(l->memacl_id, id, l->name,
1002                                               "list", "memacl_id", "list_id");
1003           if (!l->memacl_id)
1004             {
1005               printf("List %s has bad KERBEROS acl %d\n", l->name, 
1006                      l->memacl_id);
1007               if (single_fix("Patch", 1))
1008                 fix_list_memacl(l->list_id);
1009             }
1010           break;
1011     }
1012 }
1013
1014 void fix_list_acl(int id)
1015 {
1016   EXEC SQL BEGIN DECLARE SECTION;
1017   int rowcount, iid = (int)id;
1018   EXEC SQL END DECLARE SECTION;
1019
1020   EXEC SQL UPDATE list SET acl_id = :iid, acl_type = 'LIST'
1021     WHERE list_id = :iid;
1022   rowcount = sqlca.sqlerrd[2];
1023   if (rowcount > 0)
1024     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1025   else
1026     printf("Not fixed\n");
1027   modified("list");
1028 }
1029
1030 void fix_list_memacl(int id)
1031 {
1032   EXEC SQL BEGIN DECLARE SECTION;
1033   int rowcount, iid = (int)id;
1034   EXEC SQL END DECLARE SECTION;
1035
1036   EXEC SQL UPDATE list SET memacl_id = 0, memacl_type = 'NONE'
1037     WHERE list_id = :iid;
1038   rowcount = sqlca.sqlerrd[2];
1039   if (rowcount > 0)
1040     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1041   else
1042     printf("Not fixed\n");
1043   modified("list");
1044 }
1045
1046 int show_member_list(void *id)
1047 {
1048   EXEC SQL BEGIN DECLARE SECTION;
1049   int mid, iid = (int)id, found = 1;
1050   char mtype[IMEMBERS_MEMBER_TYPE_SIZE], *name = NULL;
1051   EXEC SQL END DECLARE SECTION;
1052
1053   EXEC SQL DECLARE csr204 CURSOR FOR
1054     SELECT member_type, member_id FROM imembers
1055     WHERE list_id = :iid;
1056   EXEC SQL OPEN csr204;
1057   while (1)
1058     {
1059       EXEC SQL FETCH csr204 INTO :mtype, :mid;
1060       if (sqlca.sqlcode)
1061         break;
1062
1063       strtrim(mtype);
1064       found = 0;
1065       if (mtype[0] == 'L')
1066         {
1067           struct list *l = hash_lookup(lists, mid);
1068           if (l)
1069             name = l->name;
1070         }
1071       else if (mtype[0] == 'U')
1072         {
1073           struct user *u = hash_lookup(users, mid);
1074           if (u)
1075             name = u->login;
1076         }
1077       else if (mtype[0] == 'S' || mtype[0] == 'K')
1078         {
1079           struct string *s = hash_lookup(strings, mid);
1080           if (s)
1081             name = s->name;
1082         }
1083       if (name)
1084         printf("Non-existant list %d has member %s %s\n", iid, mtype, name);
1085       else
1086         {
1087           printf("Non-existant list %d has non-existent member %s %d\n",
1088                  iid, mtype, mid);
1089         }
1090     }
1091   EXEC SQL CLOSE csr204;
1092   return found;
1093 }
1094
1095 int show_mem_user(void *id)
1096 {
1097   EXEC SQL BEGIN DECLARE SECTION;
1098   int lid, iid = (int)id, found = 1;
1099   EXEC SQL END DECLARE SECTION;
1100   struct list *l;
1101
1102   EXEC SQL DECLARE csr205 CURSOR FOR
1103     SELECT list_id FROM imembers
1104     WHERE member_id = :iid AND member_type = 'USER';
1105   EXEC SQL OPEN csr205;
1106   while (1)
1107     {
1108       EXEC SQL FETCH csr205 INTO :lid;
1109       if (sqlca.sqlcode)
1110         break;
1111       l = hash_lookup(lists, lid);
1112       if (!l)
1113         continue;
1114
1115       found = 0;
1116       printf("List %s has non-existant user member, id %d\n", l->name, iid);
1117     }
1118   EXEC SQL CLOSE csr205;
1119   return found;
1120 }
1121
1122 int show_mem_list(void *id)
1123 {
1124   EXEC SQL BEGIN DECLARE SECTION;
1125   int lid, iid = (int)id, found = 1;
1126   EXEC SQL END DECLARE SECTION;
1127   struct list *l;
1128
1129   EXEC SQL DECLARE csr206 CURSOR FOR
1130     SELECT list_id FROM imembers
1131     WHERE member_id = :iid AND member_type = 'LIST';
1132   EXEC SQL OPEN csr206;
1133   while (1)
1134     {
1135       EXEC SQL FETCH csr206 INTO :lid;
1136       if (sqlca.sqlcode)
1137         break;
1138       l = hash_lookup(lists, lid);
1139       if (!l)
1140         continue;
1141
1142       found = 0;
1143       printf("List %s has non-existant list member, id %d\n", l->name, iid);
1144     }
1145   EXEC SQL CLOSE csr206;
1146   return found;
1147 }
1148
1149 int show_mem_str(void *id)
1150 {
1151   EXEC SQL BEGIN DECLARE SECTION;
1152   int lid, iid = (int)id, found = 1;
1153   EXEC SQL END DECLARE SECTION;
1154   struct list *l;
1155
1156   EXEC SQL DECLARE csr207 CURSOR FOR
1157     SELECT list_id FROM imembers
1158     WHERE member_id = :iid AND member_type = 'STRING';
1159   EXEC SQL OPEN csr207;
1160   while (1)
1161     {
1162       EXEC SQL FETCH csr207 INTO :lid;
1163       if (sqlca.sqlcode)
1164         break;
1165       l = hash_lookup(lists, lid);
1166       if (!l)
1167         continue;
1168
1169       found = 0;
1170       printf("List %s has non-existant string member, id %d\n", l->name, iid);
1171     }
1172   EXEC SQL CLOSE csr207;
1173   return found;
1174 }
1175
1176
1177 int show_mem_krb(void *id)
1178 {
1179   EXEC SQL BEGIN DECLARE SECTION;
1180   int lid, iid = (int)id, found = 1;
1181   EXEC SQL END DECLARE SECTION;
1182   struct list *l;
1183
1184   EXEC SQL DECLARE csr208 CURSOR FOR
1185     SELECT list_id FROM imembers
1186     WHERE member_id = :iid AND member_type = 'KERBEROS';
1187   EXEC SQL OPEN csr208;
1188   while (1)
1189     {
1190       EXEC SQL FETCH csr208 INTO :lid;
1191       if (sqlca.sqlcode)
1192         break;
1193       l = hash_lookup(lists, lid);
1194       if (!l)
1195         continue;
1196
1197       found = 0;
1198       printf("List %s has non-existant kerberos member, id %d\n",
1199              l->name, iid);
1200     }
1201   EXEC SQL CLOSE csr208;
1202   return found;
1203 }
1204
1205 int show_mem_mach(void *id)
1206 {
1207   EXEC SQL BEGIN DECLARE SECTION;
1208   int lid, iid = (int)id, found = 1;
1209   EXEC SQL END DECLARE SECTION;
1210   struct list *l; 
1211
1212   EXEC SQL DECLARE csr208a CURSOR FOR
1213     SELECT list_id FROM imembers
1214     WHERE member_id = :iid AND member_type = 'MACHINE';
1215   EXEC SQL OPEN csr208a;
1216   while (1)
1217     {
1218       EXEC SQL FETCH csr208a INTO :lid;
1219       if (sqlca.sqlcode)
1220         break;
1221       l = hash_lookup(lists, lid);
1222       if (!l)
1223         continue;
1224
1225       found = 0;
1226       printf("List %s has nonexistant machine member, id %d\n",
1227              l->name, iid);
1228     }
1229   EXEC SQL CLOSE csr208a;
1230   return found;
1231 }
1232
1233 void del_mem_user(void *id)
1234 {
1235   EXEC SQL BEGIN DECLARE SECTION;
1236   int iid = (int)id, rowcount;
1237   EXEC SQL END DECLARE SECTION;
1238
1239   EXEC SQL DELETE FROM imembers WHERE member_type = 'USER' AND
1240     member_id = :iid;
1241   rowcount = sqlca.sqlerrd[2];
1242   if (rowcount > 0)
1243     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1244   else
1245     printf("Not deleted\n");
1246   modified("imembers");
1247 }
1248
1249 void del_mem_list(void *id)
1250 {
1251   EXEC SQL BEGIN DECLARE SECTION;
1252   int iid = (int)id, rowcount;
1253   EXEC SQL END DECLARE SECTION;
1254
1255   EXEC SQL DELETE FROM imembers WHERE member_type = 'LIST' AND
1256     member_id = :iid;
1257   rowcount = sqlca.sqlerrd[2];
1258   if (rowcount > 0)
1259     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1260   else
1261     printf("Not deleted\n");
1262   modified("imembers");
1263 }
1264
1265 void del_mem_str(void *id)
1266 {
1267   EXEC SQL BEGIN DECLARE SECTION;
1268   int iid = (int)id, rowcount;
1269   EXEC SQL END DECLARE SECTION;
1270
1271   EXEC SQL DELETE FROM imembers WHERE member_type = 'STRING' AND
1272     member_id = :iid;
1273   rowcount = sqlca.sqlerrd[2];
1274   if (rowcount > 0)
1275     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1276   else
1277     printf("Not deleted\n");
1278   modified("imembers");
1279 }
1280
1281
1282 void del_mem_krb(void *id)
1283 {
1284   EXEC SQL BEGIN DECLARE SECTION;
1285   int iid = (int)id, rowcount;
1286   EXEC SQL END DECLARE SECTION;
1287
1288   EXEC SQL DELETE FROM imembers WHERE member_type = 'KERBEROS' AND
1289     member_id = :iid;
1290   rowcount = sqlca.sqlerrd[2];
1291   if (rowcount > 0)
1292     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1293   else
1294     printf("Not deleted\n");
1295   modified("imembers");
1296 }
1297
1298 void del_mem_mach(void *id)
1299 {
1300   EXEC SQL BEGIN DECLARE SECTION;
1301   int iid = (int)id, rowcount;
1302   EXEC SQL END DECLARE SECTION;
1303
1304   EXEC SQL DELETE FROM imembers WHERE member_type = 'MACHINE' AND
1305     member_id = :iid;
1306   rowcount = sqlca.sqlerrd[2];
1307   if (rowcount > 0)
1308     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1309   else
1310     printf("Not deleted\n");
1311   modified("imembers");
1312 }
1313
1314 int show_sh(void *id)
1315 {
1316   EXEC SQL BEGIN DECLARE SECTION;
1317   char name[SERVERHOSTS_SERVICE_SIZE];
1318   int iid = (int)id;
1319   EXEC SQL END DECLARE SECTION;
1320   int found = 1;
1321
1322   EXEC SQL DECLARE csr209 CURSOR FOR
1323     SELECT service FROM serverhosts
1324     WHERE mach_id = :iid;
1325   EXEC SQL OPEN csr209;
1326   while (1)
1327     {
1328       EXEC SQL FETCH csr209 INTO :name;
1329       if (sqlca.sqlcode)
1330         break;
1331
1332       found = 0;
1333       printf("ServerHost entry for service %s non-existant host %d\n",
1334              name, iid);
1335     }
1336   EXEC SQL CLOSE csr209;
1337   return found;
1338 }
1339
1340 void del_sh_mach(void *id)
1341 {
1342   EXEC SQL BEGIN DECLARE SECTION;
1343   int iid = (int)id, rowcount;
1344   EXEC SQL END DECLARE SECTION;
1345
1346   EXEC SQL DELETE FROM serverhosts WHERE mach_id = :iid;
1347   rowcount = sqlca.sqlerrd[2];
1348   if (rowcount > 0)
1349     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1350   else
1351     printf("Not deleted\n");
1352   modified("serverhosts");
1353 }
1354
1355
1356 static int fnchecklen;
1357
1358 void fsmatch(int id, void *nfsphys, void *filesys)
1359 {
1360   struct nfsphys *n = nfsphys;
1361   struct filesys *f = filesys;
1362
1363   if (n->mach_id == f->mach_id &&
1364       !strncmp(f->dir, n->dir, strlen(n->dir)) &&
1365       strlen(n->dir) > fnchecklen)
1366     {
1367       f->phys_id = id;
1368       fnchecklen = strlen(n->dir);
1369     }
1370 }
1371
1372
1373 void check_fs(int id, void *filesys, void *hint)
1374 {
1375   EXEC SQL BEGIN DECLARE SECTION;
1376   int iid = id, id1, id2, id3, rowcount;
1377   char *dir;
1378   EXEC SQL END DECLARE SECTION;
1379   struct filesys *f = filesys;
1380   struct nfsphys *n;
1381   struct machine *m;
1382
1383   if (!hash_lookup(machines, f->mach_id))
1384     {
1385       printf("Filesys %s with bad machine %d\n", f->name, f->mach_id);
1386       if (single_fix("Fix", 0))
1387         {
1388           EXEC SQL UPDATE filesys SET mach_id = 0 WHERE filsys_id = :iid;
1389           rowcount = sqlca.sqlerrd[2];
1390           if (rowcount > 0)
1391             printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1392           else
1393             printf("Not fixed\n");
1394           modified("filesys");
1395           f->mach_id = 0;
1396         }
1397     }
1398
1399   if (!hash_lookup(users, f->owner))
1400     {
1401       printf("Filesys %s with bad owning user %d\n", f->name, f->owner);
1402       if (single_fix("Fix", 1))
1403         {
1404           zero_fix("filesys", "owner", "filsys_id", f->filsys_id);
1405           f->owner = 0;
1406         }
1407     }
1408   if (!hash_lookup(lists, f->owners))
1409     {
1410       printf("Filesys %s with bad owning group %d\n", f->name, f->owners);
1411       if (single_fix("Fix", 1))
1412         {
1413           zero_fix("filesys", "owners", "filsys_id", f->filsys_id);
1414           f->owners = 0;
1415         }
1416     }
1417
1418   if (f->type == 'N' || f->type == 'I')
1419     {
1420       if (!hash_lookup(nfsphys, f->phys_id))
1421         {
1422           m = hash_lookup(machines, f->mach_id);
1423           printf("Filesys %s with bad phys_id %d\n", f->name, f->phys_id);
1424           if (single_fix("Fix", 1))
1425             {
1426               fnchecklen = 0;
1427               hash_step(nfsphys, fsmatch, f);
1428               if (fnchecklen != 0)
1429                 {
1430                   id1 = f->phys_id;
1431                   id2 = f->filsys_id;
1432                   id3 = f->mach_id;
1433                   EXEC SQL UPDATE filesys SET phys_id = :id1
1434                     WHERE filsys_id = :id2;
1435                   rowcount = sqlca.sqlerrd[2];
1436                   if (rowcount > 0)
1437                     printf("%d entr%s fixed\n", rowcount,
1438                            rowcount == 1 ? "y" : "ies");
1439                   else
1440                     printf("Not fixed\n");
1441                   modified("filesys");
1442                 }
1443               else
1444                 {
1445                   printf("No NFSphys exsits for %s:%s\n", m->name, f->dir);
1446                   if (single_fix("Create", 0))
1447                     {
1448                       dir = f->dir;
1449                       id1 = f->phys_id;
1450                       id2 = f->filsys_id;
1451                       id3 = f->mach_id;
1452                       if (set_next_object_id("nfsphys_id", "nfsphys") !=
1453                           MR_SUCCESS)
1454                         {
1455                           printf("Unable to assign unique ID\n");
1456                           return;
1457                         }
1458                       EXEC SQL SELECT COUNT(*) INTO :rowcount FROM numvalues
1459                         WHERE name = 'nfsphys_id';
1460                       if (rowcount != 1)
1461                         {
1462                           printf("Unable to retrieve unique ID\n");
1463                           return;
1464                         }
1465                       EXEC SQL INSERT INTO nfsphys
1466                         (nfsphys_id, mach_id, device, dir, status, allocated,
1467                          size, modtime, modby, modwith) VALUES
1468                         (:id1, :id3, '\?\?\?', :dir, 0, 0, 0, SYSDATE, 0,
1469                          'dbck');
1470                         rowcount = sqlca.sqlerrd[2];
1471                         if (rowcount > 0)
1472                           {
1473                             printf("%d entr%s created\n", rowcount,
1474                                    rowcount == 1 ? "y" : "ies");
1475                           }
1476                         else
1477                           printf("Not created\n");
1478                         modified("nfsphys");
1479                         n = malloc(sizeof(struct nfsphys));
1480                         if (!n)
1481                           out_of_mem("storing new nfsphys");
1482                         strcpy(n->dir, dir);
1483                         n->mach_id = id3;
1484                         n->nfsphys_id = id1;
1485                         n->allocated = 0;
1486                         n->count = 0;
1487                         if (hash_store(nfsphys, id1, n) == -1)
1488                           out_of_mem("storing nfsphys in hash table");
1489                         EXEC SQL UPDATE filesys SET phys_id = :id1
1490                           WHERE filsys_id = :id2;
1491                         rowcount = sqlca.sqlerrd[2];
1492                         if (rowcount > 0)
1493                           {
1494                             printf("%d filesys entr%s fixed\n", rowcount,
1495                                    rowcount == 1 ? "y" : "ies");
1496                           }
1497                         else
1498                           printf("Not fixed\n");
1499                         modified("filesys");
1500                     }
1501                 }
1502             }
1503         }
1504     }
1505 }
1506
1507 void check_nfsphys(int id, void *nfsphys, void *hint)
1508 {
1509   struct nfsphys *n = nfsphys;
1510
1511   n->modby = maybe_fixup_modby(n->modby, id, n->dir, "nfsphys",
1512                                "modby", "nfsphys_id");
1513
1514   if (!hash_lookup(machines, n->mach_id))
1515     {
1516       printf("NFSphys %d(%s) on non-existant machine %d\n",
1517              id, n->dir, n->mach_id);
1518       if (single_fix("Delete", 0))
1519         single_delete("nfsphys", "nfsphys_id", id);
1520     }
1521 }
1522
1523 static void clear_ps_owner(struct printserver *ps)
1524 {
1525   EXEC SQL BEGIN DECLARE SECTION;
1526   int rowcount, id = ps->mach_id;
1527   EXEC SQL END DECLARE SECTION;
1528
1529   EXEC SQL UPDATE printserver SET owner_type = 'NONE', owner_id = 0
1530     WHERE mach_id = :id;
1531   rowcount = sqlca.sqlerrd[2];
1532   if (rowcount > 0)
1533     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1534   else
1535     printf("Not fixed\n");
1536   modified("printservers");
1537 }
1538
1539 static void clear_ps_lpc(struct printserver *ps)
1540 {
1541   EXEC SQL BEGIN DECLARE SECTION;
1542   int rowcount, id = ps->mach_id;
1543   EXEC SQL END DECLARE SECTION;
1544
1545   EXEC SQL UPDATE printserver SET lpc_acl = 0
1546     WHERE mach_id = :id;
1547   rowcount = sqlca.sqlerrd[2];
1548   if (rowcount > 0)
1549     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1550   else
1551     printf("Not fixed\n");
1552   modified("printservers");
1553 }
1554
1555 void check_ps(int id, void *printserver, void *hint)
1556 {
1557   struct printserver *ps = printserver;
1558   struct machine *m;
1559   char *name;
1560
1561   m = hash_lookup(machines, id);
1562   if (!m)
1563     {
1564       printf("Printserver on non-existant machine %d\n", id);
1565       if (single_fix("Delete", 0))
1566         {
1567           single_delete("printservers", "mach_id", id);
1568           return;
1569         }
1570       else
1571         name = "[UNKNOWN]";
1572     }
1573   else
1574     name = m->name;      
1575
1576   ps->modby = maybe_fixup_modby(ps->modby, id, name, "printservers",
1577                                 "modby", "mach_id");
1578   ps->printer_types = maybe_fixup_unref_string(ps->printer_types, id, name,
1579                                                "printservers", "printer_types",
1580                                                "mach_id");
1581
1582   switch (ps->owner_type)
1583     {
1584     case 'U':
1585       if (!hash_lookup(users, ps->owner_id))
1586         {
1587           printf("Printserver %s has non-existant USER owner %d\n",
1588                  name, ps->owner_id);
1589           if (single_fix("Set to no owner", 1))
1590             clear_ps_owner(ps);
1591         }
1592       break;
1593     case 'L':
1594       if (!hash_lookup(lists, ps->owner_id))
1595         {
1596           printf("Printserver %s has non-existant LIST owner %d\n",
1597                  name, ps->owner_id);
1598           if (single_fix("Set to no owner", 1))
1599             clear_ps_owner(ps);
1600         }
1601       break;
1602     case 'K':
1603       if (ps->owner_id)
1604         ps->owner_id = maybe_fixup_unref_string(ps->owner_id, id, name,
1605                                                "printserver", "owner_id",
1606                                                "mach_id");
1607       if (ps->owner_id == 0)
1608         clear_ps_owner(ps);
1609     }
1610
1611   if (!hash_lookup(lists, ps->lpc_acl))
1612     {
1613       printf("Printserver %s has non-existent lpc_acl %d\n",
1614              name, ps->lpc_acl);
1615       if (single_fix("Set to no lpc_acl", 1))
1616         clear_ps_lpc(ps);
1617     }
1618 }
1619
1620 static void clear_container_list(struct container *cnt)
1621 {
1622   EXEC SQL BEGIN DECLARE SECTION;
1623   int rowcount, id = cnt->cnt_id;
1624   EXEC SQL END DECLARE SECTION;
1625
1626   EXEC SQL UPDATE containers SET list_id = 0
1627     WHERE cnt_id = :id;
1628   rowcount = sqlca.sqlerrd[2];
1629   if (rowcount > 0)
1630     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1631   else
1632     printf("Not fixed\n");
1633   modified("containers");
1634 }
1635
1636 void fix_container_acl(int id)
1637 {
1638   EXEC SQL BEGIN DECLARE SECTION;
1639   int rowcount, iid = (int)id;
1640   EXEC SQL END DECLARE SECTION;
1641
1642   EXEC SQL UPDATE containers SET acl_id = 0, acl_type = 'NONE'
1643     WHERE cnt_id = :iid;
1644   rowcount = sqlca.sqlerrd[2];
1645   if (rowcount > 0)
1646     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1647   else
1648     printf("Not fixed\n");
1649   modified("containers");
1650 }
1651
1652 void fix_container_memacl(int id)
1653 {
1654   EXEC SQL BEGIN DECLARE SECTION;
1655   int rowcount, iid = (int)id;
1656   EXEC SQL END DECLARE SECTION;
1657
1658   EXEC SQL UPDATE containers SET memacl_id = 0, memacl_type = 'NONE'
1659     WHERE cnt_id = :iid;
1660   rowcount = sqlca.sqlerrd[2];
1661   if (rowcount > 0)
1662     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1663   else
1664     printf("Not fixed\n");
1665   modified("containers");
1666 }
1667
1668 void check_container(int id, void *container, void *hint)
1669 {
1670   struct container *cnt = container;
1671
1672   if (!hash_lookup(lists, cnt->list_id))
1673     {
1674       printf("Container %s has non-existent associated list_id %d\n",
1675              cnt->name, cnt->list_id);
1676       if (single_fix("Set to no associated list", 1))
1677         clear_container_list(cnt);
1678     }
1679
1680   switch (cnt->acl_type)
1681     {
1682     case 'L':
1683       if (!hash_lookup(lists, cnt->acl_id))
1684         {
1685           printf("Container %s has bad LIST acl %d\n", cnt->name, cnt->acl_id);
1686           if (single_fix("Patch", 1))
1687             fix_container_acl(cnt->cnt_id);
1688         }
1689       break;
1690     case 'U':
1691       if (!hash_lookup(users, cnt->acl_id))
1692         {
1693           printf("Container %s has bad USER acl %d\n", cnt->name, cnt->acl_id);
1694           if (single_fix("Patch", 1))
1695             fix_container_acl(cnt->cnt_id);
1696         }
1697       break;
1698     case 'K':
1699       cnt->acl_id = maybe_fixup_unref_string(cnt->acl_id, id, cnt->name,
1700                                              "container", "acl_id", "cnt_id");
1701       if (!cnt->acl_id)
1702         {
1703           printf("Container %s has bad KERBEROS acl %d\n", cnt->name,
1704                  cnt->acl_id);
1705           if (single_fix("Patch", 1))
1706             fix_container_acl(cnt->cnt_id);
1707         }
1708       break;
1709     }
1710
1711  switch (cnt->memacl_type)
1712     {
1713     case 'L':
1714       if (!hash_lookup(lists, cnt->memacl_id))
1715         {
1716           printf("Container %s has bad LIST memacl %d\n", cnt->name,
1717                  cnt->memacl_id);
1718           if (single_fix("Patch", 1))
1719             fix_container_memacl(cnt->cnt_id);
1720         }
1721       break;
1722     case 'U':
1723       if (!hash_lookup(users, cnt->memacl_id))
1724         {
1725           printf("Container %s has bad USER memacl %d\n", cnt->name,
1726                  cnt->memacl_id);
1727           if (single_fix("Patch", 1))
1728             fix_container_memacl(cnt->cnt_id);
1729         }
1730       break;
1731     case 'K':
1732       cnt->memacl_id = maybe_fixup_unref_string(cnt->memacl_id, id, cnt->name,
1733                                              "container", "memacl_id",
1734                                                 "cnt_id");
1735       if (!cnt->memacl_id)
1736         {
1737           printf("Container %s has bad KERBEROS memacl %d\n", cnt->name,
1738                  cnt->memacl_id);
1739           if (single_fix("Patch", 1))
1740             fix_container_memacl(cnt->cnt_id);
1741         }
1742       break;
1743     }  
1744
1745   cnt->modby = maybe_fixup_modby(cnt->modby, id, cnt->name, "containers",
1746                                  "modby", "cnt_id");
1747 }
1748
1749 int show_fsg_missing(void *id)
1750 {
1751   EXEC SQL BEGIN DECLARE SECTION;
1752   int iid = (int)id, id1, found = 1;
1753   EXEC SQL END DECLARE SECTION;
1754   struct filesys *f;
1755
1756   EXEC SQL DECLARE csr210 CURSOR FOR
1757     SELECT filsys_id FROM fsgroup
1758     WHERE group_id = :iid;
1759   EXEC SQL OPEN csr210;
1760   while (1)
1761     {
1762       EXEC SQL FETCH csr210 INTO :id1;
1763       if (sqlca.sqlcode)
1764         break;
1765
1766       found = 0;
1767       if ((f = hash_lookup(filesys, id1)))
1768         printf("Missing fsgroup %d has member filesystem %s\n", iid, f->name);
1769       else
1770         printf("Missing fsgroup %d has member filesystem %d\n", iid, id1);
1771     }
1772   EXEC SQL CLOSE csr210;
1773   return found;
1774 }
1775
1776 int show_fsg_type(void *filesys)
1777 {
1778   struct filesys *f = filesys;
1779   char *t;
1780
1781   switch (f->type)
1782     {
1783     case 'N':
1784       t = "NFS";
1785       break;
1786     case 'R':
1787       t = "RVD";
1788       break;
1789     case 'A':
1790       t = "AFS";
1791       break;
1792     case 'E':
1793       t = "ERR";
1794       break;
1795     case 'F':
1796       t = "FSGROUP";
1797       break;
1798     case 'M':
1799       t = "MUL";
1800       break;
1801     default:
1802       t = "\?\?\?";
1803     }
1804   printf("FSGroup %s has type %s instead of FSGROUP\n", f->name, t);
1805   return 0;
1806 }
1807
1808 void fix_fsg_type(void *filesys)
1809 {
1810   struct filesys *f = filesys;
1811   EXEC SQL BEGIN DECLARE SECTION;
1812   int rowcount, id = f->filsys_id;
1813   EXEC SQL END DECLARE SECTION;
1814
1815   EXEC SQL UPDATE filesys SET type = 'FSGROUP' WHERE filsys_id = :id;
1816   rowcount = sqlca.sqlerrd[2];
1817   if (rowcount > 0)
1818     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1819   else
1820     printf("Not fixed\n");
1821   modified("filesys");
1822 }
1823
1824 int show_fsg_nomember(void *id)
1825 {
1826   EXEC SQL BEGIN DECLARE SECTION;
1827   int iid = (int)id, id1, found = 1;
1828   EXEC SQL END DECLARE SECTION;
1829   struct filesys *f;
1830
1831   EXEC SQL DECLARE csr211 CURSOR FOR
1832     SELECT group_id FROM fsgroup
1833     WHERE filsys_id = :iid;
1834   EXEC SQL OPEN csr211;
1835   while (1)
1836     {
1837       EXEC SQL FETCH csr211 INTO :id1;
1838       if (sqlca.sqlcode)
1839         break;
1840
1841       found = 0;
1842       if ((f = hash_lookup(filesys, id1)))
1843         printf("FSGroup %s has missing member %d\n", f->name, iid);
1844       else
1845         printf("FSGroup %d has missing member %d\n", id1, iid);
1846     }
1847   EXEC SQL CLOSE csr211;
1848   return found;
1849 }
1850
1851 int show_quota_nouser(void *id)
1852 {
1853   EXEC SQL BEGIN DECLARE SECTION;
1854   int iid = (int)id, id1, found = 1;
1855   EXEC SQL END DECLARE SECTION;
1856
1857   EXEC SQL DECLARE csr212 CURSOR FOR
1858     SELECT filsys_id FROM quota
1859     WHERE entity_id = :iid AND type = 'USER';
1860   EXEC SQL OPEN csr212;
1861   while (1)
1862     {
1863       EXEC SQL FETCH csr212 INTO :id1;
1864       if (sqlca.sqlcode)
1865         break;
1866
1867       found = 0;
1868       printf("Quota on fs %d for non-existant user %d\n", id1, iid);
1869     }
1870   EXEC SQL CLOSE csr212;
1871   return found;
1872 }
1873
1874 int show_quota_nolist(void *id)
1875 {
1876   EXEC SQL BEGIN DECLARE SECTION;
1877   int iid = (int)id, id1, found = 1;
1878   EXEC SQL END DECLARE SECTION;
1879
1880   EXEC SQL DECLARE csr213 CURSOR FOR
1881     SELECT filsys_id FROM quota
1882     WHERE entity_id = :iid AND type = 'GROUP';
1883   EXEC SQL OPEN csr213;
1884   while (1)
1885     {
1886       EXEC SQL FETCH csr213 INTO :id1;
1887       if (sqlca.sqlcode)
1888         break;
1889
1890       found = 0;
1891       printf("Quota on fs %d for non-existant list %d\n", id1, iid);
1892     }
1893   EXEC SQL CLOSE csr213;
1894   return found;
1895 }
1896
1897 void fix_quota_nouser(void *id)
1898 {
1899   EXEC SQL BEGIN DECLARE SECTION;
1900   int iid = (int)id, rowcount;
1901   EXEC SQL END DECLARE SECTION;
1902
1903   EXEC SQL DELETE FROM quota
1904     WHERE entity_id = :iid AND type = 'USER';
1905   rowcount = sqlca.sqlerrd[2];
1906   if (rowcount > 0)
1907     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1908   else
1909     printf("Not deleted\n");
1910   modified("quota");
1911 }
1912
1913 void fix_quota_nolist(void *id)
1914 {
1915   EXEC SQL BEGIN DECLARE SECTION;
1916   int iid = (int)id, rowcount;
1917   EXEC SQL END DECLARE SECTION;
1918
1919   EXEC SQL DELETE FROM quota WHERE entity_id = :iid AND type = 'GROUP';
1920   rowcount = sqlca.sqlerrd[2];
1921   if (rowcount > 0)
1922     printf("%d entr%s deleted\n", rowcount, rowcount == 1 ? "y" : "ies");
1923   else
1924     printf("Not deleted\n");
1925   modified("quota");
1926 }
1927
1928 int show_quota_nofs(void *id)
1929 {
1930   EXEC SQL BEGIN DECLARE SECTION;
1931   int iid = (int)id, id1, found = 1;
1932   char type[QUOTA_TYPE_SIZE];
1933   EXEC SQL END DECLARE SECTION;
1934
1935   EXEC SQL DECLARE csr214 CURSOR FOR
1936     SELECT entity_id, type FROM quota
1937     WHERE filsys_id = :iid;
1938   EXEC SQL OPEN csr214;
1939   while (1)
1940     {
1941       EXEC SQL FETCH csr214 INTO :id1, :type;
1942       if (sqlca.sqlcode)
1943         break;
1944
1945       found = 0;
1946       printf("Quota for %s %d on non-existant filesys %d\n", type, id1, iid);
1947     }
1948   EXEC SQL CLOSE csr214;
1949   return found;
1950 }
1951
1952 void fix_quota_nofs(void *id)
1953 {
1954   single_delete("quota", "filsys_id", (int)id);
1955 }
1956
1957 int show_quota_wrongpid(void *id)
1958 {
1959   EXEC SQL BEGIN DECLARE SECTION;
1960   int iid = (int)id, id1, found = 1;
1961   char type[QUOTA_TYPE_SIZE];
1962   EXEC SQL END DECLARE SECTION;
1963   struct filesys *f;
1964
1965   f = hash_lookup(filesys, iid);
1966   EXEC SQL DECLARE csr215 CURSOR FOR
1967     SELECT entity_id, type FROM quota
1968     WHERE filsys_id = :iid;
1969   EXEC SQL OPEN csr215;
1970   while (1)
1971     {
1972       EXEC SQL FETCH csr215 INTO :id1, :type;
1973       if (sqlca.sqlcode)
1974         break;
1975
1976       found = 0;
1977       printf("Quota for %s %d on filesys %s has wrong phys_id %d\n",
1978              type, id1, f->name, iid);
1979     }
1980   EXEC SQL CLOSE csr215;
1981   return found;
1982 }
1983
1984 void fix_quota_physid(void *id)
1985 {
1986   EXEC SQL BEGIN DECLARE SECTION;
1987   int iid = (int)id, rowcount, id1;
1988   EXEC SQL END DECLARE SECTION;
1989
1990   id1 = ((struct filesys *)hash_lookup(filesys, iid))->phys_id;
1991   EXEC SQL UPDATE quota SET phys_id = :id1
1992     WHERE filsys_id = :iid AND phys_id != :id1;
1993   rowcount = sqlca.sqlerrd[2];
1994   if (rowcount > 0)
1995     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
1996   else
1997     printf("Not fixed\n");
1998   modified("quota");
1999 }
2000
2001 int show_srv_user(void *id)
2002 {
2003   EXEC SQL BEGIN DECLARE SECTION;
2004   char name[SERVERS_NAME_SIZE];
2005   int iid = (int)id;
2006   EXEC SQL END DECLARE SECTION;
2007   int found = 1;
2008
2009   EXEC SQL DECLARE csr216 CURSOR FOR
2010     SELECT name FROM servers
2011     WHERE acl_type = 'USER' and acl_id = :iid;
2012   EXEC SQL OPEN csr216;
2013   while (1)
2014     {
2015       EXEC SQL FETCH csr216 INTO :name;
2016       if (sqlca.sqlcode)
2017         break;
2018
2019       strtrim(name);
2020       printf("Service %s has acl non-existant user %d\n", name, iid);
2021       found = 0;
2022     }
2023   EXEC SQL CLOSE csr216;
2024   return found;
2025 }
2026
2027 int show_srv_list(void *id)
2028 {
2029   EXEC SQL BEGIN DECLARE SECTION;
2030   char name[SERVERS_NAME_SIZE];
2031   int iid = (int)id;
2032   EXEC SQL END DECLARE SECTION;
2033   int found = 1;
2034
2035   EXEC SQL DECLARE csr217 CURSOR FOR
2036     SELECT name FROM servers
2037     WHERE acl_type = 'LIST' AND acl_id = :iid;
2038   EXEC SQL OPEN csr217;
2039   while (1)
2040     {
2041       EXEC SQL FETCH csr217 INTO :name;
2042       if (sqlca.sqlcode)
2043         break;
2044
2045       strtrim(name);
2046       printf("Service %s has acl non-existant list %d\n", name, iid);
2047       found = 0;
2048     }
2049   EXEC SQL CLOSE csr217;
2050   return found;
2051 }
2052
2053 void zero_srv_user(void *id)
2054 {
2055   EXEC SQL BEGIN DECLARE SECTION;
2056   int iid = (int)id, rowcount;
2057   EXEC SQL END DECLARE SECTION;
2058
2059   EXEC SQL UPDATE servers SET acl_id = 0 WHERE acl_id = :iid AND
2060     acl_type = 'USER';
2061   rowcount = sqlca.sqlerrd[2];
2062   if (rowcount > 0)
2063     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
2064   else
2065     printf("Not fixed\n");
2066   modified("servers");
2067 }
2068
2069 void zero_srv_list(void *id)
2070 {
2071   EXEC SQL BEGIN DECLARE SECTION;
2072   int iid = (int)id, rowcount;
2073   EXEC SQL END DECLARE SECTION;
2074
2075   EXEC SQL UPDATE servers SET acl_id = 0 WHERE acl_id = :iid AND
2076     acl_type = 'LIST';
2077   rowcount = sqlca.sqlerrd[2];
2078   if (rowcount > 0)
2079     printf("%d entr%s fixed\n", rowcount, rowcount == 1 ? "y" : "ies");
2080   else
2081     printf("Not fixed\n");
2082   modified("servers");
2083 }
2084
2085 int show_krb_usr(void *id)
2086 {
2087   EXEC SQL BEGIN DECLARE SECTION;
2088   int iid = (int)id, found = 1, id1;
2089   EXEC SQL END DECLARE SECTION;
2090   struct string *s;
2091   char *ss;
2092
2093   EXEC SQL DECLARE csr218 CURSOR FOR
2094     SELECT string_id FROM krbmap
2095     WHERE users_id = :iid;
2096   EXEC SQL OPEN csr218;
2097   while (1)
2098     {
2099       EXEC SQL FETCH csr218 INTO :id1;
2100       if (sqlca.sqlcode)
2101         break;
2102
2103       if ((s = hash_lookup(strings, id1)))
2104         ss = s->name;
2105       else
2106         ss = "[unknown]";
2107       found = 0;
2108       printf("Kerberos map for non-existant user %d to principal %s\n",
2109              iid, ss);
2110     }
2111   EXEC SQL CLOSE csr218;
2112   return found;
2113 }
2114
2115 int show_krb_str(void *id)
2116 {
2117   EXEC SQL BEGIN DECLARE SECTION;
2118   int iid = (int)id, found = 1, id1;
2119   EXEC SQL END DECLARE SECTION;
2120   struct user *u;
2121   char *s;
2122
2123   EXEC SQL DECLARE csr219 CURSOR FOR
2124     SELECT users_id FROM krbmap
2125     WHERE string_id = :iid;
2126   EXEC SQL OPEN csr219;
2127   while (1)
2128     {
2129       EXEC SQL FETCH csr219 INTO :id1;
2130       if (sqlca.sqlcode)
2131         break;
2132
2133       if ((u = hash_lookup(users, id1)))
2134         s = u->login;
2135       else
2136         s = "[\?\?\?]";
2137       found = 0;
2138       printf("Kerberos map for user %s (%d) to non-existant string %d\n",
2139              s, id1, iid);
2140     }
2141   EXEC SQL CLOSE csr219;
2142   return found;
2143 }
2144
2145 void phase2(void)
2146 {
2147   struct save_queue *sq, *sq1, *sq2, *sq3, *sq4, *sq5, *sq6;
2148   struct filesys *f;
2149   struct list *l;
2150   struct nfsphys *n;
2151   struct machine *m;
2152   char rowid[32];
2153
2154   printf("Phase 2 - Checking references\n");
2155
2156   dprintf("Checking users...\n");
2157   hash_step(users, user_check, NULL);
2158
2159   dprintf("Checking machines...\n");
2160   hash_step(machines, mach_check, NULL);
2161
2162   dprintf("Checking subnets...\n");
2163   hash_step(subnets, subnet_check, NULL);
2164
2165   dprintf("Checking clusters...\n");
2166   hash_step(clusters, cluster_check, NULL);
2167
2168   dprintf("Checking mcmap...\n");
2169   sq1 = sq_create();
2170   sq2 = sq_create();
2171   EXEC SQL DECLARE csr221 CURSOR FOR
2172     SELECT mach_id, clu_id FROM mcmap;
2173   EXEC SQL OPEN csr221;
2174   while (1)
2175     {
2176       EXEC SQL BEGIN DECLARE SECTION;
2177       int mach_id, clu_id;
2178       EXEC SQL END DECLARE SECTION;
2179
2180       EXEC SQL FETCH csr221 INTO :mach_id, :clu_id;
2181       if (sqlca.sqlcode)
2182         break;
2183
2184       if (!(m = hash_lookup(machines, mach_id)))
2185         sq_save_unique_data(sq1, (void *)mach_id);
2186       else if (!hash_lookup(clusters, clu_id))
2187         sq_save_unique_data(sq2, (void *)clu_id);
2188       if (m)
2189         m->clucount++;
2190     }
2191   EXEC SQL CLOSE csr221;
2192   generic_delete(sq1, show_mcm_mach, "mcmap", "mach_id", 1);
2193   generic_delete(sq2, show_mcm_clu, "mcmap", "clu_id", 1);
2194
2195   dprintf("Checking service clusters...\n");
2196   sq1 = sq_create();
2197   EXEC SQL DECLARE csr222 CURSOR FOR
2198     SELECT clu_id FROM svc;
2199   EXEC SQL OPEN csr222;
2200   while (1)
2201     {
2202       EXEC SQL BEGIN DECLARE SECTION;
2203       int clu_id;
2204       EXEC SQL END DECLARE SECTION;
2205
2206       EXEC SQL FETCH csr222 INTO :clu_id;
2207       if (sqlca.sqlcode)
2208         break;
2209
2210       if (!hash_lookup(clusters, clu_id))
2211         sq_save_unique_data(sq1, (void *)clu_id);
2212     }
2213   EXEC SQL CLOSE csr222;
2214   generic_delete(sq1, show_svc, "svc", "clu_id", 1);
2215
2216   dprintf("Checking lists...\n");
2217   hash_step(lists, list_check, NULL);
2218
2219   dprintf("Checking members...\n");
2220   sq1 = sq_create();
2221   sq2 = sq_create();
2222   sq3 = sq_create();
2223   sq4 = sq_create();
2224   sq5 = sq_create();
2225   sq6 = sq_create();
2226
2227   EXEC SQL DECLARE csr223 CURSOR FOR
2228     SELECT list_id, member_type, member_id, tag, ref_count, direct, rowid
2229     FROM imembers FOR UPDATE OF member_id;
2230   EXEC SQL OPEN csr223;
2231   while (1)
2232     {
2233       EXEC SQL BEGIN DECLARE SECTION;
2234       int list_id, id, tag, ref_count, direct;
2235       char type[IMEMBERS_MEMBER_TYPE_SIZE];
2236       EXEC SQL END DECLARE SECTION;
2237
2238       EXEC SQL FETCH csr223 INTO :list_id, :type, :id, :tag,
2239         :ref_count, :direct, :rowid;
2240       if (sqlca.sqlcode)
2241         break;
2242       strtrim(rowid);
2243
2244       if (!(l = hash_lookup(lists, list_id)))
2245         sq_save_unique_data(sq1, (void *)list_id);
2246       else if (type[0] == 'U' && !hash_lookup(users, id))
2247         sq_save_unique_data(sq2, (void *)id);
2248       else if (type[0] == 'L' && !hash_lookup(lists, id))
2249         sq_save_unique_data(sq3, (void *)id);
2250       else if (type[0] == 'S' && !maybe_fixup_unref_string2("imembers", "member_id", rowid, id))
2251         sq_save_unique_data(sq4, (void *)id);
2252       else if (type[0] == 'K' && !maybe_fixup_unref_string2("imembers", "member_id", rowid, id))
2253         sq_save_unique_data(sq5, (void *)id);
2254       else if (type[0] == 'M' && !hash_lookup(machines, id))
2255         sq_save_unique_data(sq6, (void *)id);
2256       else
2257         l->members++;
2258       maybe_fixup_unref_string2("imembers", "tag", rowid, tag);
2259     }
2260   EXEC SQL CLOSE csr223;
2261   generic_delete(sq1, show_member_list, "imembers", "list_id", 1);
2262   generic_fix(sq2, show_mem_user, "Delete", del_mem_user, 1);
2263   generic_fix(sq3, show_mem_list, "Delete", del_mem_list, 1);
2264   generic_fix(sq4, show_mem_str, "Delete", del_mem_str, 1);
2265   generic_fix(sq5, show_mem_krb, "Delete", del_mem_krb, 1);
2266   generic_fix(sq6, show_mem_mach, "Delete", del_mem_mach, 1);
2267
2268   dprintf("Checking servers...\n");
2269   sq1 = sq_create();
2270   sq2 = sq_create();
2271   EXEC SQL DECLARE csr224 CURSOR FOR
2272     SELECT name, acl_type, acl_id, modby, rowid FROM servers
2273     FOR UPDATE of modby;
2274   EXEC SQL OPEN csr224;
2275   while (1)
2276     {
2277       EXEC SQL BEGIN DECLARE SECTION;
2278       int acl_id, modby;
2279       char name[SERVERS_NAME_SIZE], acl_type[SERVERS_ACL_TYPE_SIZE];
2280       EXEC SQL END DECLARE SECTION;
2281
2282       EXEC SQL FETCH csr224 INTO :name, :acl_type, :acl_id, :modby, :rowid;
2283       if (sqlca.sqlcode)
2284         break;
2285
2286       maybe_fixup_modby2("servers", "modby", strtrim(rowid), modby);
2287       strtrim(acl_type);
2288       if (!strcmp(acl_type, "USER") && !hash_lookup(users, acl_id))
2289         sq_save_data(sq1, (void *)acl_id);
2290       else if (!strcmp(acl_type, "LIST") && !hash_lookup(lists, acl_id))
2291         sq_save_data(sq2, (void *)acl_id);
2292     }
2293   EXEC SQL CLOSE csr224;
2294   generic_fix(sq1, show_srv_user, "Fix", zero_srv_user, 1);
2295   generic_fix(sq2, show_srv_list, "Fix", zero_srv_list, 1);
2296
2297   dprintf("Checking serverhosts...\n");
2298   sq = sq_create();
2299   EXEC SQL DECLARE csr225 CURSOR FOR
2300     SELECT mach_id, modby, rowid FROM serverhosts
2301     FOR UPDATE OF modby;
2302   EXEC SQL OPEN csr225;
2303   while (1)
2304     {
2305       EXEC SQL BEGIN DECLARE SECTION;
2306       int mach_id, modby;
2307       EXEC SQL END DECLARE SECTION;
2308
2309       EXEC SQL FETCH csr225 INTO :mach_id, :modby, :rowid;
2310       if (sqlca.sqlcode)
2311         break;
2312
2313       maybe_fixup_modby2("serverhosts", "modby", strtrim(rowid), modby);
2314       if (!hash_lookup(machines, mach_id))
2315         sq_save_data(sq, (void *)mach_id);
2316     }
2317   EXEC SQL CLOSE csr225;
2318   generic_fix(sq, show_sh, "Delete", del_sh_mach, 0);
2319
2320   dprintf("Checking nfsphys...\n");
2321   hash_step(nfsphys, check_nfsphys, NULL);
2322
2323   dprintf("Checking filesys...\n");
2324   hash_step(filesys, check_fs, NULL);
2325
2326   dprintf("Checking filesystem groups...\n");
2327   sq1 = sq_create();
2328   sq2 = sq_create();
2329   sq3 = sq_create();
2330   EXEC SQL DECLARE csr226 CURSOR FOR
2331     SELECT group_id, filsys_id FROM fsgroup;
2332   EXEC SQL OPEN csr226;
2333   while (1)
2334     {
2335       EXEC SQL BEGIN DECLARE SECTION;
2336       int group_id, filsys_id;
2337       EXEC SQL END DECLARE SECTION;
2338
2339       EXEC SQL FETCH csr226 INTO :group_id, :filsys_id;
2340       if (sqlca.sqlcode)
2341         break;
2342
2343       if (!(f = hash_lookup(filesys, group_id)))
2344         sq_save_data(sq1, (void *)group_id);
2345       if (!hash_lookup(filesys, filsys_id))
2346         sq_save_data(sq3, (void *)filsys_id);
2347     }
2348   EXEC SQL CLOSE csr226;
2349   generic_delete(sq1, show_fsg_missing, "fsgroup", "group_id", 0);
2350   generic_delete(sq3, show_fsg_nomember, "fsgroup", "filsys_id", 1);
2351
2352   dprintf("Checking quotas...\n");
2353   sq1 = sq_create();
2354   sq2 = sq_create();
2355   sq3 = sq_create();
2356   sq4 = sq_create();
2357   EXEC SQL DECLARE csr227 CURSOR FOR
2358     SELECT entity_id, type, filsys_id, phys_id, quota, modby, rowid
2359     FROM quota FOR UPDATE OF modby;
2360   EXEC SQL OPEN csr227;
2361   while (1)
2362     {
2363       EXEC SQL BEGIN DECLARE SECTION;
2364       int entity_id, filsys_id, phys_id, quota, modby;
2365       char type[QUOTA_TYPE_SIZE];
2366       EXEC SQL END DECLARE SECTION;
2367
2368       EXEC SQL FETCH csr227 INTO :entity_id, :type, :filsys_id,
2369         :phys_id, :quota, :modby, :rowid;
2370       if (sqlca.sqlcode)
2371         break;
2372
2373       maybe_fixup_modby2("quota", "modby", strtrim(rowid), modby);
2374       if (type[0] == 'U' && entity_id != 0 && !hash_lookup(users, entity_id))
2375         sq_save_data(sq1, (void *)entity_id);
2376       else if (type[0] == 'G' && !hash_lookup(lists, entity_id))
2377         sq_save_data(sq4, (void *)entity_id);
2378       else if (!(f = hash_lookup(filesys, filsys_id)))
2379         sq_save_data(sq2, (void *)filsys_id);
2380       else if (phys_id != f->phys_id || !(n = hash_lookup(nfsphys, phys_id)))
2381         sq_save_data(sq3, (void *)phys_id);
2382       else
2383         n->count += quota;
2384     }
2385   EXEC SQL CLOSE csr227;
2386   generic_fix(sq1, show_quota_nouser, "Delete", fix_quota_nouser, 1);
2387   generic_fix(sq2, show_quota_nofs, "Delete", fix_quota_nofs, 0);
2388   generic_fix(sq3, show_quota_wrongpid, "Fix", fix_quota_physid, 1);
2389   generic_fix(sq4, show_quota_nolist, "Delete", fix_quota_nolist, 1);
2390
2391   dprintf("Checking zephyr...\n");
2392   EXEC SQL DECLARE csr_zc CURSOR FOR
2393     SELECT class, xmt_type, xmt_id, sub_type, sub_id, iws_type, iws_id,
2394     iui_type, iui_id, modby FROM zephyr;
2395   EXEC SQL OPEN csr_zc;
2396   while(1)
2397     {
2398       EXEC SQL BEGIN DECLARE SECTION;
2399       int xmt_id, sub_id, iws_id, iui_id, modby;
2400       char class[ZEPHYR_CLASS_SIZE];
2401       char xmt_type[ZEPHYR_XMT_TYPE_SIZE];
2402       char sub_type[ZEPHYR_SUB_TYPE_SIZE];
2403       char iws_type[ZEPHYR_IWS_TYPE_SIZE];
2404       char iui_type[ZEPHYR_IUI_TYPE_SIZE];
2405       EXEC SQL END DECLARE SECTION;
2406
2407       EXEC SQL FETCH csr_zc INTO :class, :xmt_type, :xmt_id, :sub_type, 
2408         :sub_id, :iws_type, :iws_id, :iui_type, :iui_id, :modby;
2409
2410       if (sqlca.sqlcode)
2411         break;
2412
2413       maybe_fixup_modby2("zephyr", "modby", strtrim(rowid), modby);
2414
2415       strtrim(xmt_type);
2416       if (!strcmp(xmt_type, "USER") && !hash_lookup(users, xmt_id))
2417         {
2418           printf("xmt acl for %s is non-existant user %d\n", class, xmt_id);
2419           printf("Not fixing this error\n");
2420         }
2421       else if (!strcmp(xmt_type, "LIST") && !hash_lookup(lists, xmt_id))
2422         {
2423           printf("xmt acl for %s is non-existant list %d\n", class, xmt_id);
2424           printf("Not fixing this error\n");
2425         }
2426       else if (!strcmp(xmt_type, "STRING") || !strcmp(xmt_type, "KERBEROS"))
2427         maybe_fixup_unref_string2("zephyr", "xmt_id", strtrim(rowid), xmt_id);
2428
2429       strtrim(sub_type);
2430       if (!strcmp(sub_type, "USER") && !hash_lookup(users, sub_id))
2431         {
2432           printf("sub acl for %s is non-existant user %d\n", class, sub_id);
2433           printf("Not fixing this error\n");
2434         }
2435       else if (!strcmp(sub_type, "LIST") && !hash_lookup(lists, sub_id))
2436         {
2437           printf("sub acl for %s is non-existant list %d\n", class, sub_id);
2438           printf("Not fixing this error\n");
2439         }
2440       else if (!strcmp(sub_type, "STRING") || !strcmp(sub_type, "KERBEROS"))
2441         maybe_fixup_unref_string2("zephyr", "sub_id", strtrim(rowid), sub_id);
2442
2443       strtrim(iws_type);
2444       if (!strcmp(iws_type, "USER") && !hash_lookup(users, iws_id))
2445         {
2446           printf("iws acl for %s is non-existant user %d\n", class, iws_id);
2447           printf("Not fixing this error\n");
2448         }
2449       else if (!strcmp(iws_type, "LIST") && !hash_lookup(lists, iws_id))
2450         {
2451           printf("iws acl for %s is non-existant list %d\n", class, iws_id);
2452           printf("Not fixing this error\n");
2453         }
2454       else if (!strcmp(iws_type, "STRING") || !strcmp(iws_type, "KERBEROS"))
2455         maybe_fixup_unref_string2("zephyr", "iws_id", strtrim(rowid), iws_id);
2456
2457       strtrim(iui_type);
2458       if (!strcmp(iui_type, "USER") && !hash_lookup(users, iui_id))
2459         {
2460           printf("iui acl for %s is non-existant user %d\n", class, iui_id);
2461           printf("Not fixing this error\n");
2462         }
2463       else if (!strcmp(iui_type, "LIST") && !hash_lookup(lists, iui_id))
2464         {
2465           printf("iui acl for %s is non-existant list %d\n", class, iui_id);
2466           printf("Not fixing this error\n");
2467         }
2468       else if (!strcmp(iui_type, "STRING") || !strcmp(iui_type, "KERBEROS"))
2469         maybe_fixup_unref_string2("zephyr", "iui_id", strtrim(rowid), iui_id);
2470     }
2471
2472   dprintf("Checking hostaccess...\n");
2473   EXEC SQL DECLARE csr228 CURSOR FOR
2474     SELECT mach_id, acl_type, acl_id, modby, rowid FROM hostaccess
2475     FOR UPDATE OF modby;
2476   EXEC SQL OPEN csr228;
2477   while (1)
2478     {
2479       EXEC SQL BEGIN DECLARE SECTION;
2480       int mach_id, acl_id, modby;
2481       char acl_type[HOSTACCESS_ACL_TYPE_SIZE];
2482       EXEC SQL END DECLARE SECTION;
2483
2484       EXEC SQL FETCH csr228 INTO :mach_id, :acl_type, :acl_id, :modby, :rowid;
2485       if (sqlca.sqlcode)
2486         break;
2487
2488       maybe_fixup_modby2("hostaccess", "modby", strtrim(rowid), modby);
2489       strtrim(acl_type);
2490       if (!hash_lookup(machines, mach_id))
2491         {
2492           printf("Hostaccess for non-existant host %d\n", mach_id);
2493           printf("Not fixing this error\n");
2494         }
2495       if (!strcmp(acl_type, "USER") && !hash_lookup(users, acl_id))
2496         {
2497           printf("Hostaccess for %d is non-existant user %d\n", mach_id, acl_id);
2498           printf("Not fixing this error\n");
2499         }
2500       else if (!strcmp(acl_type, "LIST") && !hash_lookup(lists, acl_id))
2501         {
2502           printf("Hostaccess for %d is non-existant list %d\n", mach_id, acl_id);
2503           printf("Not fixing this error\n");
2504         }
2505     }
2506   EXEC SQL CLOSE csr228;
2507
2508   dprintf("Checking krbmap...\n");
2509   sq1 = sq_create();
2510   sq2 = sq_create();
2511   EXEC SQL DECLARE csr230 CURSOR FOR
2512     SELECT users_id, string_id, rowid FROM krbmap
2513     FOR UPDATE OF string_id;
2514   EXEC SQL OPEN csr230;
2515   while (1)
2516     {
2517       EXEC SQL BEGIN DECLARE SECTION;
2518       int users_id, string_id;
2519       EXEC SQL END DECLARE SECTION;
2520
2521       EXEC SQL FETCH csr230 INTO :users_id, :string_id, :rowid;
2522       if (sqlca.sqlcode)
2523         break;
2524
2525       if (!hash_lookup(users, users_id))
2526         sq_save_unique_data(sq1, (void *)users_id);
2527       else if (!maybe_fixup_unref_string2("krbmap", "string_id", strtrim(rowid), string_id))
2528         sq_save_unique_data(sq2, (void *)string_id);
2529     }
2530   EXEC SQL CLOSE csr230;
2531   generic_delete(sq1, show_krb_usr, "krbmap", "users_id", 1);
2532   generic_delete(sq2, show_krb_str, "krbmap", "string_id", 1);
2533
2534   dprintf("Checking capacls...\n");
2535   EXEC SQL DECLARE csr231 CURSOR FOR
2536     SELECT list_id, tag FROM capacls;
2537   EXEC SQL OPEN csr231;
2538   while (1)
2539     {
2540       EXEC SQL BEGIN DECLARE SECTION;
2541       int list_id;
2542       char tag[CAPACLS_TAG_SIZE];
2543       EXEC SQL END DECLARE SECTION;
2544
2545       EXEC SQL FETCH csr231 INTO :list_id, :tag;
2546       if (sqlca.sqlcode)
2547         break;
2548
2549       if (!hash_lookup(lists, list_id))
2550         {
2551           printf("Capacl for %s is non-existant list %d\n", tag, list_id);
2552           printf("Not fixing this error\n");
2553         }
2554     }
2555   EXEC SQL CLOSE csr231;
2556
2557   dprintf("Checking hostaliases...\n");
2558   sq1 = sq_create();
2559   EXEC SQL DECLARE csr232 CURSOR FOR
2560     SELECT mach_id FROM hostalias;
2561   EXEC SQL OPEN csr232;
2562   while (1)
2563     {
2564       EXEC SQL BEGIN DECLARE SECTION;
2565       int mach_id;
2566       EXEC SQL END DECLARE SECTION;
2567
2568       EXEC SQL FETCH csr232 INTO :mach_id;
2569       if (sqlca.sqlcode)
2570         break;
2571
2572       if (!hash_lookup(machines, mach_id))
2573         sq_save_unique_data(sq1, (void *)mach_id);
2574     }
2575   EXEC SQL CLOSE csr232;
2576   generic_delete(sq1, show_hostalias, "hostalias", "mach_id", 1);
2577
2578   dprintf("Checking printers...\n");
2579   sq1 = sq_create();
2580   sq2 = sq_create();
2581   sq3 = sq_create();
2582   sq4 = sq_create();
2583   sq5 = sq_create();
2584   sq6 = sq_create();
2585   EXEC SQL DECLARE csr233 CURSOR FOR
2586     SELECT mach_id, loghost, rm, rq, ac, lpc_acl, modby, rowid FROM printers;
2587   EXEC SQL OPEN csr233;
2588   while (1)
2589     {
2590       EXEC SQL BEGIN DECLARE SECTION;
2591       int mach_id, loghost, rm, rq, ac, lpc_acl, modby;
2592       EXEC SQL END DECLARE SECTION;
2593
2594       EXEC SQL FETCH csr233 INTO :mach_id, :loghost, :rm, :rq, :ac,
2595         :lpc_acl, :modby, :rowid;
2596       if (sqlca.sqlcode)
2597         break;
2598
2599       maybe_fixup_modby2("printers", "modby", strtrim(rowid), modby);
2600       if (!hash_lookup(machines, mach_id))
2601         sq_save_unique_data(sq1, (void *)mach_id);
2602       else if (!hash_lookup(machines, rm))
2603         sq_save_unique_data(sq2, (void *)rm);
2604       else if (!hash_lookup(printservers, rm))
2605         sq_save_unique_data(sq6, (void *)mach_id);
2606       else if (!hash_lookup(machines, rq))
2607         sq_save_unique_data(sq3, (void *)rq);
2608       else {
2609         if (!hash_lookup(lists, ac))
2610           sq_save_unique_data(sq4, (void *)ac);
2611         if (!hash_lookup(lists, lpc_acl))
2612           sq_save_unique_data(sq5, (void *)lpc_acl);
2613         if (!hash_lookup(machines, loghost))
2614           {
2615             show_printer_loghost((void *)loghost);
2616             cant_fix();
2617           }
2618       }
2619     }
2620   EXEC SQL CLOSE csr233;
2621   generic_delete(sq1, show_printer_mach, "printers", "mach_id", 1);
2622   generic_delete(sq6, show_printer_server, "printers", "mach_id", 1);
2623   generic_delete(sq2, show_printer_spool, "printers", "rm", 1);
2624   generic_delete(sq3, show_printer_quota, "printers", "rq", 1);
2625   generic_fix(sq4, show_printer_ac, "Clear", fix_printer_ac, 1);
2626   generic_fix(sq5, show_printer_lpc_acl, "Clear", fix_printer_lpc_acl, 1);
2627
2628   dprintf("Checking printservers...\n");
2629   hash_step(printservers, check_ps, NULL);
2630
2631   dprintf("Checking containers...\n");
2632   hash_step(containers, check_container, NULL);
2633
2634   dprintf("Checking mcntmap...\n");
2635   sq1 = sq_create();
2636   sq2 = sq_create();
2637   EXEC SQL DECLARE csr_mcntmap CURSOR FOR
2638     SELECT mach_id, cnt_id FROM mcntmap;
2639   EXEC SQL OPEN csr_mcntmap;
2640   while (1)
2641     {
2642       EXEC SQL BEGIN DECLARE SECTION;
2643       int mach_id, cnt_id;
2644       EXEC SQL END DECLARE SECTION;
2645
2646       EXEC SQL FETCH csr_mcntmap INTO :mach_id, :cnt_id;
2647       if (sqlca.sqlcode)
2648         break;
2649
2650       if (!(m = hash_lookup(machines, mach_id)))
2651         sq_save_unique_data(sq1, (void *)mach_id);
2652       else if (!hash_lookup(containers, cnt_id))
2653         sq_save_unique_data(sq2, (void *)cnt_id);
2654     }
2655   EXEC SQL CLOSE csr_mcntmap;
2656   generic_delete(sq1, show_mcntmap_mach, "mcntmap", "mach_id", 1);
2657   generic_delete(sq2, show_mcntmap_cnt, "mcntmap", "cnt_id", 1);
2658
2659 }
2660  
This page took 0.421395 seconds and 5 git commands to generate.