예제 #1
0
int
pr_ChangeEntry(prname oldname, prname newname, afs_int32 *newid, prname newowner)
{
    afs_int32 code;
    afs_int32 id;
    afs_int32 oid = 0;

    /* pr_SNameToId takes care of length checks for us. */
    code = pr_SNameToId(oldname, &id);
    if (code)
	return code;
    if (id == ANONYMOUSID)
	return PRNOENT;
    if (newowner && *newowner) {
	code = pr_SNameToId(newowner, &oid);
	if (code)
	    return code;
	if (oid == ANONYMOUSID)
	    return PRNOENT;
    }
    if (newid)
	code = ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid, *newid);
    else
	code = ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid, 0);
    return code;
}
예제 #2
0
int
pr_ChangeEntry(char *oldname, char *newname, afs_int32 *newid, char *newowner)
{
    afs_int32 code;
    afs_int32 id;
    afs_int32 oid = 0;

    code = pr_SNameToId(oldname, &id);
    if (code)
	return code;
    if (id == ANONYMOUSID)
	return PRNOENT;
    if (newowner && *newowner) {
	code = pr_SNameToId(newowner, &oid);
	if (code)
	    return code;
	if (oid == ANONYMOUSID)
	    return PRNOENT;
    }
    if (newid)
	code = ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid, *newid);
    else
	code = ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid, 0);
    return code;
}
예제 #3
0
int
pr_CheckEntryByName(prname name, afs_int32 *id, prname owner, prname creator)
{
    /* struct prcheckentry returns other things, which aren't useful to show at this time. */
    afs_int32 code;
    struct prcheckentry aentry;

    /* pr_SNameToId will check name's length. */
    code = pr_SNameToId(name, id);
    if (code)
	return code;
    if (*id == ANONYMOUSID)
	return PRNOENT;
    code = ubik_PR_ListEntry(pruclient, 0, *id, &aentry);
    if (code)
	return code;
    /* this should be done in one RPC, but I'm lazy. */
    code = pr_SIdToName(aentry.owner, owner);
    if (code)
	return code;
    code = pr_SIdToName(aentry.creator, creator);
    if (code)
	return code;
    return PRSUCCESS;
}
예제 #4
0
int
pr_ListMembers(prname group, namelist *lnames)
{
    afs_int32 code;
    afs_int32 gid;
    int i;

    memset(lnames, 0, sizeof(namelist));

    /* pr_SNameToId checks the length of group. */
    code = pr_SNameToId(group, &gid);
    if (code)
	return code;
    if (gid == ANONYMOUSID)
	return PRNOENT;
    code = pr_IDListMembers(gid, lnames);
    if (code)
	return code;
    for (i = 0; i < lnames->namelist_len; i++) {
	code = check_length(lnames->namelist_val[i]);
	if (code)
	    return code;
    }
    return code;
}
예제 #5
0
int
pr_CreateGroup(prname name, prname owner, afs_int32 *id)
{
    afs_int32 code;
    afs_int32 oid = 0;
    afs_int32 flags = 0;

    code = check_length(name);
    if (code)
	return code;
    /* pr_SNameToId will check owner's length. */
    stolower(name);
    if (owner) {
	code = pr_SNameToId(owner, &oid);
	if (code)
	    return code;
	if (oid == ANONYMOUSID)
	    return PRNOENT;
    }
    flags |= PRGRP;
    if (*id) {
	code = ubik_PR_INewEntry(pruclient, 0, name, *id, oid);
    } else {
	code = ubik_PR_NewEntry(pruclient, 0, name, flags, oid, id);
    }
    return code;
}
예제 #6
0
파일: fs_acl.c 프로젝트: bagdxk/openafs
/*
 * Check if a username is valid: If it contains only digits (or a
 * negative sign), then it might be bad.  If we know the cellname,
 * then query the ptserver to see if the entry is recognized.
 */
