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