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