static int
BadName(char *aname, char *cellname)
{
    afs_int32 tc, code, id = 0;
    char *nm;

    for ( nm = aname; tc = *nm; nm++) {
	/* all must be '-' or digit to be bad */
	if (tc != '-' && (tc < '0' || tc > '9'))
            return 0;
    }

    if (cellname) {
        char confDir[257];

        /* Go to the PRDB and see if this all number username is valid */
        cm_GetConfigDir(confDir, sizeof(confDir));

        pr_Initialize(1, confDir, cellname);
        code = pr_SNameToId(aname, &id);
        pr_End();
    }

    /* 1=>Not-valid; 0=>Valid */
    return ((!code && (id == ANONYMOUSID)) ? 1 : 0);
}
예제 #7
0
int
pr_ListMembers(char *group, namelist *lnames)
{
    afs_int32 code;
    afs_int32 gid;

    code = pr_SNameToId(group, &gid);
    if (code)
	return code;
    if (gid == ANONYMOUSID)
	return PRNOENT;
    code = pr_IDListMembers(gid, lnames);
    return code;
}
예제 #8
0
int
pr_Delete(char *name)
{
    afs_int32 code;
    afs_int32 id;

    stolower(name);
    code = pr_SNameToId(name, &id);
    if (code)
	return code;
    if (id == ANONYMOUSID)
	return PRNOENT;
    code = ubik_PR_Delete(pruclient, 0, id);
    return code;
}
예제 #9
0
int
pr_Delete(prname name)
{
    afs_int32 code;
    afs_int32 id;

    /* pr_SNameToId both checks the length of name and lowercases it. */
    code = pr_SNameToId(name, &id);
    if (code)
	return code;
    if (id == ANONYMOUSID)
	return PRNOENT;
    code = ubik_PR_Delete(pruclient, 0, id);
    return code;
}
예제 #10
0
int afs_set_token(struct afs_auth_creds afscreds ) {
	/*
	 * Set tokens in kernel
	 */

	int afs_status;
	char buf[1024];
	int buflen=0;
	afs_int32 viceId;

	/*
	 * Initialize afs? and map the afs user (client.name) to an id
	 */
	atc_log_debug("Initialize afs client?");
	if (afs_status=pr_Initialize(0,AFSDIR_CLIENT_ETC_DIRPATH,afscreds.server.cell)) {
		sprintf(afs_token_cache_errmsg,"Failed to initialize afs stuff for cell '%s'",afscreds.server.cell);
		goto fail;
	}

	atc_log_debug("Mapping username to afs pts id");
	if ( afs_status=afs_status=pr_SNameToId(afscreds.client.name,&viceId)) {
		sprintf(afs_token_cache_errmsg,"Failed to map name '%s' to id",afscreds.client.name);
		goto fail;
	}

 
	/*
	 * Set the token if the afs id is greater than 0 and not anonymous (32766)
	 */
	if ( viceId != 32766 && viceId > 0 ) {
		atc_log_info("Setting afs tokens in kernel for user '%s'", afscreds.client.name);
		afs_status=ktc_SetToken(&afscreds.server, &afscreds.token, &afscreds.client, 0);
		if ( afs_status ) {
			sprintf(afs_token_cache_errmsg, "Failed to set tokens in kernel for user '%s'", afscreds.client.name);
			goto fail;
		}
	} else {
		atc_log_info("User id is either 0 or the afs anonymous id (32766), not setting tokens");
	}
 
	return 0;

	fail:
		atc_log_err(afs_token_cache_errmsg);
		return 1;
}
예제 #11
0
파일: klog.c 프로젝트: openafs/openafs
static int
whoami(struct ktc_token *atoken,
    struct afsconf_cell *cellconfig,
    struct ktc_principal *aclient,
    int *vicep)
{
    int code;
    char tempname[2*PR_MAXNAMELEN];

    code = pr_Initialize(0, AFSDIR_CLIENT_ETC_DIRPATH, cellconfig->name);
    if (code)
	goto Failed;

    if (*aclient->instance)
	snprintf (tempname, sizeof tempname, "%s.%s",
	    aclient->name, aclient->instance);
    else
	snprintf (tempname, sizeof tempname, "%s", aclient->name);
    code = pr_SNameToId(tempname, vicep);
Failed:
    return code;
}
예제 #12
0
int
pr_CreateGroup(char name[PR_MAXNAMELEN], char owner[PR_MAXNAMELEN], afs_int32 *id)
{
    afs_int32 code;
    afs_int32 oid = 0;
    afs_int32 flags = 0;

    stolower(name);
    if (owner) {
	code = pr_SNameToId(owner, &oid);
	if (code)
	    return code;
	if (oid == ANONYMOUSID)
	    return PRNOENT;
    }
    flags |= PRGRP;
    if (*id) {
	code = ubik_PR_INewEntry(pruclient, 0, name, *id, oid);
	return code;
    } else {
	code = ubik_PR_NewEntry(pruclient, 0, name, flags, oid, id);
	return code;
    }
}
예제 #13
0
파일: aklog.c 프로젝트: snktagarwal/openafs
void ViceIDToUsername(char *username, char *realm_of_user, char *realm_of_cell,
                      char * cell_to_use, CREDENTIALS *c,
                      int *status, 
                      struct ktc_principal *aclient, struct ktc_principal *aserver, struct ktc_token *atoken)
{
    static char lastcell[MAXCELLCHARS+1] = { 0 };
    static char confname[512] = { 0 };
    char username_copy[BUFSIZ];
    afs_int32 viceId;			/* AFS uid of user */

    if (confname[0] == '\0') {
        strncpy(confname, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confname));
        confname[sizeof(confname) - 2] = '\0';
    }

    if (dflag)
        printf("About to resolve name %s to id\n", username);

    strcpy(lastcell, aserver->cell);

    if (!pr_Initialize (0, confname, aserver->cell)) {
        char sname[PR_MAXNAMELEN], *at;

        strncpy(sname, username, PR_MAXNAMELEN);
        sname[PR_MAXNAMELEN-1] = '\0';

	at = strchr(sname, '@');
	if (at && !stricmp(at+1, realm_of_cell))
	    *at = '\0';
	*status = pr_SNameToId (sname, &viceId);
    }

    if (dflag)
    {
        if (*status)
            printf("pr_SNameToId Error %s\n",  afs_error_message(*status));
        else
            printf("Id %d\n", viceId);
    }       

    /*
     * This code is taken from cklog -- it lets people
     * automatically register with the ptserver in foreign cells
     */

#ifdef ALLOW_REGISTER
    if (*status == 0) {
        if (viceId != ANONYMOUSID) {
#else /* ALLOW_REGISTER */
            if ((*status == 0) && (viceId != ANONYMOUSID))
#endif /* ALLOW_REGISTER */
            {
#ifdef AFS_ID_TO_NAME
                strncpy(username_copy, username, BUFSIZ);
                snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
#endif /* AFS_ID_TO_NAME */
            }
#ifdef ALLOW_REGISTER
        } else if (strcmp(realm_of_user, realm_of_cell) != 0) {
            int i;
            if (dflag) {
                printf("doing first-time registration of %s "
                        "at %s\n", username, cell_to_use);
            }
            strncpy(aclient->name, username, MAXKTCNAMELEN - 1);
            aclient->name[MAXKTCNAMELEN - 1] = '\0';
            strcpy(aclient->instance, "");
            strncpy(aclient->cell, cell_to_use, MAXKTCREALMLEN - 1);
            aclient->cell[MAXKTCREALMLEN - 1] = '\0';

            for ( i=0; aclient->cell[i]; i++ ) {
                if ( islower(aclient->cell[i]) )
                    aclient->cell[i] = toupper(aclient->cell[i]);
            }

            if ((*status = ktc_SetToken(aserver, atoken, aclient, 0))) {
                afs_com_err(progname, *status,
                             "while obtaining tokens for cell %s\n",
                             cell_to_use);
                *status = AKLOG_TOKEN;
                return ;
            }

            /*
             * In case you're wondering, we don't need to change the
             * filename here because we're still connecting to the
             * same cell -- we're just using a different authentication
             * level
             */

            if ((*status = pr_Initialize(1L, confname, aserver->cell))) {
                printf("pr_Initialize Error %s\n",  afs_error_message(*status));
                return;
            }

            /* copy the name because pr_CreateUser lowercases the realm */
            strncpy(username_copy, username, BUFSIZ);

            viceId = 0;
            *status = pr_CreateUser(username_copy, &viceId);

            if (*status) {
                printf("%s: unable to create remote PTS "
                        "user %s in cell %s (status: %s).\n", progname,
                        username_copy, cell_to_use, afs_error_message(*status));
            } else {
                printf("created cross-cell entry for %s (Id %d) at %s\n",
                        username_copy, viceId, cell_to_use);
#ifdef AFS_ID_TO_NAME
                snprintf (username, BUFSIZ, "%s (AFS ID %d)", username_copy, (int) viceId);
#endif /* AFS_ID_TO_NAME */
            }
        }
    }
