예제 #1
0
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;
}
예제 #2
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;
}