int main(int argc, char **argv) { afs_int32 code; char name[PR_MAXNAMELEN]; char gname[PR_MAXNAMELEN]; char owner[PR_MAXNAMELEN]; afs_int32 id; char buf[3000]; FILE *fp; char *ptr; char *tmp; char *cellname; namelist lnames; afs_int32 i; afs_int32 fail = 0; if (argc < 2) { fprintf(stderr, "Usage: readgroup [-v] [-c cellname] groupfile.\n"); exit(0); } cellname = 0; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-v")) verbose = 1; else { if (!strcmp(argv[i], "-c")) { cellname = (char *)malloc(100); strncpy(cellname, argv[++i], 100); } else strncpy(buf, argv[i], 150); } } code = pr_Initialize(2, AFSDIR_CLIENT_ETC_DIRPATH, cellname); free(cellname); if (code) { fprintf(stderr, "pr_Initialize failed .. exiting.\n"); fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code), code); exit(1); } if ((fp = fopen(buf, "r")) == NULL) { fprintf(stderr, "Couldn't open %s.\n", argv[1]); exit(1); } while ((tmp = fgets(buf, 3000, fp)) != NULL) { /* group file lines must either have the name of a group or a tab or blank space at beginning */ if (buf[0] == '\n') break; if (buf[0] != ' ' && buf[0] != '\t') { /* grab the group name */ memset(gname, 0, PR_MAXNAMELEN); memset(owner, 0, PR_MAXNAMELEN); sscanf(buf, "%s %d", gname, &id); tmp = buf; skip(&tmp); skip(&tmp); stolower(gname); ptr = strchr(gname, ':'); strncpy(owner, gname, ptr - gname); if (strcmp(owner, "system") == 0) strncpy(owner, "system:administrators", PR_MAXNAMELEN); fail = 0; if (verbose) printf("Group is %s, owner is %s, id is %d.\n", gname, owner, id); code = pr_CreateGroup(gname, owner, &id); if (code != 0) { if (code != PRIDEXIST) { /* already exists */ fprintf(stderr, "Failed to create group %s with id %d!\n", gname, id); fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code), code); } if (code != PREXIST && code != PRIDEXIST) { /* we won't add users if it's not there */ fail = 1; } } if (!fail) { /* read members out of buf and add to the group */ memset(name, 0, PR_MAXNAMELEN); while (sscanf(tmp, "%s", name) != EOF) { if (strchr(name, ':') == NULL) { /* then it's not a group */ code = pr_AddToGroup(name, gname); report_error(code, name, gname); } else { /* add the members of a group to the group */ if (verbose) printf("Adding %s to %s.\n", lnames.namelist_val[i], gname); code = pr_ListMembers(name, &lnames); if (code) { fprintf(stderr, "Couldn't get the members for %s to add to %s.\n", name, gname); fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code), code); } for (i = 0; i < lnames.namelist_len; i++) { code = pr_AddToGroup(lnames.namelist_val[i], gname); report_error(code, lnames.namelist_val[i], gname); } if (lnames.namelist_val) free(lnames.namelist_val); } memset(name, 0, PR_MAXNAMELEN); skip(&tmp); } } } else { /* must have more names to add */ /* if we couldn't create the group, and it wasn't already there, don't try to add more users */ if (fail) continue; /* read members out of buf and add to the group */ memset(name, 0, PR_MAXNAMELEN); tmp = buf; tmp++; while (sscanf(tmp, "%s", name) != EOF) { if (strchr(name, ':') == NULL) { /* then it's not a group */ code = pr_AddToGroup(name, gname); report_error(code, name, gname); } else { /* add the members of a group to the group */ code = pr_ListMembers(name, &lnames); if (code) { fprintf(stderr, "Couldn't get the members for %s to add to %s.\n", name, gname); fprintf(stderr, "%s (%d).\n", pr_ErrorMsg(code), code); } for (i = 0; i < lnames.namelist_len; i++) { if (verbose) printf("Adding %s to %s.\n", lnames.namelist_val[i], gname); code = pr_AddToGroup(lnames.namelist_val[i], gname); report_error(code, lnames.namelist_val[i], gname); } if (lnames.namelist_val) free(lnames.namelist_val); } memset(name, 0, PR_MAXNAMELEN); skip(&tmp); } } } return 0; }
static struct auth_state *myauthstate(const char *identifier, size_t size, const char **reply, int *dsize) { const char *canon_id = afspts_canonifyid(identifier, size); char canon_id_tmp[PTS_DB_KEYSIZE+1]; namelist groups; int i, rc; struct auth_state *newstate; if (canon_id == NULL) { syslog(LOG_ERR, "afspts_canonifyid failed for %s", identifier); return NULL; } *reply = NULL; size = strlen(canon_id); memset(&groups, 0, sizeof(groups)); groups.namelist_len = 0; groups.namelist_val = NULL; /* canon_id_tmp is used because AFS would otherwise trample * on our nice canonical user id */ strlcpy(canon_id_tmp,canon_id,sizeof(canon_id_tmp)); if ((rc = pr_ListMembers(canon_id_tmp, &groups))) { /* Failure may indicate that we need new tokens */ pr_End(); rc = pr_Initialize (1L, AFSCONF_CLIENTNAME, config_getstring(IMAPOPT_AFSPTS_MYCELL)); if (rc) { syslog(LOG_DEBUG, "pr_Initialize failed: %d", rc); fatal("pr_Initialize failed", EC_TEMPFAIL); } /* Okay, rerun it now */ rc = pr_ListMembers(canon_id_tmp, &groups); } /* Don't die because of afs, but log the error */ if(rc) { syslog(LOG_ERR, "pr_ListMembers %s: %s", canon_id, error_message(rc)); } /* fill in our new state structure */ *dsize = sizeof(struct auth_state) + (groups.namelist_len * sizeof(struct auth_ident)); newstate = (struct auth_state *) xzmalloc(*dsize); strcpy(newstate->userid.id, canon_id); newstate->userid.hash = strhash(canon_id); /* If we get a permission error, assume it may be temporary authentication problem, and cache only for a minute. Should negative cache time be configurable? */ if (rc == PRPERM) { newstate->mark = time(0) + 60 - (config_getint(IMAPOPT_PTSCACHE_TIMEOUT) > 60)? config_getint(IMAPOPT_PTSCACHE_TIMEOUT) : 60; } else newstate->mark = time(0); newstate->ngroups = groups.namelist_len; /* store group list in contiguous array for easy storage in the database */ memset(newstate->groups, 0, newstate->ngroups * sizeof(struct auth_ident)); for (i = 0; i < newstate->ngroups; i++) { strlcpy(newstate->groups[i].id, groups.namelist_val[i], sizeof(newstate->groups[i].id)); newstate->groups[i].hash = strhash(groups.namelist_val[i]); /* don't free groups.namelist_val[i]. Something else currently * takes care of that data. */ } if (groups.namelist_val != NULL) { free(groups.namelist_val); } return newstate; }