#endif /* ALLOW_REGISTER */
}
예제 #14
0
/*
 * Log to a cell.  If the cell has already been logged to, return without
 * doing anything.  Otherwise, log to it and mark that it has been logged
 * to.
 */
static int auth_to_cell(krb5_context context, char *user, char *cell, char *realm)
{
    int status = 0;
    char username[BUFSIZ];	/* To hold client username structure */
    afs_int32 viceId;		/* AFS uid of user */

    char name[ANAME_SZ];	/* Name of afs key */
    char primary_instance[INST_SZ];	/* Instance of afs key */
    char secondary_instance[INST_SZ];	/* Backup instance to try */
    int try_secondary = 0;		/* Flag to indicate if we try second */
    char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
    char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
    char local_cell[MAXCELLCHARS+1];
    char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */
    static char lastcell[MAXCELLCHARS+1] = { 0 };
    static char confname[512] = { 0 };
    krb5_creds *v5cred = NULL;
    struct ktc_principal aserver;
    struct ktc_principal aclient;
    struct ktc_token atoken, btoken;
    int afssetpag = 0, uid = -1;
    struct passwd *pwd;

    memset(name, 0, sizeof(name));
    memset(primary_instance, 0, sizeof(primary_instance));
    memset(secondary_instance, 0, sizeof(secondary_instance));
    memset(realm_of_user, 0, sizeof(realm_of_user));
    memset(realm_of_cell, 0, sizeof(realm_of_cell));
    syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog starting: user %s uid %d", user, getuid());
    if (confname[0] == '\0') {
        strncpy(confname, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confname));
        confname[sizeof(confname) - 2] = '\0';
    }

    /* NULL or empty cell returns information on local cell */
    if ((status = get_cellconfig(cell, &ak_cellconfig,
                                 local_cell, linkedcell))) {
        syslog(LOG_AUTH|LOG_ERR, "LAM aklog: get_cellconfig returns %d", status);
        return(status);
    }

    strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS);
    cell_to_use[MAXCELLCHARS] = 0;

    /*
     * Find out which realm we're supposed to authenticate to.  If one
     * is not included, use the kerberos realm found in the credentials
     * cache.
     */

    if (realm && realm[0]) {
        strcpy(realm_of_cell, realm);
    }
    else {
        char *afs_realm = afs_realm_of_cell(context, &ak_cellconfig, FALSE);

        if (!afs_realm) {
            syslog(LOG_AUTH|LOG_ERR, "LAM aklog: afs_realm_of_cell returns %d", status);
            return AFSCONF_FAILURE;
        }

        strcpy(realm_of_cell, afs_realm);
    }

    /* We use the afs.<cellname> convention here...
     *
     * Doug Engert's original code had principals of the form:
     *
     * "afsx/cell@realm"
     *
     * in the KDC, so the name wouldn't conflict with DFS.  Since we're
     * not using DFS, I changed it just to look for the following
     * principals:
     *
     * afs/<cell>@<realm>
     * afs@<realm>
     *
     * Because people are transitioning from afs@realm to afs/cell,
     * we configure things so that if the first one isn't found, we
     * try the second one.  You can select which one you prefer with
     * a configure option.
     */

    strcpy(name, AFSKEY);

    if (1 || strcasecmp(cell_to_use, realm_of_cell) != 0) {
        strncpy(primary_instance, cell_to_use, sizeof(primary_instance));
        primary_instance[sizeof(primary_instance)-1] = '\0';
        if (strcasecmp(cell_to_use, realm_of_cell) == 0) {
            try_secondary = 1;
            secondary_instance[0] = '\0';
        }
    } else {
        primary_instance[0] = '\0';
        try_secondary = 1;
        strncpy(secondary_instance, cell_to_use,
                sizeof(secondary_instance));
        secondary_instance[sizeof(secondary_instance)-1] = '\0';
    }

    /*
     * Extract the session key from the ticket file and hand-frob an
     * afs style authenticator.
     */

    /*
     * Try to obtain AFS tickets.  Because there are two valid service
     * names, we will try both, but trying the more specific first.
     *
     *	afs/<cell>@<realm> i.e. allow for single name with "."
     * 	afs@<realm>
     */

    status = get_credv5(context, user, name, primary_instance, realm_of_cell,
                        &v5cred);

    if ((status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
            status == KRB5KRB_ERR_GENERIC) && !realm_of_cell[0]) {
        char *afs_realm = afs_realm_of_cell(context, &ak_cellconfig, TRUE);

        if (!afs_realm) {
            syslog(LOG_AUTH|LOG_ERR, "LAM aklog: afs_realm_of_cell returns %d", status);
            return AFSCONF_FAILURE;
        }

        strcpy(realm_of_cell, afs_realm);

        if (strcasecmp(cell_to_use, realm_of_cell) == 0) {
            try_secondary = 1;
            secondary_instance[0] = '\0';
        }

        status = get_credv5(context, user, name, primary_instance,
                            realm_of_cell, &v5cred);
    }
    if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
            status == KRB5KRB_ERR_GENERIC) {
        if (try_secondary)
            status = get_credv5(context, user, name, secondary_instance,
                                realm_of_cell, &v5cred);
    }

    if (status) {
        syslog(LOG_AUTH|LOG_ERR, "LAM aklog: get_credv5 returns %d", status);
        return status;
    }

    strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1);
    strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1);
    strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1);

    /*
     * The default is to use rxkad2b, which means we put in a full
     * V5 ticket.  If the user specifies -524, we talk to the
     * 524 ticket converter.
     */

    {
        char *p;
        int len;

        len = min(get_princ_len(context, v5cred->client, 0),
                  second_comp(context, v5cred->client) ?
                  MAXKTCNAMELEN - 2 : MAXKTCNAMELEN - 1);
        strncpy(username, get_princ_str(context, v5cred->client, 0), len);
        username[len] = '\0';

        if (second_comp(context, v5cred->client)) {
            strcat(username, ".");
            p = username + strlen(username);
            len = min(get_princ_len(context, v5cred->client, 1),
                      MAXKTCNAMELEN - strlen(username) - 1);
            strncpy(p, get_princ_str(context, v5cred->client, 1), len);
            p[len] = '\0';
        }

        memset(&atoken, 0, sizeof(atoken));
        atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
        atoken.startTime = v5cred->times.starttime;;
        atoken.endTime = v5cred->times.endtime;
        memcpy(&atoken.sessionKey, get_cred_keydata(v5cred),
               get_cred_keylen(v5cred));
        atoken.ticketLen = v5cred->ticket.length;
        memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
    }

    if ((status = get_user_realm(context, realm_of_user))) {
        syslog(LOG_AUTH|LOG_ERR, "LAM aklog: get_user_realm returns %d", status);
        return KRB5_REALM_UNKNOWN;
    }
    if (strcmp(realm_of_user, realm_of_cell)) {
        strcat(username, "@");
        strcat(username, realm_of_user);
    }

    strcpy(lastcell, aserver.cell);

    /*
     * This is a crock, but it is Transarc's crock, so
     * we have to play along in order to get the
     * functionality.  The way the afs id is stored is
     * as a string in the username field of the token.
     * Contrary to what you may think by looking at
     * the code for tokens, this hack (AFS ID %d) will
     * not work if you change %d to something else.
     */

