source: trunk/third/moira/incremental/afs/afs.c @ 25817

Revision 25817, 19.8 KB checked in by jdreed, 11 years ago (diff)
In moira: * Re-snapshot moira at r4097 to pick up Status 10 (Suspended) (Trac: #1295) * Remove our addusr.1 and namespace.1 in favor of upstreams (Trac: #918) * Build-dep on OpenSSL and pass new configure flag per moira r4091
Line 
1/* $Id: afs.c 4097 2013-02-11 14:54:53Z zacheiss $
2 *
3 * Do AFS incremental updates
4 *
5 * Copyright (C) 1989,1992 by the Massachusetts Institute of Technology
6 * for copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <moira.h>
11#include <moira_site.h>
12#include <moira_schema.h>
13
14#include <stdio.h>
15#include <stdlib.h>
16#include <sys/resource.h>
17#include <sys/types.h>
18#include <sys/utsname.h>
19#include <sys/file.h>
20#include <string.h>
21#include <unistd.h>
22
23#include <com_err.h>
24#ifdef HAVE_KRB4
25#include <krb.h>
26#else
27#include <mr_krb.h>
28#endif
29#include <krb5.h>
30
31#include <afs/param.h>
32#include <afs/cellconfig.h>
33#include <afs/venus.h>
34#include <afs/ptclient.h>
35#include <afs/pterror.h>
36
37/* Cheesy test for determining AFS more recent than 3.4a */
38#ifndef AFSCONF_CLIENTNAME
39#include <afs/dirpath.h>
40#define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
41#endif
42
43#define STOP_FILE "/moira/afs/noafs"
44#define file_exists(file) (access((file), F_OK) == 0)
45
46RCSID("$HeadURL: svn+ssh://svn.mit.edu/moira/trunk/moira/incremental/afs/afs.c $ $Id: afs.c 4097 2013-02-11 14:54:53Z zacheiss $");
47
48char *whoami;
49
50/* Main stub routines */
51void do_user(char **before, int beforec, char **after, int afterc);
52void do_list(char **before, int beforec, char **after, int afterc);
53void do_member(char **before, int beforec, char **after, int afterc);
54void do_filesys(char **before, int beforec, char **after, int afterc);
55void do_quota(char **before, int beforec, char **after, int afterc);
56
57/* Support stub routines */
58void run_cmd(char *cmd);
59int add_user_lists(int ac, char **av, void *user);
60int add_list_members(int ac, char **av, void  *group);
61int check_user(int ac, char **av, void *ustate);
62void edit_group(int op, char *group, char *type, char *member);
63int pr_try();
64void check_afs(void);
65int moira_connect(void);
66int moira_disconnect(void);
67
68/* libprot.a routines */
69extern int pr_Initialize();
70extern int pr_CreateUser();
71extern int pr_CreateGroup();
72extern int pr_DeleteByID();
73extern int pr_ChangeEntry();
74extern int pr_SetFieldsEntry();
75extern int pr_AddToGroup();
76extern int pr_RemoveUserFromGroup();
77extern int pr_SIdToName();
78
79static char tbl_buf[1024];
80static struct member {
81  int op;
82  char list[LIST_NAME_SIZE];
83  char type[IMEMBERS_MEMBER_TYPE_SIZE];
84  char member[MAX_FIELD_WIDTH];
85  struct member *next;
86} *member_head = NULL;
87
88static int mr_connections = 0;
89
90int main(int argc, char **argv)
91{
92  int beforec, afterc, i;
93  char *table, **before, **after;
94  struct rlimit rl;
95
96  getrlimit(RLIMIT_NOFILE, &rl);
97  for (i = rl.rlim_cur; i > 2; i--)
98    close(i);
99
100  whoami = ((whoami = strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
101
102  table = argv[1];
103  beforec = atoi(argv[2]);
104  before = &argv[4];
105  afterc = atoi(argv[3]);
106  after = &argv[4 + beforec];
107
108  setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
109
110  strcpy(tbl_buf, table);
111  strcat(tbl_buf, " (");
112  for (i = 0; i < beforec; i++)
113    {
114      if (i > 0)
115        strcat(tbl_buf, ",");
116      strcat(tbl_buf, before[i]);
117    }
118  strcat(tbl_buf, ")->(");
119  for (i = 0; i < afterc; i++)
120    {
121      if (i > 0)
122        strcat(tbl_buf, ",");
123      strcat(tbl_buf, after[i]);
124    }
125  strcat(tbl_buf, ")");
126
127  initialize_sms_error_table();
128  initialize_krb_error_table();
129
130  if (!strcmp(table, "users"))
131    do_user(before, beforec, after, afterc);
132  else if (!strcmp(table, "list"))
133    do_list(before, beforec, after, afterc);
134  else if (!strcmp(table, "imembers"))
135    do_member(before, beforec, after, afterc);
136  else if (!strcmp(table, "filesys"))
137    do_filesys(before, beforec, after, afterc);
138  else if (!strcmp(table, "quota"))
139    do_quota(before, beforec, after, afterc);
140
141  exit(0);
142}
143
144
145void do_user(char **before, int beforec, char **after, int afterc)
146{
147  int astate, bstate, auid, buid, code;
148  char *av[2];
149
150  auid = buid = astate = bstate = 0;
151  if (afterc > U_STATE)
152    astate = atoi(after[U_STATE]);
153  if (beforec > U_STATE)
154    bstate = atoi(before[U_STATE]);
155  if (afterc > U_UID)
156    auid = atoi(after[U_UID]);
157  if (beforec > U_UID)
158    buid = atoi(before[U_UID]);
159
160  /* We consider "half-registered" users and "suspended" users to be active */
161  if ((astate == 2) || (astate == 10))
162    astate = 1;
163  if (bstate == 2 || (astate == 10))
164    bstate = 1;
165
166  if (astate != 1 && bstate != 1)               /* inactive user */
167    return;
168
169  if (astate == bstate && auid == buid &&
170      !strcmp(before[U_NAME], after[U_NAME]))
171    /* No AFS related attributes have changed */
172    return;
173
174  if (astate == bstate)
175    {
176      /* Only a modify has to be done */
177      com_err(whoami, 0, "Changing user %s (uid %d) to %s (uid %d)",
178              before[U_NAME], buid, after[U_NAME], auid);
179
180      code = pr_try(pr_ChangeEntry, before[U_NAME], after[U_NAME], &auid, "");
181      if (code)
182        {
183          critical_alert(whoami, "incremental",
184                         "Couldn't change user %s (id %d) to %s (id %d): %s",
185                         before[U_NAME], buid, after[U_NAME], auid,
186                         error_message(code));
187        }
188      return;
189    }
190  if (bstate == 1)
191    {
192      com_err(whoami, 0, "Deleting user %s (uid %d)",
193              before[U_NAME], buid);
194
195      code = pr_try(pr_DeleteByID, buid);
196      if (code && code != PRNOENT)
197        {
198          critical_alert(whoami, "incremental", "Couldn't delete user %s (id %d): %s",
199                         before[U_NAME], buid, error_message(code));
200        }
201      return;
202    }
203  if (astate == 1)
204    {
205      com_err(whoami, 0, "%s user %s (uid %d)",
206              ((bstate != 0) ? "Reactivating" : "Creating"),
207              after[U_NAME], auid);
208
209      code = pr_try(pr_CreateUser, after[U_NAME], &auid);
210      /* if we get PRIDEXIST, it's only an error if the username
211         doesn't match (otherwise it just means the user was deleted
212         from Moira but not AFS */
213      if (code == PRIDEXIST)
214        {
215          char ename[PR_MAXNAMELEN];
216
217          if (pr_try(pr_SIdToName, auid, ename) == 0 &&
218              !strcmp(after[U_NAME], ename))
219            return;
220        }
221      if (code)
222        {
223          critical_alert(whoami, "incremental", "Couldn't create user %s (id %d): %s",
224                         after[U_NAME], auid, error_message(code));
225          return;
226        }
227
228      if (bstate != 0)
229        {
230          /* Reactivating a user; get his group list */
231          code = moira_connect();
232          if (code)
233            {
234              critical_alert(whoami, "incremental", "Error contacting Moira server "
235                             "to retrieve grouplist of user %s: %s",
236                             after[U_NAME], error_message(code));
237              return;
238            }
239          av[0] = "ruser";
240          av[1] = after[U_NAME];
241          code = mr_query("get_lists_of_member", 2, av, add_user_lists,
242                          after[U_NAME]);
243          if (code && code != MR_NO_MATCH)
244            {
245              critical_alert(whoami, "incremental",
246                             "Couldn't retrieve membership of user %s: %s",
247                             after[U_NAME], error_message(code));
248            }
249          moira_disconnect();
250        }
251      return;
252    }
253}
254
255
256void do_list(char **before, int beforec, char **after, int afterc)
257{
258  int agid, bgid;
259  int ahide, bhide;
260  int code, id;
261  char g1[PR_MAXNAMELEN], g2[PR_MAXNAMELEN];
262  char *av[2];
263
264  agid = bgid = 0;
265  if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP]))
266    {
267      bgid = atoi(before[L_GID]);
268      bhide = atoi(before[L_HIDDEN]);
269    }
270  if (afterc > L_GID && atoi(after[L_ACTIVE]) && atoi(after[L_GROUP]))
271    {
272      agid = atoi(after[L_GID]);
273      ahide = atoi(after[L_HIDDEN]);
274    }
275
276  if (agid == 0 && bgid == 0)                   /* Not active groups */
277    return;
278
279  if (agid && bgid)
280    {
281      if (strcmp(after[L_NAME], before[L_NAME]))
282        {
283          /* Only a modify is required */
284          strcpy(g1, "system:");
285          strcpy(g2, "system:");
286          strcat(g1, before[L_NAME]);
287          strcat(g2, after[L_NAME]);
288          id = -agid;
289
290          com_err(whoami, 0, "Changing group %s (gid %d) to %s (gid %d)",
291                  before[L_NAME], bgid, after[L_NAME], agid);
292
293          code = pr_try(pr_ChangeEntry, g1, g2, &id, "");
294          if (code)
295            {
296              critical_alert(whoami, "incremental", "Couldn't change group %s (id %d) "
297                             "to %s (id %d): %s", before[L_NAME], -bgid,
298                             after[L_NAME], -agid, error_message(code));
299            }
300        }
301      if (ahide != bhide)
302        {
303          com_err(whoami, 0, "Making group %s (gid %d) %s", after[L_NAME],
304                  agid, (ahide ? "hidden" : "visible"));
305          code = pr_try(pr_SetFieldsEntry, -agid, PR_SF_ALLBITS,
306                        (ahide ? PRP_STATUS_ANY : PRP_GROUP_DEFAULT) >>
307                        PRIVATE_SHIFT, 0 /*ngroups*/, 0 /*nusers*/);
308          if (code)
309            {
310              critical_alert(whoami, "incremental",
311                             "Couldn't set flags of group %s: %s",
312                             after[L_NAME], error_message(code));
313            }
314        }
315      return;
316    }
317  if (bgid)
318    {
319      com_err(whoami, 0, "Deleting group %s (gid %d)", before[L_NAME], bgid);
320      code = pr_try(pr_DeleteByID, -bgid);
321      if (code && code != PRNOENT)
322        {
323          critical_alert(whoami, "incremental",
324                         "Couldn't delete group %s (id %d): %s",
325                         before[L_NAME], -bgid, error_message(code));
326        }
327      return;
328    }
329  if (agid)
330    {
331      strcpy(g1, "system:");
332      strcat(g1, after[L_NAME]);
333      strcpy(g2, "system:administrators");
334      id = -agid;
335      com_err(whoami, 0, "Creating %s group %s (gid %d)",
336              (ahide ? "hidden" : "visible"), after[L_NAME], agid);
337      code = pr_try(pr_CreateGroup, g1, g2, &id);
338      if (code == PRIDEXIST)
339        {
340          char ename[PR_MAXNAMELEN];
341
342          if (pr_try(pr_SIdToName, -agid, ename) == 0 && !strcmp(g1, ename))
343            return;
344        }
345      if (code)
346        {
347          critical_alert(whoami, "incremental", "Couldn't create group %s (id %d): %s",
348                         after[L_NAME], id, error_message(code));
349          return;
350        }
351      if (ahide)
352        {
353          code = pr_try(pr_SetFieldsEntry, -agid, PR_SF_ALLBITS,
354                        (ahide ? PRP_STATUS_ANY : PRP_GROUP_DEFAULT) >>
355                        PRIVATE_SHIFT, 0 /*ngroups*/, 0 /*nusers*/);
356          if (code)
357            {
358              critical_alert(whoami, "incremental",
359                             "Couldn't set flags of group %s: %s",
360                             after[L_NAME], error_message(code));
361            }
362        }
363
364      /* We need to make sure the group is properly populated */
365      if (beforec < L_ACTIVE)
366        return;
367
368      code = moira_connect();
369      if (code)
370        {
371          critical_alert(whoami, "incremental",
372                         "Error contacting Moira server to resolve %s: %s",
373                         after[L_NAME], error_message(code));
374          return;
375        }
376      av[0] = after[L_NAME];
377      code = mr_query("get_end_members_of_list", 1, av,
378                      add_list_members, after[L_NAME]);
379      if (code)
380        {
381          critical_alert(whoami, "incremental",
382                         "Couldn't retrieve full membership of list %s: %s",
383                         after[L_NAME], error_message(code));
384        }
385      moira_disconnect();
386      return;
387    }
388}
389
390
391
392#define LM_EXTRA_ACTIVE   (LM_END)
393#define LM_EXTRA_PUBLIC   (LM_END+1)
394#define LM_EXTRA_HIDDEN   (LM_END+2)
395#define LM_EXTRA_MAILLIST (LM_END+3)
396#define LM_EXTRA_GROUP    (LM_END+4)
397#define LM_EXTRA_GID      (LM_END+5)
398#define LM_EXTRA_END      (LM_END+6)
399
400void do_member(char **before, int beforec, char **after, int afterc)
401{
402  if (afterc)
403    {
404      if (afterc < LM_EXTRA_END)
405        return;
406      else
407        {
408          if (!atoi(after[LM_EXTRA_ACTIVE]) || !atoi(after[LM_EXTRA_GROUP]))
409            return;
410        }
411
412      edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER]);
413    }
414  else if (beforec)
415    {
416      if (beforec < LM_EXTRA_END)
417        return;
418      else
419        {
420          if (!atoi(before[LM_EXTRA_ACTIVE]) || !atoi(before[LM_EXTRA_GROUP]))
421            return;
422        }
423      edit_group(0, before[LM_LIST], before[LM_TYPE], before[LM_MEMBER]);
424    }
425}
426
427
428void do_filesys(char **before, int beforec, char **after, int afterc)
429{
430  char cmd[1024];
431  int acreate, atype, bcreate, btype, fsltypelen, fsnamelen;
432  char *tmp;
433
434  if (afterc < FS_CREATE)
435    atype = acreate = 0;
436  else
437    {
438      atype = !strcmp(after[FS_TYPE], "AFS");
439      acreate = atoi(after[FS_CREATE]);
440      /* If the lockername ends in ".lockertype" strip that.
441       * eg.  the SITE locker "foo.site" becomes just "foo"
442       */
443      fsltypelen = strlen(after[FS_L_TYPE]);
444      fsnamelen = strlen(after[FS_NAME]);
445      tmp = (after[FS_NAME] + fsnamelen - fsltypelen);
446      if (!strcasecmp(tmp, after[FS_L_TYPE]) && *(tmp-1) == '.')
447        *(tmp-1) = '\0';
448    }
449
450  if (beforec < FS_CREATE)
451    {
452      if (acreate == 0 || atype == 0)
453        return;
454
455      /* new locker creation */
456      sprintf(cmd, "%s/perl -I%s %s/afs_create.pl %s %s %s %s %s %s",
457              BIN_DIR, BIN_DIR, BIN_DIR,
458              after[FS_NAME], after[FS_L_TYPE], after[FS_MACHINE],
459              after[FS_PACK], after[FS_OWNER], after[FS_OWNERS]);
460      run_cmd(cmd);
461      return;
462    }
463  else
464    {
465      /* If the lockername ends in ".lockertype" strip that.
466       * eg.  the SITE locker "foo.site" becomes just "foo"
467       */
468      fsltypelen = strlen(before[FS_L_TYPE]);
469      fsnamelen = strlen(before[FS_NAME]);
470      tmp = (before[FS_NAME] + fsnamelen - fsltypelen);
471      if (!strcasecmp(tmp, before[FS_L_TYPE]) && *(tmp-1) == '.')
472        *(tmp-1) = '\0';
473    }
474
475  btype = !strcmp(before[FS_TYPE], "AFS");
476  bcreate = atoi(before[FS_CREATE]);
477  if (afterc < FS_CREATE)
478    {
479      if (btype && bcreate)
480        critical_alert(whoami, "incremental", "Cannot delete AFS filesystem %s: "
481                       "Operation not supported", before[FS_NAME]);
482      return;
483    }
484
485  if (!acreate)
486    return;
487
488  /* Are we dealing with AFS lockers (could be type ERR lockers) */
489  if (!atype && !btype)
490    {
491      if (strcmp(before[FS_TYPE], "ERR") || strcmp(after[FS_TYPE], "ERR"))
492        return;
493    }
494
495  /* By now, we know we are simply changing AFS filesystem attributes.
496   * Operations supported:
497   *    Name change:  rename/remount
498   *    Path change:  remount
499   *    Type change:  ERR<-->AFS
500   */
501
502#if 0
503  if (strcmp(before[FS_OWNER], after[FS_OWNER]) ||
504      strcmp(before[FS_OWNERS], after[FS_OWNERS]))
505    {
506      critical_alert(whoami, "incremental",
507                     "Cannot change ownership of filesystem %s: Operation not yet supported",
508                     after[FS_NAME]);
509    }
510#endif
511
512  sprintf(cmd, "%s/perl -I%s %s/afs_rename.pl %s %s %s %s %s %s %s %s %s %s",
513          BIN_DIR, BIN_DIR, BIN_DIR,
514          before[FS_NAME], before[FS_MACHINE], before[FS_TYPE],
515          before[FS_L_TYPE], before[FS_PACK],
516          after[FS_NAME], after[FS_MACHINE], after[FS_TYPE],
517          after[FS_L_TYPE], after[FS_PACK]);
518  run_cmd(cmd);
519}
520
521
522void do_quota(char **before, int beforec, char **after, int afterc)
523{
524  char cmd[1024];
525
526  if (afterc < Q_DIRECTORY || strcmp("ANY", after[Q_TYPE]) ||
527      strncmp("/afs/", after[Q_DIRECTORY], 5))
528    return;
529
530  sprintf(cmd, "%s/perl -I%s %s/afs_quota.pl %s %s",
531          BIN_DIR, BIN_DIR, BIN_DIR,
532          after[Q_DIRECTORY], after[Q_QUOTA]);
533  run_cmd(cmd);
534  return;
535}
536
537
538void run_cmd(char *cmd)
539{
540  int success=0, tries=0;
541
542  check_afs();
543
544  while (success == 0 && tries < 2)
545    {
546      if (tries++)
547        sleep(90);
548      com_err(whoami, 0, "Executing command: %s", cmd);
549      if (system(cmd) == 0)
550        success++;
551    }
552  if (!success)
553    critical_alert(whoami, "incremental", "failed command: %s", cmd);
554}
555
556
557int add_user_lists(int ac, char **av, void *user)
558{
559  if (atoi(av[L_ACTIVE]) && atoi(av[L_GROUP]))  /* active group ? */
560    edit_group(1, av[L_NAME], "USER", user);
561  return 0;
562}
563
564
565int add_list_members(int ac, char **av, void *group)
566{
567  edit_group(1, group, av[0], av[1]);
568  return 0;
569}
570
571int check_user(int ac, char **av, void *ustate)
572{
573  *(int *)ustate = atoi(av[U_STATE]);
574  return 0;
575}
576
577
578void edit_group(int op, char *group, char *type, char *member)
579{
580  char *p = 0;
581  char buf[PR_MAXNAMELEN];
582  int code, ustate;
583  static char *local_realm = NULL;
584  struct member *m;
585  krb5_context context = NULL;
586  krb5_principal client = NULL;
587  char name[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ];
588  char canon_member[MAX_K_NAME_SZ];
589
590  memset(name, 0, sizeof(name));
591  memset(inst, 0, sizeof(inst));
592  memset(realm, 0, sizeof(realm));
593
594  code = krb5_init_context(&context);
595  if (code)
596    goto out;
597
598  /* The following KERBEROS code allows for the use of entities
599   * user@foreign_cell.
600   */
601  if (!local_realm)
602    {
603      code = krb5_get_default_realm(context, &local_realm);
604      if (code)
605        goto out;
606    }
607
608  /* Cannot risk doing another query during a callback */
609
610  /* We could do this simply for type USER, but eventually this may
611   * also dynamically add KERBEROS types to the prdb, and we will need
612   * to do a query to look up the uid of the null-instance user */
613
614  if (mr_connections)
615    {
616      m = malloc(sizeof(struct member));
617      if (!m)
618        {
619          critical_alert(whoami, "incremental", "Out of memory");
620          exit(1);
621        }
622      m->op = op;
623      strcpy(m->list, group);
624      strcpy(m->type, type);
625      strcpy(m->member, member);
626      m->next = member_head;
627      member_head = m;
628      return;
629    }
630
631  if (!strcmp(type, "KERBEROS"))
632    {
633      /* AFS still uses a v4-style namespace, so convert. */
634      code = krb5_parse_name(context, member, &client);
635      if (code)
636        goto out;
637
638      code = krb5_524_conv_principal(context, client, name, inst, realm);
639      if (code)
640        goto out;
641
642      strcpy(canon_member, mr_kname_unparse(name, inst, realm));
643      member = canon_member;
644
645      p = strchr(member, '@');
646      if (p && !strcasecmp(p+1, local_realm))
647        *p = 0;
648    }
649  else if (strcmp(type, "USER"))
650    return;                                     /* invalid type */
651
652  strcpy(buf, "system:");
653  strcat(buf, group);
654  com_err(whoami, 0, "%s %s %s group %s", (op ? "Adding" : "Removing"), member,
655          (op ? "to" : "from"), group);
656  code = pr_try(op ? pr_AddToGroup : pr_RemoveUserFromGroup, member, buf);
657  if (code)
658    {
659      if (op==1 && code == PRIDEXIST)
660        return; /* Already added */
661
662      if (code == PRNOENT)
663        {                       /* Something is missing */
664          if (op == 0)
665            return;                     /* Already deleted */
666          if (!strcmp(type, "KERBEROS"))        /* Special instances; ok */
667            return;
668
669          /* Check whether the member being added is an active user */
670          code = moira_connect();
671          if (!code)
672            {
673              code = mr_query("get_user_by_login", 1, &member,
674                              check_user, (char *) &ustate);
675            }
676          if (code)
677            {
678              critical_alert(whoami, "incremental", "Error contacting Moira server "
679                             "to lookup user %s: %s", member,
680                             error_message(code));
681            }
682
683          /* We don't use moira_disconnect()
684           * because we may already be in the routine.
685           */
686          mr_disconnect();
687          mr_connections--;
688
689          if (!code && ustate!=1 && ustate!=2)
690            return; /* inactive user */
691          code = PRNOENT;
692        }
693
694    out:
695      if (client)
696        krb5_free_principal(context, client);
697      if (context)
698        krb5_free_context(context);
699      if (local_realm)
700        free(local_realm);
701
702      critical_alert(whoami, "incremental", "Couldn't %s %s %s %s: %s",
703                     op ? "add" : "remove", member,
704                     op ? "to" : "from", buf,
705                     error_message(code));
706    }
707}
708
709
710int pr_try(int (*fn)(), char *a1, char *a2, char *a3, char *a4, char *a5,
711            char *a6, char *a7, char *a8)
712{
713  static int initd = 0;
714  int code;
715  int tries = 0;
716
717  check_afs();
718
719  if (initd)
720    code = pr_Initialize(0, AFSCONF_CLIENTNAME, 0);
721  else
722    {
723      code = 0;
724      initd = 1;
725    }
726  if (!code)
727    code = pr_Initialize(1, AFSCONF_CLIENTNAME, 0);
728  if (code)
729    {
730      critical_alert(whoami, "incremental", "Couldn't initialize libprot: %s",
731                     error_message(code));
732      return code;
733    }
734
735  sleep(1);                                     /* give ptserver room */
736
737  while ((code = (*fn)(a1, a2, a3, a4, a5, a6, a7, a8)))
738    {
739      if (++tries > 2)
740        break;          /* 3 tries */
741
742      if (code == UNOQUORUM)
743        sleep(90);
744      else if (code == PRPERM)
745        system("/usr/bin/aklog");
746      else
747        sleep(1);
748
749      /* Re-initialize the prdb connection */
750      code = pr_Initialize(0, AFSCONF_CLIENTNAME, 0);
751      if (!code)
752        code = pr_Initialize(1, AFSCONF_CLIENTNAME, 0);
753      if (code)
754        {
755          critical_alert(whoami, "incremental", "Couldn't re-initialize libprot: %s",
756                         error_message(code));
757          initd = 0;                            /* we lost */
758          break;
759        }
760    }
761  return code;
762}
763
764
765void check_afs(void)
766{
767  int i;
768
769  for (i = 0; file_exists(STOP_FILE); i++)
770    {
771      if (i > 30)
772        {
773          critical_alert(whoami, "incremental",
774                         "AFS incremental failed (%s exists): %s",
775                         STOP_FILE, tbl_buf);
776          exit(1);
777        }
778      sleep(60);
779    }
780}
781
782
783int moira_connect(void)
784{
785  int code;
786
787  if (!mr_connections++)
788    {
789      struct utsname uts;
790      uname(&uts);
791      code = mr_connect(uts.nodename);
792      if (!code)
793        code = mr_krb5_auth("afs.incr");
794      return code;
795    }
796  return 0;
797}
798
799int moira_disconnect(void)
800{
801  struct member *m;
802
803  if (!--mr_connections)
804    {
805      mr_disconnect();
806      while ((m = member_head))
807        {
808          edit_group(m->op, m->list, m->type, m->member);
809          member_head = m->next;
810          free(m);
811        }
812    }
813  return 0;
814}
Note: See TracBrowser for help on using the repository browser.