#if 0
    /* This actually crashes long-running daemons */
    if (!pr_Initialize (0, confname, aserver.cell))
        status = pr_SNameToId (username, &viceId);
    if ((status == 0) && (viceId != ANONYMOUSID))
        sprintf (username, "AFS ID %d", (int) viceId);
#else
    /*
     * This actually only works assuming that your uid and pts space match
     * and probably this works only for the local cell anyway.
     */

    if ((uid = getuid()) == 0) {
        if ((pwd = getpwnam(user)) == NULL) {
            syslog(LOG_AUTH|LOG_ERR, "LAM aklog: getpwnam %s failed", user);
            return AUTH_FAILURE;
        }
    }

    /* Don't do first-time registration. Handle only the simple case */
    if ((status == 0) && (viceId != ANONYMOUSID))
        sprintf (username, "AFS ID %d", ((uid==0)?(int)pwd->pw_uid:(int)uid));
#endif

    /* Reset the "aclient" structure before we call ktc_SetToken.
     * This structure was first set by the ktc_GetToken call when
     * we were comparing whether identical tokens already existed.
     */
    strncpy(aclient.name, username, MAXKTCNAMELEN - 1);
    strcpy(aclient.instance, "");
    strncpy(aclient.cell, realm_of_user, MAXKTCREALMLEN - 1);

#ifndef AFS_AIX51_ENV
    /* on AIX 4.1.4 with AFS 3.4a+ if a write is not done before
     * this routine, it will not add the token. It is not clear what
     * is going on here! So we will do the following operation.
     * On AIX 5 this kills our parent. So we won't.
     */
    write(2,"",0); /* dummy write */
#endif
    afssetpag = (getpagvalue("afs") > 0) ? 1 : 0;
    if (uid == 0) {
        struct sigaction newAction, origAction;
        pid_t cid, pcid;
        int wstatus;

        sigemptyset(&newAction.sa_mask);
        newAction.sa_handler = SIG_DFL;
        newAction.sa_flags = 0;
        status = sigaction(SIGCHLD, &newAction, &origAction);
        if (status) {
            syslog(LOG_AUTH|LOG_ERR, "LAM aklog: sigaction returned %d", status);
            return AUTH_FAILURE;
        }
        syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog: in daemon? forking to set tokens");
        cid = fork();
        if (cid <= 0) {
            syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog child: setting tokens");
            setuid(pwd->pw_uid);
            status = ktc_SetToken(&aserver, &atoken, &aclient, afssetpag);
            if (status != 0)
                syslog(LOG_AUTH|LOG_ERR, "LAM aklog child: set tokens, returning %d", status);
            exit((status == 0)?0:255);
        } else {
            do {
                pcid = waitpid(cid, &wstatus, 0);
            } while ((pcid == -1) && (errno == EINTR));
            if ((pcid == cid) && WIFEXITED(wstatus))
                status = WEXITSTATUS(wstatus);
            else
                status = -1;
        }
        syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog: collected child status %d", status);
        sigaction(SIGCHLD, &origAction, NULL);
    } else {
        status = ktc_SetToken(&aserver, &atoken, &aclient, afssetpag);
    }
    if (status != 0)
        syslog(LOG_AUTH|LOG_ERR, "LAM aklog: set tokens returned %d", status);
    else
        syslog(LOG_AUTH|LOG_DEBUG, "LAM aklog: set tokens, pag %d", getpagvalue("afs"));
    return(status);
}
예제 #15
0
/*
 * Requires that you already possess a TGT.
 */
afs_int32
ka_GetAFSTicket(char *name, char *instance, char *realm, Date lifetime,
		afs_int32 flags)
{
    afs_int32 code;
    struct ktc_token token;
    struct ktc_principal server, client;

    code = ka_GetServerToken("afs", "", realm, lifetime, &token, /*new */ 1,
			     /*dosetpag */ flags);
    if (code)
	return code;
    if (ktc_OldPioctl()) {
	int local;
	char username[MAXKTCNAMELEN];
	afs_int32 viceId;
	int len;
	char *whoami = "UserAuthenticate: ptserver";

	strcpy(server.name, "afs");
	strcpy(server.instance, "");
	code = ka_ExpandCell(realm, server.cell, &local);
	if (code)
	    return code;
	code = pr_Initialize(0, AFSDIR_CLIENT_ETC_DIRPATH, server.cell);
	if (code) {
	    afs_com_err(whoami, code, "initializing ptserver in cell '%s'",
		    server.cell);
	    return 0;
	}
	len = strlen(name);
	if (instance[0])
	    len += strlen(instance) + 1;
	if (len >= sizeof(username)) {
	    fprintf(stderr, "user's name '%s'.'%s' would be too large\n",
		    name, instance);
	    return 0;
	}
	strcpy(username, name);
	if (instance[0]) {
	    strcat(username, ".");
	    strcat(username, instance);
	}
	code = pr_SNameToId(username, &viceId);
	/* Before going further, shutdown the pr ubik connection */
	pr_End();
	if ((code == 0) && (viceId == ANONYMOUSID))
	    code = PRNOENT;
	if (code) {
	    afs_com_err(whoami, code, "translating %s to id", username);
	    return 0;
	}

	sprintf(client.name, "AFS ID %d", viceId);
	strcpy(client.instance, "");
	strcpy(client.cell, server.cell);
	code = ktc_SetToken(&server, &token, &client, /*dosetpag */ 0);
	if (code)
	    return code;
    }
    return code;
}
예제 #16
0
int
main(int argc, char **argv)
{
    register afs_int32 code;
    char op[8];
    char name[PR_MAXNAMELEN];
    afs_int32 id, oid = ANONYMOUSID, gid;
    afs_int32 pos;
    unsigned int i;
    int n;
    struct prentry entry;
    prlist alist;
    idlist lid;
    namelist lnames;
    struct hostent *hostinfo;
    struct in_addr *hostaddr;
    afs_int32 *ptr;
    char *foo;
    afs_int32 over;
    char *cell;

#ifdef	AFS_AIX32_ENV
    /*
     * The following signal action for AIX is necessary so that in case of a 
     * crash (i.e. core is generated) we can include the user's data section 
     * in the core dump. Unfortunately, by default, only a partial core is
     * generated which, in many cases, isn't too useful.
     */
    struct sigaction nsa;

    sigemptyset(&nsa.sa_mask);
    nsa.sa_handler = SIG_DFL;
    nsa.sa_flags = SA_FULLDUMP;
    sigaction(SIGSEGV, &nsa, NULL);
#endif
    whoami = argv[0];

    initialize_PT_error_table();

    strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH);
    cell = 0;
    n = 1;
    while (n < argc) {
	int arglen = strlen(argv[n]);
	char arg[256];
	lcstring(arg, argv[n], sizeof(arg));
#define IsArg(a) (strncmp (arg,a, arglen) == 0)
	if (IsArg("-testconfdir"))
	    strncpy(confdir, argv[++n], sizeof(confdir));
	else if (IsArg("client"))
	    strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir));
	else if (IsArg("server"))
	    strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir));
	else if (IsArg("0") || IsArg("1") || IsArg("2"))
	    security = atoi(argv[n]);
	else if (IsArg("-ignoreexist"))
	    ignoreExist++;
	else if (IsArg("-cell"))
	    cell = argv[++n];
	else {
	    printf
		("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n");
	    exit(1);
	}
	n++;
    }

    printf("Using CellServDB file in %s\n", confdir);
    if (security == 0)
	printf("Making unauthenticated connection to prserver\n");

    code = pr_Initialize(security, confdir, cell);
    if (code) {
	afs_com_err(whoami, code, "Couldn't initialize protection library");
	exit(1);
    }

    while (1) {
	char *s;

	printf("pr> ");
	s = fgets(line, sizeof(line), stdin);
	if (s == NULL)
	    break;
	lineProgress = 0;

	code = GetString(op, sizeof(op));
	if (code) {
	    afs_com_err(whoami, PRBADARG,
		    "error reading opcode in line '%s', got '%.*s'", line,
		    sizeof(op), op);
	    exit(1);
	}
	if (strlen(op) == 0)
	    continue;		/* no input */

	if (!strcmp(op, "cr")) {
	    if (GetString(name, sizeof(name)) || GetInt32(&id)
		|| GetInt32(&oid))
		code = PRBADARG;
	    /* use ubik_Call to do the work, finding an up server and handling
	     * the job of finding a sync site, if need be */
	    else
		code = ubik_PR_INewEntry(pruclient, 0, name, id, oid);
	    if (CodeOk(code))
		afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid);
	} else if (!strcmp(op, "sf")) {
	    afs_int32 mask, access, gq, uq;
	    if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access)
		|| GetInt32(&gq) || GetInt32(&uq))
		code = PRBADARG;
	    else
		code =
		    ubik_PR_SetFieldsEntry(pruclient, 0, id, mask,
			      access, gq, uq, 0, 0);
	    if (CodeOk(code))
		afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask,
			access, gq, uq);
	} else if (!strcmp(op, "ce")) {
	    char newname[PR_MAXNAMELEN];
	    afs_int32 newid;
	    if (GetInt32(&id) || GetString(newname, sizeof(newname))
		|| GetInt32(&oid) || GetInt32(&newid))
		code = PRBADARG;
	    else
		code =
		    ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid,
			      newid);
	    if (CodeOk(code))
		afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname,
			oid, newid);
	} else if (!strcmp(op, "wh")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    else
		printf("location %d\n", pos);
	} else if (!strcmp(op, "du")) {
	    memset(&entry, 0, sizeof(entry));
	    /* scanf("%d",&pos); */
	    if (GetInt32(&pos))
		code = PRBADARG;
	    else
		code = ubik_PR_DumpEntry(pruclient, 0, pos, (struct prdebugentry *)&entry);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		PrintEntry(pos, &entry, /*indent */ 0);
#if 0
		printf("The contents of the entry for %d are:\n", entry.id);
		printf("flags %d next %d\n", entry.flags, entry.next);
		printf("Groups (or members) \n");
		for (i = 0; i < PRSIZE; i++)
		    printf("%d\n", entry.entries[i]);
		printf("nextID %d nextname %d name %s\n", entry.nextID,
		       entry.nextName, entry.name);
		printf("owner %d creator %d\n", entry.owner, entry.creator);
#endif
	    }
	} else if (!strcmp(op, "add") || !strcmp(op, "au")) {
	    /* scanf("%d %d",&id,&gid); */
	    if (GetInt32(&id) || GetInt32(&gid))
		code = PRBADARG;
	    else
		code = ubik_PR_AddToGroup(pruclient, 0, id, gid);
	    if (CodeOk(code))
		afs_com_err(whoami, code, "on %s %d %d", op, id, gid);
	} else if (!strcmp(op, "iton")) {
	    lid.idlist_val = (afs_int32 *) malloc(20 * sizeof(afs_int32));
	    ptr = lid.idlist_val;
	    lid.idlist_len = 0;
	    foo = line;
	    skip(&foo);
	    while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) {
		lid.idlist_len++;
		skip(&foo);
		ptr++;
	    }
	    if (*foo) {
		fprintf(stderr, "too many values specified; max is %d\n", 20);
	    }
	    lnames.namelist_val = 0;
	    lnames.namelist_len = 0;
	    code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		for (i = 0; i < lnames.namelist_len; i++) {
		    printf("id %d name %s\n", lid.idlist_val[i],
			   lnames.namelist_val[i]);
		}
		free(lnames.namelist_val);
	    }
	    free(lid.idlist_val);
	    lid.idlist_val = 0;
	    lid.idlist_len = 0;
	} else if (!strcmp(op, "ntoi")) {
	    lnames.namelist_val =
		(prname *) malloc(PR_MAXLIST * PR_MAXNAMELEN);
	    lnames.namelist_len = 0;
	    foo = line;
	    skip(&foo);
	    for (i = 0; ((lnames.namelist_len < PR_MAXLIST)
			 && (sscanf(foo, "%s", lnames.namelist_val[i]) !=
			     EOF)); i++) {
		lnames.namelist_len++;
		skip(&foo);
	    }
	    if (*foo) {
		fprintf(stderr, "too many values specified; max is %d\n",
			PR_MAXLIST);
	    }
	    lid.idlist_val = 0;
	    lid.idlist_len = 0;
	    code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		for (i = 0; i < lid.idlist_len; i++)
		    printf("name %s id %d\n", lnames.namelist_val[i],
			   lid.idlist_val[i]);
		free(lid.idlist_val);
	    }
	    free(lnames.namelist_val);
	    lnames.namelist_val = 0;
	    lnames.namelist_len = 0;
	} else if (!strcmp(op, "del")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_Delete(pruclient, 0, id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	} else if (!strcmp(op, "dg")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_Delete(pruclient, 0, id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	} else if (!strcmp(op, "rm")) {
	    /* scanf("%d %d",&id,&gid); */
	    if (GetInt32(&id) || GetInt32(&gid))
		code = PRBADARG;
	    else
		code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	}
#if defined(SUPERGROUPS)
	else if (!strcmp(op, "lsg")) {
	    alist.prlist_len = 0;
	    alist.prlist_val = 0;
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code =
		    ubik_PR_ListSuperGroups(pruclient, 0, id, &alist,
			      &over);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		ptr = alist.prlist_val;
		if (over) {
		    printf("Number of groups greater than PR_MAXGROUPS!\n");
		    printf("Excess of %d.\n", over);
		}
		for (i = 0; i < alist.prlist_len; i++, ptr++)
		    printf("%d\n", *ptr);
		free(alist.prlist_val);
		alist.prlist_len = 0;
		alist.prlist_val = 0;
	    }
	}
#endif /* SUPERGROUPS */
	else if (!strcmp(op, "l")) {
	    alist.prlist_len = 0;
	    alist.prlist_val = 0;
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		ptr = alist.prlist_val;
		if (over) {
		    printf("Number of groups greater than PR_MAXGROUPS!\n");
		    printf("Excess of %d.\n", over);
		}
		for (i = 0; i < alist.prlist_len; i++, ptr++)
		    printf("%d\n", *ptr);
		free(alist.prlist_val);
		alist.prlist_len = 0;
		alist.prlist_val = 0;
	    }
	} else if (!strcmp(op, "lh")) {
	    alist.prlist_len = 0;
	    alist.prlist_val = 0;
	    /* scanf("%d",&id); */
	    if (GetString(name, sizeof(name)))
		code = PRBADARG;
	    else if (!(hostinfo = gethostbyname(name)))
		code = PRBADARG;
	    else {
		hostaddr = (struct in_addr *)hostinfo->h_addr_list[0];
		id = ntohl(hostaddr->s_addr);
		code =
		    ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over);
	    }
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		ptr = alist.prlist_val;
		if (over) {
		    printf("Number of groups greater than PR_MAXGROUPS!\n");
		    printf("Excess of %d.\n", over);
		}
		for (i = 0; i < alist.prlist_len; i++, ptr++)
		    printf("%d\n", *ptr);
		free(alist.prlist_val);
		alist.prlist_len = 0;
		alist.prlist_val = 0;
	    }
	}
#if defined(SUPERGROUPS)
	else if (!strcmp(op, "m")) {
	    alist.prlist_len = 0;
	    alist.prlist_val = 0;
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code =
		    ubik_PR_ListElements(pruclient, 0, id, &alist,
			      &over);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS) {
		ptr = alist.prlist_val;
		if (over) {
		    printf("Number of groups greater than PR_MAXGROUPS!\n");
		    printf("Excess of %d.\n", over);
		}
		for (i = 0; i < alist.prlist_len; i++, ptr++)
		    printf("%d\n", *ptr);
		free(alist.prlist_val);
		alist.prlist_len = 0;
		alist.prlist_val = 0;
	    }
	}
#endif /* SUPERGROUPS */
	else if (!strcmp(op, "nu")) {
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name)))
		code = PRBADARG;
	    else
		code = pr_CreateUser(name, &id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("Id is %d.\n", id);
	} else if (!strcmp(op, "ng")) {
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name)))
		code = PRBADARG;
	    else
		code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("Id is %d.\n", id);
	} else if (!strcmp(op, "lm")) {
	    code = ubik_PR_ListMax(pruclient, 0, &id, &gid);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("Max user id is %d, max (really min) group is %d.\n",
		       id, gid);
	} else if (!strcmp(op, "smu")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_SetMax(pruclient, 0, id, 0);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	} else if (!strcmp(op, "smg")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = ubik_PR_SetMax(pruclient, 0, id, 1);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	} else if (!strcmp(op, "sin")) {
	    /* scanf("%d",&id); */
	    if (GetInt32(&id))
		code = PRBADARG;
	    else
		code = pr_SIdToName(id, name);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("id %d name %s\n", id, name);
	} else if (!strcmp(op, "sni")) {
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name)))
		code = PRBADARG;
	    else
		code = pr_SNameToId(name, &id);
	    if (CodeOk(code))
		printf("%s\n", pr_ErrorMsg(code));
	    if (code == PRSUCCESS)
		printf("name %s id %d\n", name, id);
	} else if (!strcmp(op, "fih")) {
	    char tname[128];
	    struct PrUpdateEntry uentry;
	    memset(&uentry, 0, sizeof(uentry));
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name))) {
		code = PRBADARG;
		continue;
	    }
	    code = pr_SNameToId(name, &id);
	    if (CodeOk(code)) {
		printf("%s\n", pr_ErrorMsg(code));
		continue;
	    }
	    code = pr_SIdToName(id, tname);
	    if (code == PRSUCCESS) {
		printf
		    ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
		     name, id);
/*		continue;*/
	    }
	    uentry.Mask = PRUPDATE_IDHASH;
	    code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
	    if (code) {
		printf("Failed to update entry %s (err=%d)\n", name, code);
		continue;
	    }
	} else if (!strcmp(op, "fnh")) {
	    int tid;
	    struct PrUpdateEntry uentry;
	    memset(&uentry, 0, sizeof(uentry));
	    /* scanf("%d", &id); */
	    if (GetInt32(&id)) {
		code = PRBADARG;
		continue;
	    }
	    code = pr_SIdToName(id, name);
	    if (CodeOk(code)) {
		printf("%s\n", pr_ErrorMsg(code));
		continue;
	    }
	    code = pr_SNameToId(name, &tid);
	    if (code == PRSUCCESS) {
		printf
		    ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
		     id, name);
/*		continue;*/
	    }
	    uentry.Mask = PRUPDATE_NAMEHASH;
	    code =
		ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
	    if (code) {
		printf("Failed to update entry with id %d (err=%d)\n", id,
		       code);
		continue;
	    }
	}
#if defined(SUPERGROUPS)
	else if (!strcmp(op, "fih")) {
	    char tname[128];
	    struct PrUpdateEntry uentry;
	    memset(&uentry, 0, sizeof(uentry));
	    /* scanf("%s",name); */
	    if (GetString(name, sizeof(name))) {
		code = PRBADARG;
		continue;
	    }
	    code = pr_SNameToId(name, &id);
	    if (CodeOk(code)) {
		printf("%s\n", pr_ErrorMsg(code));
		continue;
	    }
	    code = pr_SIdToName(id, tname);
	    if (code == PRSUCCESS) {
		printf
		    ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n",
		     name, id);
/*		continue;*/
	    }
	    uentry.Mask = PRUPDATE_IDHASH;
	    code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry);
	    if (code) {
		printf("Failed to update entry %s (err=%d)\n", name, code);
		continue;
	    }
	} else if (!strcmp(op, "fnh")) {
	    int tid;
	    struct PrUpdateEntry uentry;
	    memset(&uentry, 0, sizeof(uentry));
	    /* scanf("%d", &id); */
	    if (GetInt32(&id)) {
		code = PRBADARG;
		continue;
	    }
	    code = pr_SIdToName(id, name);
	    if (CodeOk(code)) {
		printf("%s\n", pr_ErrorMsg(code));
		continue;
	    }
	    code = pr_SNameToId(name, &tid);
	    if (code == PRSUCCESS) {
		printf
		    ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n",
		     id, name);
/*		continue;*/
	    }
	    uentry.Mask = PRUPDATE_NAMEHASH;
	    code =
		ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry);
	    if (code) {
		printf("Failed to update entry with id %d (err=%d)\n", id,
		       code);
		continue;
	    }
	}
#endif /* SUPERGROUPS */
	else if (!strcmp(op, "?"))
	    PrintHelp();
	else if (!strcmp(op, "q"))
	    exit(0);
	else
	    printf("Unknown op: '%s'! ? for help\n", op);
    }
}
예제 #17
0
파일: aklog.c 프로젝트: mit-athena/aklog
/*
 * Log to a cell.  If the cell has already been logged to, return without
 * doing anything.  Otherwise, log to it and mark that it has been logged
 * to.  */
static int auth_to_cell(char *cell, char *realm)
{
  int status = AKLOG_SUCCESS;
  char username[BUFSIZ];	/* To hold client username structure */
  long viceId;			/* AFS uid of user */

  char name[ANAME_SZ];		/* Name of afs key */
  char instance[INST_SZ];	/* Instance of afs key */
  char realm_of_user[REALM_SZ]; /* Kerberos realm of user */
  char realm_of_cell[REALM_SZ]; /* Kerberos realm of cell */
  char local_cell[MAXCELLCHARS+1];
  char cell_to_use[MAXCELLCHARS+1]; /* Cell to authenticate to */

  int i,j;

  CREDENTIALS c;
  struct ktc_principal aserver;
  struct ktc_principal aclient;
  struct ktc_token atoken, btoken;

  /* try to avoid an expensive call to get_cellconfig */
  if (cell && ll_string_check(&authedcells, cell))
    {
      if (dflag)
	printf("Already authenticated to %s (or tried to)\n", cell);
      return(AKLOG_SUCCESS);
    }

  memset(name, 0, sizeof(name));
  memset(instance, 0, sizeof(instance));
  memset(realm_of_user, 0, sizeof(realm_of_user));
  memset(realm_of_cell, 0, sizeof(realm_of_cell));

  /* NULL or empty cell returns information on local cell */
  if (status = get_cellconfig(cell, &ak_cellconfig, local_cell))
    return(status);

  strncpy(cell_to_use, ak_cellconfig.name, MAXCELLCHARS);
  cell_to_use[MAXCELLCHARS] = 0;

  if (ll_string_check(&authedcells, cell_to_use))
    {
      if (dflag)
	printf("Already authenticated to %s (or tried to)\n", cell_to_use);
      return(AKLOG_SUCCESS);
    }

  /*
   * Record that we have attempted to log to this cell.  We do this
   * before we try rather than after so that we will not try
   * and fail repeatedly for one cell.
   */
  (void)ll_add_string(&authedcells, cell_to_use);

  if (dflag)
    printf("Authenticating to cell %s.\n", cell_to_use);

  if (realm && realm[0])
    strcpy(realm_of_cell, realm);
  else
    strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig));

  /* We use the afs.<cellname> convention here... */
  strcpy(name, AFSKEY);
  strncpy(instance, cell_to_use, sizeof(instance));
  instance[sizeof(instance)-1] = '\0';

  /*
   * Extract the session key from the ticket file and hand-frob an
   * afs style authenticator.
   */

  /*
   * Try to obtain AFS tickets.  Because there are two valid service
   * names, we will try both, but trying the more specific first.
   *
   * 	afs.<cell>@<realm>
   * 	afs@<realm>
   */
  if (dflag)
    printf("Getting tickets: %s.%s@%s\n", name, instance, realm_of_cell);
  status = get_cred(name, instance, realm_of_cell, &c);
  if (status == KDC_PR_UNKNOWN)
    {
      if (dflag)
	printf("Getting tickets: %s@%s\n", name, realm_of_cell);
      status = get_cred(name, "", realm_of_cell, &c);
    }

  if (status != KSUCCESS)
    {
      if (dflag)
	printf("Kerberos error code returned by get_cred: %d\n", status);
      fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n",
	      progname, cell_to_use, krb_err_txt[status]);
      return(AKLOG_KERBEROS);
    }

  strncpy(aserver.name, AFSKEY, MAXKTCNAMELEN - 1);
  strncpy(aserver.instance, AFSINST, MAXKTCNAMELEN - 1);
  strncpy(aserver.cell, cell_to_use, MAXKTCREALMLEN - 1);

  strcpy (username, c.pname);
  if (c.pinst[0])
    {
      strcat(username, ".");
      strcat(username, c.pinst);
    }

  atoken.kvno = c.kvno;
  atoken.startTime = c.issue_date;
  /* ticket lifetime is in five-minutes blocks. */
  atoken.endTime = c.issue_date + ((unsigned char)c.lifetime * 5 * 60);
  memcpy(&atoken.sessionKey, c.session, 8);
  atoken.ticketLen = c.ticket_st.length;
  memcpy(atoken.ticket, c.ticket_st.dat, atoken.ticketLen);

  if (!force &&
      !ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient) &&
      atoken.kvno == btoken.kvno &&
      atoken.ticketLen == btoken.ticketLen &&
      !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
      !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
    {
      if (dflag)
	printf("Identical tokens already exist; skipping.\n");
      return 0;
    }

  if (noprdb)
    {
      if (dflag)
	printf("Not resolving name %s to id (-noprdb set)\n", username);
    }
  else
    {
      if ((status = krb_get_tf_realm(TKT_FILE, realm_of_user)) != KSUCCESS)
	{
	  fprintf(stderr, "%s: Couldn't determine realm of user: %s)",
		  progname, krb_err_txt[status]);
	  return(AKLOG_KERBEROS);
	}
      if (strcmp(realm_of_user, realm_of_cell))
	{
	  strcat(username, "@");
	  strcat(username, realm_of_user);
	}

      if (dflag)
	printf("About to resolve name %s to id\n", username);

      if (!pr_Initialize (0, AFSDIR_CLIENT_ETC_DIRPATH, aserver.cell))
	status = pr_SNameToId (username, &viceId);

      if (dflag)
	{
	  if (status)
	    printf("Error %d\n", status);
	  else
	    printf("Id %d\n", viceId);
	}

      /*
       * This is a crock, but it is Transarc's crock, so
       * we have to play along in order to get the
       * functionality.  The way the afs id is stored is
       * as a string in the username field of the token.
       * Contrary to what you may think by looking at
       * the code for tokens, this hack (AFS ID %d) will
       * not work if you change %d to something else.
       */
      if ((status == 0) && (viceId != ANONYMOUSID))
	sprintf (username, "AFS ID %d", viceId);
    }

  if (dflag)
    printf("Set username to %s\n", username);

  /* Reset the "aclient" structure before we call ktc_SetToken.
   * This structure was first set by the ktc_GetToken call when
   * we were comparing whether identical tokens already existed.
   */
  strncpy(aclient.name, username, MAXKTCNAMELEN - 1);
  strcpy(aclient.instance, "");
  strncpy(aclient.cell, c.realm, MAXKTCREALMLEN - 1);

  if (dflag)
    printf("Getting tokens.\n");
  if (status = ktc_SetToken(&aserver, &atoken, &aclient, 0))
    {
      fprintf(stderr,
	      "%s: unable to obtain tokens for cell %s (status: %d).\n",
	      progname, cell_to_use, status);
      status = AKLOG_TOKEN;
    }

  return(status);
}