Ejemplo n.º 1
0
/*
 * Build a list of tokens, delete the bad ones (the ones to remove from the
 * permissions list,) destroy all tokens, and then re-register the good ones.
 * Ugly, but it works.
 */
int
uss_fs_UnlogToken(char *celln)
{
    int count = 0, index, index2;
    afs_int32 code = 0, cnt = 0;
    struct ktc_principal serviceName;
    struct tokenInfo *tokenInfoP, *tp;

    do {
	code = ktc_ListTokens(count, &count, &serviceName);
	cnt++;
    } while (!code);
    count = cnt - 1;
    tokenInfoP = malloc((sizeof(struct tokenInfo) * count));
    for (code = index = index2 = 0; (!code) && (index < count); index++) {
	tp = tokenInfoP + index;
	code = ktc_ListTokens(index2, &index2, &tp->service);
	if (!code) {
	    code =
		ktc_GetToken(&tp->service, &tp->token,
			     sizeof(struct ktc_token), &tp->client);
	    if (!code) {
		tp->deleted = (!strcmp(celln, tp->client.cell) ? 1 : 0);
		if (tp->deleted)
		    cnt = 1;
	    }
	}
    }
    if ((code = ktc_ForgetAllTokens())) {
	printf("uss_fs_UnlogToken: could not discard tickets, code %d\n",
	       code);
	exit(1);
    }
    for (code = index = 0; index < count; index++) {
	tp = tokenInfoP + index;
	if (!(tp->deleted)) {
	    code = ktc_SetToken(&tp->service, &tp->token, &tp->client, 0);
	    if (code) {
		printf
		    ("uss_fs_UnlogToken: Couldn't re-register token, code = %d\n",
		     code);
	    }
	}
    }
    return 0;
}
Ejemplo n.º 2
0
afs_int32
afsconf_ClientAuthToken(struct afsconf_cell *info,
			afsconf_secflags flags,
			struct rx_securityClass **sc,
			afs_int32 *scIndex,
			time_t *expires)
{
    struct ktc_principal sname;
    struct ktc_token ttoken;
    int encryptLevel;
    afs_int32 code;

    *sc = NULL;
    *scIndex = RX_SECIDX_NULL;

    strcpy(sname.cell, info->name);
    sname.instance[0] = 0;
    strcpy(sname.name, "afs");
    code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);

    if (code == 0) {
	/* XXX - We should think about how to handle this */
	if (ttoken.kvno < 0 || ttoken.kvno > 256) {
	     fprintf(stderr,
		    "funny kvno (%d) in ticket, proceeding\n",
		    ttoken.kvno);
	}
	if (flags & AFSCONF_SECOPTS_ALWAYSENCRYPT)
	    encryptLevel = rxkad_crypt;
	else
	    encryptLevel = rxkad_clear;
	*sc = rxkad_NewClientSecurityObject(encryptLevel,
					    &ttoken.sessionKey,
					    ttoken.kvno,
					    ttoken.ticketLen,
					    ttoken.ticket);
	*scIndex = RX_SECIDX_KAD;
	if (expires)
	    *expires = ttoken.endTime;
    }
    if (*sc == NULL)
	return AFSCONF_NO_SECURITY_CLASS;

    return code;
}
Ejemplo n.º 3
0
static long
GetToken(long *versionP, struct ktc_encryptionKey *session,
	 int *ticketLenP, char *ticket, char *cell)
{
    struct ktc_principal sname;
    struct ktc_token ttoken;
    long code;

    strcpy(sname.cell, cell);
    sname.instance[0] = 0;
    strcpy(sname.name, "afs");
    code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
    if (code)
	return code;

    *versionP = ttoken.kvno;
    *ticketLenP = ttoken.ticketLen;
    memcpy(ticket, ttoken.ticket, ttoken.ticketLen);
    memcpy(session, &ttoken.sessionKey, sizeof(struct ktc_encryptionKey));
    return 0;
}
Ejemplo n.º 4
0
static int
unlog_ForgetCertainTokens(char **list, int listSize)
{
    int index, index2;
    int count;
    afs_int32 code;
    struct ktc_principal serviceName;
    struct tokenInfo *tokenInfoP;

    /* normalize all the names in the list */
    unlog_NormalizeCellNames(list, listSize);

    /* figure out how many tokens exist */
    count = 0;
    do {
	code = ktc_ListTokens(count, &count, &serviceName);
    } while (!code);

    tokenInfoP =
	(struct tokenInfo *)malloc((sizeof(struct tokenInfo) * count));
    if (!tokenInfoP) {
	perror("unlog_ForgetCertainTokens -- osi_Alloc failed");
	exit(1);
    }

    for (code = index = index2 = 0; (!code) && (index < count); index++) {
	code =
	    ktc_ListTokens(index2, &index2, &(tokenInfoP + index)->service);

	if (!code) {
	    code =
		ktc_GetToken(&(tokenInfoP + index)->service,
			     &(tokenInfoP + index)->token,
			     sizeof(struct ktc_token),
			     &(tokenInfoP + index)->client);

	    if (!code)
		(tokenInfoP + index)->deleted =
		    unlog_CheckUnlogList(list, listSize,
					 &(tokenInfoP + index)->client);
	}
    }

    unlog_VerifyUnlog(list, listSize, tokenInfoP, count);
    code = ktc_ForgetAllTokens();

    if (code) {
	printf("unlog: could not discard tickets, code %d\n", code);
	exit(1);
    }

    for (code = index = 0; index < count; index++) {
	if (!((tokenInfoP + index)->deleted)) {
	    code =
		ktc_SetToken(&(tokenInfoP + index)->service,
			     &(tokenInfoP + index)->token,
			     &(tokenInfoP + index)->client, 0);
	    if (code) {
		fprintf(stderr, "Couldn't re-register token, code = %d\n",
			code);
	    }
	}
    }
    return 0;
}
Ejemplo n.º 5
0
int
main(int argc, char **argv)
{
    char localName[64];
    register afs_int32 code;
    register char *cname;
    struct afsconf_dir *tdir;
    struct ktc_principal tserver;
    struct ktc_token token;

    strcpy(whoami, argv[0]);

    if (argc <= 1) {
	printf
	    ("%s: copies a file system ticket from the local cell to another cell\n",
	     whoami);
	printf("%s: usage is 'setauth <new-cell>\n", whoami);
	exit(1);
    }

    cname = argv[1];

    /* lookup the name of the local cell */
    tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
    if (!tdir) {
	printf("copyauth: can't open dir %s\n", AFSDIR_CLIENT_ETC_DIRPATH);
	exit(1);
    }
    code = afsconf_GetLocalCell(tdir, localName, sizeof(localName));
    if (code) {
	printf("%s: can't determine local cell name\n", whoami);
	exit(1);
    }
    /* done with configuration stuff now */
    afsconf_Close(tdir);


    /* get ticket in local cell */
    strcpy(tserver.cell, localName);
    strcpy(tserver.name, "afs");
    tserver.instance[0] = 0;
    code = ktc_GetToken(&tserver, &token, sizeof(token), NULL);
    if (code) {
	printf
	    ("%s: failed to get '%s' service ticket in cell '%s' (code %d)\n",
	     whoami, tserver.name, tserver.cell, code);
	exit(1);
    }

    /* and now set the ticket in the new cell */
    strcpy(tserver.cell, argv[1]);
    code = ktc_SetToken(&tserver, &token, NULL, 0);
    if (code) {
	printf
	    ("%s: failed to set ticket (code %d), are you sure you're authenticated?\n",
	     whoami, code);
	exit(1);
    }

    /* all done */
    printf("Authentication established for cell %s.\n", cname);
    exit(0);
}
Ejemplo n.º 6
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 *cell, char *realm)
{
    int status = AKLOG_SUCCESS;
    char username[BUFSIZ];	  /* To hold client username structure */

    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 */

    krb5_creds *v5cred = NULL;
#ifdef HAVE_KRB4
    CREDENTIALS c;
#endif
    struct ktc_principal aserver;
    struct ktc_principal aclient;
    struct ktc_token atoken, btoken;
    struct afsconf_cell ak_cellconfig; /* General information about the cell */
    int i;
    int getLinkedCell = 0;

    /* 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));
    memset(&ak_cellconfig, 0, sizeof(ak_cellconfig));

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

  linkedCell:
    if (getLinkedCell)
        strncpy(cell_to_use, ak_cellconfig.linkedCell, MAXCELLCHARS);
    else
        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);
        status = AKLOG_SUCCESS;
        goto done2;
    }

    /*
     * 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);

    /* 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.
     */

    if (usev5) 
    { /* using krb5 */
        int retry = 1;
	int realm_fallback = 0;

        if ((status = get_v5_user_realm(context, realm_of_user)) != KSUCCESS) {
            char * msg;
            
            if (pkrb5_get_error_message)
                msg = pkrb5_get_error_message(context, status);
            else
                msg = (char *)error_message(status);
            fprintf(stderr, "%s: Couldn't determine realm of user: %s\n",
                     progname, msg);
            if (pkrb5_free_error_message)
                pkrb5_free_error_message(context, msg);
            status = AKLOG_KERBEROS;
            goto done;
        }

        if ( strchr(name,'.') != NULL ) {
            fprintf(stderr, "%s: Can't support principal names including a dot.\n",
                    progname);
            status = AKLOG_MISC;
            goto done;
        }

      try_v5:
	if (realm && realm[0]) {
            if (dflag)
                printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm);
            status = get_v5cred(context, name, instance, realm, 
#ifdef HAVE_KRB4
                            use524 ? &c : NULL, 
#else
                            NULL,
#endif
                            &v5cred);
            strcpy(realm_of_cell, realm);
        } else {
	    strcpy(realm_of_cell,
		    afs_realm_of_cell5(context, &ak_cellconfig, realm_fallback));

            if (retry == 1 && realm_fallback == 0) {
                /* Only try the realm_of_user once */
                status = -1;
                if (dflag)
                    printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_user);
                status = get_v5cred(context, name, instance, realm_of_user, 
#ifdef HAVE_KRB4
                                     use524 ? &c : NULL, 
#else
                                     NULL,
#endif
                                     &v5cred);
                if (status == 0) {
                    /* we have determined that the client realm 
                     * is a valid cell realm
                     */
                    strcpy(realm_of_cell, realm_of_user);
                }
            }

            if (status != 0 && (!retry || retry && strcmp(realm_of_user,realm_of_cell))) {
                if (dflag)
                    printf("Getting v5 tickets: %s/%s@%s\n", name, instance, realm_of_cell);
                status = get_v5cred(context, name, instance, realm_of_cell, 
#ifdef HAVE_KRB4
                                     use524 ? &c : NULL, 
#else
                                     NULL,
#endif
                                     &v5cred);
                if (!status && !strlen(realm_of_cell)) 
                    copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), v5cred);
            }
        }

	if (!realm_fallback && status == KRB5_ERR_HOST_REALM_UNKNOWN) {
	    realm_fallback = 1;
	    goto try_v5;
	} else if (status == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN) {
	    if (!realm_fallback && !realm_of_cell[0]) {
		realm_fallback = 1;
		goto try_v5;
	    }
            if (dflag)
                printf("Getting v5 tickets: %s@%s\n", name, realm_of_cell);
            status = get_v5cred(context, name, "", realm_of_cell, 
#ifdef HAVE_KRB4
                                use524 ? &c : NULL, 
#else
                                NULL,
#endif
                                &v5cred);
            if (!status && !strlen(realm_of_cell)) 
                copy_realm_of_ticket(context, realm_of_cell, sizeof(realm_of_cell), v5cred);
	}
     
        if ( status == KRB5KRB_AP_ERR_MSG_TYPE && retry ) {
            retry = 0;
	    realm_fallback = 0;
            goto try_v5;
        }       
    }       
    else 
    {
#ifdef HAVE_KRB4
	if (realm && realm[0])
	    strcpy(realm_of_cell, realm);
	else
	    strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig));

	/*
         * 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);
        }
#else
        status = AKLOG_MISC;
        goto done;
#endif
    } 

    if (status != KSUCCESS)
    {
        char * msg = NULL;
        if (dflag)
            printf("Kerberos error code returned by get_cred: %d\n", status);

        if (usev5) {
            if (pkrb5_get_error_message)
                msg = pkrb5_get_error_message(context, status);
            else
                msg = (char *)error_message(status);
        }
#ifdef HAVE_KRB4
        else
            msg = krb_err_text(status);
#endif
        fprintf(stderr, "%s: Couldn't get %s AFS tickets: %s\n",
                 progname, cell_to_use, msg?msg:"(unknown error)");
        if (usev5 && pkrb5_free_error_message)
            pkrb5_free_error_message(context, msg);
        status = AKLOG_KERBEROS;
        goto done;
    }

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

    if (usev5 && !use524) {
        /* This code inserts the entire K5 ticket into the token
         * No need to perform a krb524 translation which is
         * commented out in the code below
         */
        char * p;
        int len;
        
        len = min(v5cred->client->data[0].length,MAXKTCNAMELEN - 1);
        strncpy(username, v5cred->client->data[0].data, len);
        username[len] = '\0';

        if ( v5cred->client->length > 1 ) {
            strcat(username, ".");
            p = username + strlen(username);
            len = min(v5cred->client->data[1].length, (unsigned int)(MAXKTCNAMELEN - strlen(username) - 1));
            strncpy(p, v5cred->client->data[1].data, 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, v5cred->keyblock.contents, v5cred->keyblock.length);
        atoken.ticketLen = v5cred->ticket.length;
        memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
    } else {
#ifdef HAVE_KRB4
        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);
#else
        status = AKLOG_MISC;
        goto done;
#endif
    }

    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");
        status = AKLOG_SUCCESS;
        goto done2;
    }

    if (noprdb)
    {
        if (dflag)
            printf("Not resolving name %s to id (-noprdb set)\n", username);
    }       
    else    
    {
        if (!usev5) {
#ifdef HAVE_KRB4
            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_text(status));
                status = AKLOG_KERBEROS;
                goto done;
            }
#else
            status = AKLOG_MISC;
            goto done;
#endif
        }

        /* For Network Identity Manager append the realm to the name */
        strcat(username, "@");
        strcat(username, realm_of_user);

        ViceIDToUsername(username, realm_of_user, realm_of_cell, cell_to_use, 
#ifdef HAVE_KRB4
                          &c, 
#else
                          NULL,
#endif
                          &status, &aclient, &aserver, &atoken);
    }

    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, "");
    
    if (usev5 && !use524) {
        int len = min(v5cred->client->realm.length,MAXKTCNAMELEN - 1);
        strncpy(aclient.cell, v5cred->client->realm.data, len);
        aclient.cell[len] = '\0';
    } 
#ifdef HAVE_KRB4
    else
	strncpy(aclient.cell, c.realm, MAXKTCREALMLEN - 1);
#endif

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

    if (dflag)
        printf("Getting tokens.\n");
    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;
    }

  done2:
    if (ak_cellconfig.linkedCell && !getLinkedCell) {
        getLinkedCell = 1;
        goto linkedCell;
    }

  done:
#if 0
    /* 
     * intentionally leak the linkedCell field because it was allocated
     * using a different C RTL version.
     */
    if (ak_cellconfig.linkedCell)
        free(ak_cellconfig.linkedCell);
#endif
    return(status);
}
Ejemplo n.º 7
0
afs_int32
krb_write_ticket_file(char *realm)
{
    int fd;
    int count;
    afs_int32 code;
    int lifetime, kvno;
    char *tf_name;
    struct ktc_principal client, server;
    struct ktc_token token;

    if ((strlen(realm) >= sizeof(client.cell)))
	return KABADNAME;
    strcpy(server.name, KA_TGS_NAME);
    strcpy(server.instance, realm);
    lcstring(server.cell, realm, sizeof(server.cell));

    code = ktc_GetToken(&server, &token, sizeof(struct ktc_token), &client);
    if (code)
	return code;

    /* Use the KRBTKFILE environment variable if it exists, otherwise fall
     * back upon /tmp/tkt(uid}.
     */
    if ((tf_name = (char *)getenv("KRBTKFILE")))
	fd = open(tf_name, O_WRONLY | O_CREAT | O_TRUNC, 0700);
    else {
	afs_asprintf(&tf_name, "%s/tkt%d", gettmpdir(), getuid());
	if (tf_name == NULL)
	    return ENOMEM;
	fd = open(tf_name, O_WRONLY | O_CREAT | O_TRUNC, 0700);
	free(tf_name);
    }

    if (fd <= 0)
	return errno;

    /* write client name as file header */

    count = strlen(client.name) + 1;
    if (write(fd, client.name, count) != count)
	goto bad;

    count = strlen(client.instance) + 1;
    if (write(fd, client.instance, count) != count)
	goto bad;

    /* Write the ticket and associated data */
    /* Service */
    count = strlen(server.name) + 1;
    if (write(fd, server.name, count) != count)
	goto bad;
    /* Instance */
    count = strlen(server.instance) + 1;
    if (write(fd, server.instance, count) != count)
	goto bad;
    /* Realm */
    ucstring(server.cell, server.cell, sizeof(server.cell));
    count = strlen(server.cell) + 1;
    if (write(fd, server.cell, count) != count)
	goto bad;
    /* Session key */
    if (write(fd, (char *)&token.sessionKey, 8) != 8)
	goto bad;
    /* Lifetime */
    lifetime = time_to_life(token.startTime, token.endTime);
    if (write(fd, (char *)&lifetime, sizeof(int)) != sizeof(int))
	goto bad;
    /* Key vno */
    kvno = token.kvno;
    if (write(fd, (char *)&kvno, sizeof(int)) != sizeof(int))
	goto bad;
    /* Tkt length */
    if (write(fd, (char *)&(token.ticketLen), sizeof(int)) != sizeof(int))
	goto bad;
    /* Ticket */
    count = token.ticketLen;
    if (write(fd, (char *)(token.ticket), count) != count)
	goto bad;
    /* Issue date */
    if (write(fd, (char *)&(token.startTime), sizeof(afs_int32))
	!= sizeof(afs_int32))
	goto bad;
    close(fd);
    return 0;

  bad:
    close(fd);
    return -1;
}
Ejemplo n.º 8
0
afs_uint32
xfon_voldump(XFILE * X, int flag, char *name)
{
    struct hostent *he;
    struct rx_securityClass *class;
    struct rx_connection *conn;
    struct ktc_principal sname;
    struct ktc_token token;
    struct afsconf_dir *confdir;
    afs_uint32 code, server_addr = 0;
    afs_int32 volid, date, partid = 0;
    int isnum, index;
    char *x, *y;

    /* Parse out the optional date and server location */
    if ((code = rx_Init(0)))
	return code;
    if (!(name = strdup(name)))
	return ENOMEM;
    if ((x = strrchr(name, ','))) {
	*x++ = 0;
	date = atoi(x);
    } else {
	date = 0;
    }
    if ((x = strrchr(name, '@'))) {
	int a, b, c, d;

	*x++ = 0;
	if (!(y = strchr(x, '/'))) {
	    free(name);
	    return VL_BADPARTITION;
	}
	*y++ = 0;
	if (sscanf(x, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && a >= 0
	    && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0
	    && d <= 255) {
	    server_addr = (a << 24) | (b << 16) | (c << 8) | d;
	    server_addr = htonl(server_addr);
	} else {
	    he = gethostbyname(x);
	    if (!he) {
		free(name);
		return VL_BADSERVER;
	    }
	    memcpy(&server_addr, he->h_addr, sizeof(server_addr));
	}
	partid = volutil_GetPartitionID(y);
	if (partid < 0) {
	    free(name);
	    return VL_BADPARTITION;
	}
    }

    /* Get tokens and set up a security object */
    confdir = afsconf_Open(AFSCONF_CLIENTNAME);
    if (!confdir) {
	free(name);
	return AFSCONF_NODB;
    }
    if ((code = afsconf_GetLocalCell(confdir, sname.cell, MAXKTCNAMELEN))) {
	free(name);
	return code;
    }
    afsconf_Close(confdir);
    strcpy(sname.name, "afs");
    sname.instance[0] = 0;
    code = ktc_GetToken(&sname, &token, sizeof(token), 0);
    if (code) {
	class = rxnull_NewClientSecurityObject();
	index = 0;
    } else {
Ejemplo n.º 9
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(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);
}
Ejemplo n.º 10
0
int
main(void)
{
    struct ktc_principal oldServer[MAXCELLS], newServer[MAXCELLS];
    struct ktc_principal oldClient[MAXCELLS], newClient[MAXCELLS];
    struct ktc_token oldToken[MAXCELLS], newToken[MAXCELLS];
    int cellCount, cellIndex;
    int i, code;

#ifdef AFS_NT40_ENV
    /* Initialize winsock; required by NT pioctl() */
    if (afs_winsockInit()) {
        printf("\nUnable to initialize winsock (required by NT pioctl()).\n");
        exit(1);
    }
#endif

    /* Get original tokens */

    printf("\nFetching original tokens.\n");

    cellIndex = 0;

    for (i = 0; i < MAXCELLS; i++) {
        /* fetch server principal */
        code = ktc_ListTokens(cellIndex, &cellIndex, &oldServer[i]);

        if (code) {
            if (code == KTC_NOENT) {
                /* no more tokens */
                break;
            } else {
                /* some error occured */
                perror("ktc_ListTokens failed fetching original tokens");
                exit(1);
            }
        }

        /* fetch token and client identity w.r.t. server */
        code =
            ktc_GetToken(&oldServer[i], &oldToken[i],
                         sizeof(struct ktc_token), &oldClient[i]);

        if (code) {
            /* some unexpected error occured */
            perror("ktc_GetToken failed fetching original tokens");
            exit(1);
        }
    }

    cellCount = i;

    if (cellCount == 0) {
        printf("Obtain one or more tokens prior to executing test.\n");
        exit(0);
    } else if (cellCount == MAXCELLS) {
        printf("Only first %d tokens utilized by test; rest will be lost.\n",
               MAXCELLS);
    }

    for (i = 0; i < cellCount; i++) {
        printf("Token[%d]: server = %s@%s, client = %s@%s\n", i,
               oldServer[i].name, oldServer[i].cell, oldClient[i].name,
               oldClient[i].cell);
    }


    /* Forget original tokens */

    printf("\nClearing original tokens and verifying disposal.\n");

    code = ktc_ForgetAllTokens();

    if (code) {
        perror("ktc_ForgetAllTokens failed on original tokens");
        exit(1);
    }

    for (i = 0; i < cellCount; i++) {
        struct ktc_principal dummyPrincipal;
        struct ktc_token dummyToken;

        code =
            ktc_GetToken(&oldServer[i], &dummyToken, sizeof(struct ktc_token),
                         &dummyPrincipal);

        if (code != KTC_NOENT) {
            printf("ktc_ForgetAllTokens did not eliminate all tokens.\n");
            exit(1);
        }

        cellIndex = 0;

        code = ktc_ListTokens(cellIndex, &cellIndex, &dummyPrincipal);

        if (code != KTC_NOENT) {
            printf("ktc_ForgetAllTokens did not eliminate all tokens.\n");
            exit(1);
        }
    }


    /* Reinstall tokens */

    printf("\nReinstalling original tokens.\n");

    for (i = 0; i < cellCount; i++) {
        code = ktc_SetToken(&oldServer[i], &oldToken[i], &oldClient[i], 0);

        if (code) {
            perror("ktc_SetToken failed reinstalling tokens");
            exit(1);
        }
    }


    /* Get reinstalled tokens */

    printf("\nFetching reinstalled tokens.\n");

    cellIndex = 0;

    for (i = 0; i < MAXCELLS; i++) {
        /* fetch server principal */
        code = ktc_ListTokens(cellIndex, &cellIndex, &newServer[i]);

        if (code) {
            if (code == KTC_NOENT) {
                /* no more tokens */
                break;
            } else {
                /* some error occured */
                perror("ktc_ListTokens failed fetching reinstalled tokens");
                exit(1);
            }
        }

        /* fetch token and client identity w.r.t. server */
        code =
            ktc_GetToken(&newServer[i], &newToken[i],
                         sizeof(struct ktc_token), &newClient[i]);

        if (code) {
            /* some unexpected error occured */
            perror("ktc_GetToken failed fetching reinstalled tokens");
            exit(1);
        }
    }


    /* Verify content of reinstalled tokens */

    printf("\nVerifying reinstalled tokens against original tokens.\n");

    if (i != cellCount) {
        printf("Reinstalled token count does not match original count.\n");
        exit(1);
    }

    for (i = 0; i < cellCount; i++) {
        int k, found;
        found = 0;

        for (k = 0; k < cellCount; k++) {
            if (SamePrincipal(&oldServer[i], &newServer[k])
                    && SamePrincipal(&oldClient[i], &newClient[k])
                    && SameToken(&oldToken[i], &newToken[k])) {
                /* found a matching token */
                found = 1;
                break;
            }
        }

        if (!found) {
            printf("Reinstalled token does not match any original token.\n");
            exit(1);
        }
    }

    /* Test passes */

    printf("\nTest completed without error.\n");
    return 0;
}
Ejemplo n.º 11
0
/* Copy the AFS service token into the kernel for a particular host and user */
static int
NFSCopyToken(afs_int32 ahost, afs_int32 auid)
{
    struct ktc_principal client, server;
    struct ktc_token theTicket;
    afs_int32 code;
    afs_int32 pheader[6];
    char space[1200];
    struct ClearToken ct;
    afs_int32 index, newIndex;
    afs_int32 temp;		/* for bcopy */
    char *tp;
    struct ViceIoctl blob;

    for (index = 0;; index = newIndex) {
	code = ktc_ListTokens(index, &newIndex, &server);
	if (code) {
	    if (code == KTC_NOENT) {
		/* all done */
		code = 0;
	    }
	    break;		/* done, but failed */
	}
	if (strcmp(server.name, "afs") != 0)
	    continue;		/* wrong ticket service */
	code = ktc_GetToken(&server, &theTicket, sizeof(theTicket), &client);
	if (code)
	    return code;

	/* otherwise we've got the token, now prepare to build the pioctl args */
	pheader[0] = ahost;
	pheader[1] = auid;
	pheader[2] = 0;		/* group low */
	pheader[3] = 0;		/* group high */
	pheader[4] = 3;		/* set token pioctl index */
	pheader[5] = 1;		/* NFS protocol exporter # */

	/* copy in the header */
	memcpy(space, pheader, sizeof(pheader));
	tp = space + sizeof(pheader);
	/* copy in the size of the encrypted part */
	memcpy(tp, &theTicket.ticketLen, sizeof(afs_int32));
	tp += sizeof(afs_int32);
	/* copy in the ticket itself */
	memcpy(tp, theTicket.ticket, theTicket.ticketLen);
	tp += theTicket.ticketLen;
	/* copy in "clear token"'s size */
	temp = sizeof(struct ClearToken);
	memcpy(tp, &temp, sizeof(afs_int32));
	tp += sizeof(afs_int32);
	/* create the clear token and copy *it* in */
	ct.AuthHandle = theTicket.kvno;	/* where we hide the key version # */
	memcpy(ct.HandShakeKey, &theTicket.sessionKey,
	       sizeof(ct.HandShakeKey));

	ct.ViceId = auid;
	ct.BeginTimestamp = theTicket.startTime;
	ct.EndTimestamp = theTicket.endTime;
	memcpy(tp, &ct, sizeof(ct));
	tp += sizeof(ct);
	/* copy in obsolete primary flag */
	temp = 0;
	memcpy(tp, &temp, sizeof(afs_int32));
	tp += sizeof(afs_int32);
	/* copy in cell name, null terminated */
	strcpy(tp, server.cell);
	tp += strlen(server.cell) + 1;

	/* finally setup the pioctl call's parameters */
	blob.in_size = tp - space;
	blob.in = space;
	blob.out_size = 0;
	blob.out = NULL;
	code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
	if (code) {
	    code = errno;
	    break;
	}
    }
    return code;
}
Ejemplo n.º 12
0
int
not_an_API_LeashAFSGetToken(
    TICKETINFO * ticketinfo,
    TicketList** ticketList,
    char * kerberosPrincipal
    )
{
#ifdef NO_AFS
    return(0);
#else
    struct ktc_principal    aserver;
    struct ktc_principal    aclient;
    struct ktc_token        atoken;
    int                     EndMonth;
    int                     EndDay;
    int                     cellNum;
    int                     BreakAtEnd;
    char                    UserName[64];
    char                    CellName[64];
    char                    ServiceName[64];
    char                    InstanceName[64];
    char                    EndTime[16];
    char                    Buffer[256];
    char                    Months[12][4] = {"Jan\0", "Feb\0", "Mar\0", "Apr\0", "May\0", "Jun\0", "Jul\0", "Aug\0", "Sep\0", "Oct\0", "Nov\0", "Dec\0"};
    char                    TokenStatus[16];
    time_t                  CurrentTime;
    struct tm               *newtime;
    DWORD                   CurrentState;
    DWORD                   rc;
    char                    HostName[64];


    TicketList* list = NULL;
    if ( ticketinfo ) {
        ticketinfo->btickets = NO_TICKETS;
        ticketinfo->principal[0] = '\0';
    }
    if ( !kerberosPrincipal )
        kerberosPrincipal = "";

    if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine)
        return(0);

    CurrentState = 0;
    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
        return(0);
    if (CurrentState != SERVICE_RUNNING)
        return(0);

    BreakAtEnd = 0;
    cellNum = 0;
    while (1)
    {
        if (rc = ktc_ListTokens(cellNum, &cellNum, &aserver))
        {
            if (rc != KTC_NOENT)
                return(0);

            if (BreakAtEnd == 1)
                break;
        }
        BreakAtEnd = 1;
        memset(&atoken, '\0', sizeof(atoken));
        if (rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient))
        {
            if (rc == KTC_ERROR)
                return(0);

            continue;
        }

        if (!list)
        {
            list = (TicketList*) calloc(1, sizeof(TicketList));
            (*ticketList) = list;
        }
        else
        {
            list->next = (struct TicketList*) calloc(1, sizeof(TicketList));
            list = (TicketList*) list->next;
        }

        CurrentTime = time(NULL);

        newtime = localtime(&atoken.endTime);

        memset(UserName, '\0', sizeof(UserName));
        strcpy(UserName, aclient.name);

        memset(CellName, '\0', sizeof(CellName));
        strcpy(CellName, aclient.cell);

        memset(InstanceName, '\0', sizeof(InstanceName));
        strcpy(InstanceName, aclient.instance);

        memset(ServiceName, '\0', sizeof(ServiceName));
        strcpy(ServiceName, aserver.name);

        memset(TokenStatus, '\0', sizeof(TokenStatus));

        EndDay = newtime->tm_mday;

        EndMonth = newtime->tm_mon + 1;;

        sprintf(EndTime, "%02d:%02d:%02d", newtime->tm_hour, newtime->tm_min, newtime->tm_sec);

        sprintf(Buffer,"                          %s %02d %s      %s%s%s@%s  %s",
                Months[EndMonth - 1], EndDay, EndTime,
                UserName,
                InstanceName[0] ? "." : "",
                InstanceName,
                CellName,
                TokenStatus);

        list->theTicket = (char*) calloc(1, sizeof(Buffer));
        if (!list->theTicket)
        {
#ifdef USE_MESSAGE_BOX
            MessageBox(NULL, "Memory Error", "Error", MB_OK);
#endif /* USE_MESSAGE_BOX */
            return ENOMEM;
        }

        strcpy(list->theTicket, Buffer);
        list->name = strdup(aclient.name);
        list->inst = aclient.instance[0] ? strdup(aclient.instance) : NULL;
        list->realm = strdup(aclient.cell);
        list->encTypes = NULL;
        list->addrCount = 0;
        list->addrList = NULL;

        if ( ticketinfo ) {
            sprintf(Buffer,"%s@%s",UserName,CellName);
            if (!ticketinfo->principal[0] || !stricmp(Buffer,kerberosPrincipal)) {
                strcpy(ticketinfo->principal, Buffer);
                ticketinfo->issue_date = 0;
                ticketinfo->lifetime = atoken.endTime;
                ticketinfo->renew_till = 0;

                _tzset();
                if ( ticketinfo->lifetime - time(0) <= 0L )
                    ticketinfo->btickets = EXPD_TICKETS;
                else
                    ticketinfo->btickets = GOOD_TICKETS;
            }
        }
    }
    return(0);
#endif
}
Ejemplo n.º 13
0
int
Leash_afs_klog(
    char *service,
    char *cell,
    char *realm,
    int LifeTime
    )
{
/////#ifdef NO_AFS
#if defined(NO_AFS) || defined(NO_KRB4)
    return(0);
#else
    long	rc;
////This is defined in krb.h:
    CREDENTIALS	creds;
    KTEXT_ST	ticket;
    struct ktc_principal	aserver;
    struct ktc_principal	aclient;
    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	Dmycell[MAXCELLCHARS+1];
    struct ktc_token	atoken;
    struct ktc_token	btoken;
    afsconf_cell	ak_cellconfig; /* General information about the cell */
    char	RealmName[128];
    char	CellName[128];
    char	ServiceName[128];
    DWORD       CurrentState;
    char        HostName[64];
    BOOL        try_krb5 = 0;
    int         retry = 0;
    int         len;
#ifndef NO_KRB5
    krb5_context  context = 0;
    krb5_ccache  _krb425_ccache = 0;
    krb5_creds increds;
    krb5_creds * k5creds = 0;
    krb5_error_code r;
    krb5_principal client_principal = 0;
    krb5_flags		flags = 0;
#endif /* NO_KRB5 */

    if (!AfsAvailable || GetAfsStatus(&AfsOnLine) && !AfsOnLine)
        return(0);

    if ( !realm ) realm = "";
    if ( !cell )  cell = "";
    if ( !service ) service = "";

    CurrentState = 0;
    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
        return(0);
    if (CurrentState != SERVICE_RUNNING)
        return(0);

    memset(RealmName, '\0', sizeof(RealmName));
    memset(CellName, '\0', sizeof(CellName));
    memset(ServiceName, '\0', sizeof(ServiceName));
    memset(realm_of_user, '\0', sizeof(realm_of_user));
    memset(realm_of_cell, '\0', sizeof(realm_of_cell));
    memset(Dmycell, '\0', sizeof(Dmycell));

    // NULL or empty cell returns information on local cell
    if (cell && cell[0])
        strcpy(Dmycell, cell);
    rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell);
    if (rc && cell && cell[0]) {
        memset(Dmycell, '\0', sizeof(Dmycell));
        rc = get_cellconfig(Dmycell, &ak_cellconfig, local_cell);
    }
    if (rc)
        return(rc);

#ifndef NO_KRB5
    if (!(r = Leash_krb5_initialize(&context, &_krb425_ccache))) {
        int i;

        memset((char *)&increds, 0, sizeof(increds));

        (*pkrb5_cc_get_principal)(context, _krb425_ccache, &client_principal);
        i = krb5_princ_realm(context, client_principal)->length;
        if (i > REALM_SZ-1)
            i = REALM_SZ-1;
        strncpy(realm_of_user,krb5_princ_realm(context, client_principal)->data,i);
        realm_of_user[i] = 0;
        try_krb5 = 1;
    }
#endif /* NO_KRB5 */

#ifndef NO_KRB4
    if ( !try_krb5 || !realm_of_user[0] ) {
        if ((rc = (*pkrb_get_tf_realm)((*ptkt_string)(), realm_of_user)) != KSUCCESS)
        {
            return(rc);
        }
    }
#endif
    strcpy(realm_of_cell, afs_realm_of_cell(&ak_cellconfig));

    if (strlen(service) == 0)
        strcpy(ServiceName, "afs");
    else
        strcpy(ServiceName, service);

    if (strlen(cell) == 0)
        strcpy(CellName, local_cell);
    else
        strcpy(CellName, cell);

    if (strlen(realm) == 0)
        strcpy(RealmName, realm_of_cell);
    else
        strcpy(RealmName, realm);

    memset(&creds, '\0', sizeof(creds));

#ifndef NO_KRB5
    if ( try_krb5 ) {
        /* First try Service/Cell@REALM */
        if (r = (*pkrb5_build_principal)(context, &increds.server,
                                      strlen(RealmName),
                                      RealmName,
                                      ServiceName,
                                      CellName,
                                      0))
        {
            try_krb5 = 0;
            goto use_krb4;
        }

        increds.client = client_principal;
        increds.times.endtime = 0;
        /* Ask for DES since that is what V4 understands */
        increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;

#ifdef KRB5_TC_NOTICKET
        flags = 0;
        r = pkrb5_cc_set_flags(context, _krb425_ccache, flags);
#endif
        if (r == 0)
            r = pkrb5_get_credentials(context, 0, _krb425_ccache, &increds, &k5creds);
        if (r == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
			r == KRB5KRB_ERR_GENERIC /* Heimdal */) {
            /* Next try Service@REALM */
            pkrb5_free_principal(context, increds.server);
            r = pkrb5_build_principal(context, &increds.server,
                                      strlen(RealmName),
                                      RealmName,
                                      ServiceName,
                                      0);
            if (r == 0)
                r = pkrb5_get_credentials(context, 0, _krb425_ccache, &increds, &k5creds);
        }

        pkrb5_free_principal(context, increds.server);
        pkrb5_free_principal(context, client_principal);
#ifdef KRB5_TC_NOTICKET
        flags = KRB5_TC_NOTICKET;
        pkrb5_cc_set_flags(context, _krb425_ccache, flags);
#endif
        (void) pkrb5_cc_close(context, _krb425_ccache);
        _krb425_ccache = 0;

        if (r || k5creds == 0) {
            pkrb5_free_context(context);
            try_krb5 = 0;
            goto use_krb4;
        }

        /* This code inserts the entire K5 ticket into the token
         * No need to perform a krb524 translation which is
         * commented out in the code below
         */
        if ( use_krb524() || k5creds->ticket.length > MAXKTCTICKETLEN )
            goto try_krb524d;

        memset(&aserver, '\0', sizeof(aserver));
        strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1);
        strncpy(aserver.cell, CellName, MAXKTCREALMLEN - 1);

        memset(&atoken, '\0', sizeof(atoken));
        atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
        atoken.startTime = k5creds->times.starttime;
        atoken.endTime = k5creds->times.endtime;
        memcpy(&atoken.sessionKey, k5creds->keyblock.contents, k5creds->keyblock.length);
        atoken.ticketLen = k5creds->ticket.length;
        memcpy(atoken.ticket, k5creds->ticket.data, atoken.ticketLen);

      retry_gettoken5:
        rc = ktc_GetToken(&aserver, &btoken, sizeof(btoken), &aclient);
        if (rc != 0 && rc != KTC_NOENT && rc != KTC_NOCELL) {
            if ( rc == KTC_NOCM && retry < 20 ) {
                Sleep(500);
                retry++;
                goto retry_gettoken5;
            }
            goto try_krb524d;
        }

        if (atoken.kvno == btoken.kvno &&
             atoken.ticketLen == btoken.ticketLen &&
             !memcmp(&atoken.sessionKey, &btoken.sessionKey, sizeof(atoken.sessionKey)) &&
             !memcmp(atoken.ticket, btoken.ticket, atoken.ticketLen))
        {
            /* Success */
            pkrb5_free_creds(context, k5creds);
            pkrb5_free_context(context);
            return(0);
        }

        // * 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.

        len = min(k5creds->client->data[0].length,MAXKTCNAMELEN - 1);
        strncpy(aclient.name, k5creds->client->data[0].data, len);
        aclient.name[len] = '\0';

        if ( k5creds->client->length > 1 ) {
            char * p;
            strcat(aclient.name, ".");
            p = aclient.name + strlen(aclient.name);
            len = min(k5creds->client->data[1].length,MAXKTCNAMELEN - strlen(aclient.name) - 1);
            strncpy(p, k5creds->client->data[1].data, len);
            p[len] = '\0';
        }
        aclient.instance[0] = '\0';

        strcpy(aclient.cell, realm_of_cell);

        len = min(k5creds->client->realm.length,strlen(realm_of_cell));
        if ( strncmp(realm_of_cell, k5creds->client->realm.data, len) ) {
            char * p;
            strcat(aclient.name, "@");
            p = aclient.name + strlen(aclient.name);
            len = min(k5creds->client->realm.length,MAXKTCNAMELEN - strlen(aclient.name) - 1);
            strncpy(p, k5creds->client->realm.data, len);
            p[len] = '\0';
        }

        rc = ktc_SetToken(&aserver, &atoken, &aclient, 0);
        if (!rc) {
            /* Success */
            pkrb5_free_creds(context, k5creds);
            pkrb5_free_context(context);
            return(0);
        }

      try_krb524d:
        /* This requires krb524d to be running with the KDC */
        r = pkrb524_convert_creds_kdc(context, k5creds, &creds);
        pkrb5_free_creds(context, k5creds);
		pkrb5_free_context(context);
        if (r) {
            try_krb5 = 0;
            goto use_krb4;
        }
        rc = KSUCCESS;
    } else
#endif /* NO_KRB5 */
    {
      use_krb4:
	rc = KFAILURE;
    }
    if (rc != KSUCCESS)
    {
            return(rc);
    }

	memset(&aserver, '\0', sizeof(aserver));
    strncpy(aserver.name, ServiceName, MAXKTCNAMELEN - 1);
    strncpy(aserver.cell, CellName, MAXKTCNAMELEN - 1);

    memset(&atoken, '\0', sizeof(atoken));
    atoken.kvno = creds.kvno;
    atoken.startTime = creds.issue_date;
    atoken.endTime = (*pkrb_life_to_time)(creds.issue_date,creds.lifetime);
    memcpy(&atoken.sessionKey, creds.session, 8);
    atoken.ticketLen = creds.ticket_st.length;
    memcpy(atoken.ticket, creds.ticket_st.dat, atoken.ticketLen);

    if (!(rc = 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))
    {
        return(0);
    }

    // * 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, creds.pname, MAXKTCNAMELEN - 1);
    aclient.name[MAXKTCNAMELEN - 1] = '\0';
    if (creds.pinst[0])
    {
        strncat(aclient.name, ".", MAXKTCNAMELEN - 1 - strlen(aclient.name));
        aclient.name[MAXKTCNAMELEN - 1] = '\0';
        strncat(aclient.name, creds.pinst, MAXKTCNAMELEN - 1 - strlen(aclient.name));
        aclient.name[MAXKTCNAMELEN - 1] = '\0';
    }
    strcpy(aclient.instance, "");

    if ( strcmp(realm_of_cell, creds.realm) )
    {
        strncat(aclient.name, "@", MAXKTCNAMELEN - 1 - strlen(aclient.name));
        aclient.name[MAXKTCNAMELEN - 1] = '\0';
        strncat(aclient.name, creds.realm, MAXKTCNAMELEN - 1 - strlen(aclient.name));
        aclient.name[MAXKTCNAMELEN - 1] = '\0';
    }
    aclient.name[MAXKTCNAMELEN-1] = '\0';

    strcpy(aclient.cell, CellName);

    // * NOTE: On WIN32, the order of SetToken params changed...
    // * to   ktc_SetToken(&aserver, &aclient, &atoken, 0)
    // * from ktc_SetToken(&aserver, &atoken, &aclient, 0) on Unix...
    // * The afscompat ktc_SetToken provides the Unix order

    if (rc = ktc_SetToken(&aserver, &atoken, &aclient, 0))
    {
        Leash_afs_error(rc, "ktc_SetToken()");
        return(rc);
    }

    return(0);
#endif
}
Ejemplo n.º 14
0
void
ObtainTokensFromUserIfNeeded(HWND hWnd)
{
    char * rootcell = NULL;
    char   cell[MAXCELLCHARS+1] = "";
    char   password[PROBE_PASSWORD_LEN+1];
    struct afsconf_cell cellconfig;
    struct ktc_principal    aserver;
    struct ktc_principal    aclient;
    struct ktc_token	atoken;
    krb5_timestamp now = 0;
    BOOL serverReachable = 0;
    int rc;
    DWORD       CurrentState, code;
    char        HostName[64];
    int         use_kfw = KFW_is_available();

    SYSTEMTIME stNow;
    FILETIME ftNow;
    LONGLONG llNow;
    FILETIME ftExpires;
    LONGLONG llExpires;
    SYSTEMTIME stExpires;

    CurrentState = 0;
    memset(HostName, '\0', sizeof(HostName));
    gethostname(HostName, sizeof(HostName));
    if (GetServiceStatus(HostName, TRANSARCAFSDAEMON, &CurrentState) != NOERROR)
        return;
    if (CurrentState != SERVICE_RUNNING) {
        SendMessage(hWnd, WM_START_SERVICE, FALSE, 0L);
        return;
    }

    rootcell = (char *)GlobalAlloc(GPTR,MAXCELLCHARS+1);
    if (!rootcell) 
        goto cleanup;

    code = KFW_AFS_get_cellconfig(cell, (void*)&cellconfig, rootcell);
    if (code) 
        goto cleanup;

    memset(&aserver, '\0', sizeof(aserver));
    strcpy(aserver.name, "afs");
    strcpy(aserver.cell, rootcell);

    GetLocalTime (&stNow);
    SystemTimeToFileTime (&stNow, &ftNow);
    llNow = (((LONGLONG)ftNow.dwHighDateTime) << 32) + (LONGLONG)(ftNow.dwLowDateTime);
    llNow /= c100ns1SECOND;

    rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient);
    if ( rc == 0 ) {
        TimeToSystemTime (&stExpires, atoken.endTime);
        SystemTimeToFileTime (&stExpires, &ftExpires);
        llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);
        llExpires /= c100ns1SECOND;

        if (llNow < llExpires)
            goto cleanup;

        if ( IsDebuggerPresent() ) {
            char message[256];
            sprintf(message,"ObtainTokensFromUserIfNeeded: %d  now = %ul  endTime = %ul\n",
                     rc, llNow, llExpires);
            OutputDebugString(message);
        }
    }

#ifdef USE_FSPROBE
    serverReachable = cellPing(NULL);
#else
    if (use_kfw) {
        // If we can't use the FSProbe interface we can attempt to forge
        // a kinit and if we can back an invalid user error we know the
        // kdc is at least reachable
        serverReachable = KFW_probe_kdc(&cellconfig);
    } else {
        int i;

        for ( i=0 ; i<PROBE_PASSWORD_LEN ; i++ )
            password[i] = 'x';

        code = ObtainNewCredentials(rootcell, PROBE_USERNAME, password, TRUE);
        switch ( code ) {
        case INTK_BADPW:
        case KERB_ERR_PRINCIPAL_UNKNOWN:
        case KERB_ERR_SERVICE_EXP:
        case RD_AP_TIME:
            serverReachable = TRUE;
            break;
        default:
            serverReachable = FALSE;
        }
    }
#endif
    if ( !serverReachable ) {
        if ( IsDebuggerPresent() )
            OutputDebugString("Server Unreachable\n");
        goto cleanup;
    }

    if ( IsDebuggerPresent() )
        OutputDebugString("Server Reachable\n");

    if ( use_kfw ) {
#ifdef USE_MS2MIT
        KFW_import_windows_lsa();
#endif /* USE_MS2MIT */
        KFW_AFS_renew_expiring_tokens();
        KFW_AFS_renew_token_for_cell(rootcell);

        rc = ktc_GetToken(&aserver, &atoken, sizeof(atoken), &aclient);
        if ( rc == 0 ) {
            TimeToSystemTime (&stExpires, atoken.endTime);
            SystemTimeToFileTime (&stExpires, &ftExpires);
            llExpires = (((LONGLONG)ftExpires.dwHighDateTime) << 32) + (LONGLONG)(ftExpires.dwLowDateTime);
            llExpires /= c100ns1SECOND;
        
            if (llNow < llExpires)
                goto cleanup;
        }
    }

    SendMessage(hWnd, WM_OBTAIN_TOKENS, FALSE, (long)rootcell);
    rootcell = NULL;    // rootcell freed by message receiver

  cleanup:
    if (rootcell)
        GlobalFree(rootcell);

    return;
}
Ejemplo n.º 15
0
int
main(int argc, char **argv)
{				/*Main program */
    int cellNum;		/*Cell entry number */
    int rc;			/*Return value from U_CellGetLocalTokens */
    time_t current_time;	/*Current time of day */
    time_t tokenExpireTime;	/*When token expires */
    char *expireString;		/*Char string of expiration time */
    char UserName[MAXKTCNAMELEN * 2 + 2]; /*Printable user name */
    struct ktc_principal serviceName, clientName;	/* service name for ticket */
    struct ktc_token token;	/* the token we're printing */

#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

    /* has no args ... support for help flag */

    if (argc > 1) {
	/* syntax from AFS Com Ref Man p9-39 */

	printf("Usage: tokens [-help]\n");
	fflush(stdout);
	exit(0);
    }

    printf("\nTokens held by the Cache Manager:\n\n");
    cellNum = 0;
    current_time = time(0);
    while (1) {
	rc = ktc_ListTokens(cellNum, &cellNum, &serviceName);
	if (rc) {
	    /* only error is now end of list */
	    printf("   --End of list--\n");
	    break;
	} else {
	    /* get the ticket info itself */
	    rc = ktc_GetToken(&serviceName, &token, sizeof(token),
			      &clientName);
	    if (rc) {
		printf
		    ("tokens: failed to get token info for service %s.%s.%s (code %d)\n",
		     serviceName.name, serviceName.instance, serviceName.cell,
		     rc);
		continue;
	    }
	    tokenExpireTime = token.endTime;
	    strcpy(UserName, clientName.name);
	    if (clientName.instance[0] != 0) {
		strcat(UserName, ".");
		strcat(UserName, clientName.instance);
	    }
	    if (UserName[0] == 0)
		printf("Tokens");
	    else if (strncmp(UserName, "AFS ID", 6) == 0) {
		printf("User's (%s) tokens", UserName);
	    } else if (strncmp(UserName, "Unix UID", 8) == 0) {
		printf("Tokens");
	    } else
		printf("User %s's tokens", UserName);
	    printf(" for %s%s%s@%s ", serviceName.name,
		   serviceName.instance[0] ? "." : "", serviceName.instance,
		   serviceName.cell);
	    if (tokenExpireTime <= current_time)
		printf("[>> Expired <<]\n");
	    else {
		expireString = ctime(&tokenExpireTime);
		expireString += 4;	/*Move past the day of week */
		expireString[12] = '\0';
		printf("[Expires %s]\n", expireString);
	    }
	}
    }
    exit(0);
}				/*Main program */
Ejemplo n.º 16
0
afs_int32
InitThisModule(void)
{				/*InitThisModule */
#ifdef USS_KAUTH_DB
    static char rn[] = "uss_kauth:InitThisModule";
#endif
    afs_int32 code;
    char prompt[2 * MAXKTCNAMELEN + 20];
    char *reasonString, longPassBuff[1024], shortPassBuff[9];
    struct ktc_encryptionKey key;
    struct ktc_token token;
    struct ktc_principal Name, tok;

    /*
     * Only call this routine once.
     */
    if (initDone)
	return (0);


    /*
     * Pull out the caller's administrator token if they have one.
     */
    code =
	ka_GetAdminToken(0, 0, uss_Cell, 0, 10 * 60 * 60, &token,
			 0 /*new */ );
    if (code) {
	if (Pipe) {
	    strncpy(longPassBuff, getpipepass(), sizeof(longPassBuff));
	} else {
	    /*
	     * Nope, no admin tokens available.  Get the key based on the
	     * full password and try again.
	     */
	    sprintf(prompt, "Password for '%s", uss_AccountCreator);
	    if (CreatorInstance[0])
		sprintf(prompt + strlen(prompt), ".%s", CreatorInstance);
	    strcat(prompt, "': ");
	    code = ka_UserReadPassword(prompt,	/*Prompt to use */
				       longPassBuff,	/*Long pwd buffer */
				       sizeof(longPassBuff),	/*Size of above */
				       &reasonString);
	    if (code) {
		afs_com_err(uss_whoami, code, "while getting password ");
#ifdef USS_KAUTH_DB
		printf("%s: Error code from ka_UserReadPassword(): %d\n", rn,
		       code);
#endif /* USS_KAUTH_DB */
		return (code);
	    }
	}
	ka_StringToKey(longPassBuff, uss_Cell, &key);
	code =
	    ka_GetAdminToken(uss_AccountCreator, CreatorInstance, uss_Cell,
			     &key, 24 * 60 * 60, &token, 0 /*new */ );
	if (code) {
	    if ((code == KABADREQUEST) && (strlen(longPassBuff) > 8)) {
		/*
		 * The key we provided just doesn't work, yet we
		 * suspect that since the password is greater than 8
		 * chars, it might be the case that we really need
		 * to truncate the password to generate the appropriate
		 * key.
		 */
		afs_com_err(uss_whoami, code,
			"while getting administrator token (trying shortened password next...)");
#ifdef USS_KAUTH_DB
		printf("%s: Error code from ka_GetAdminToken: %d\n", rn,
		       code);
#endif /* USS_KAUTH_DB */
		strncpy(shortPassBuff, longPassBuff, 8);
		shortPassBuff[8] = 0;
		ka_StringToKey(shortPassBuff, uss_Cell, &key);
		code =
		    ka_GetAdminToken(uss_AccountCreator, CreatorInstance,
				     uss_Cell, &key, 24 * 60 * 60, &token,
				     0 /*new */ );
		if (code) {
		    afs_com_err(uss_whoami, code,
			    "while getting administrator token (possibly wrong password, or not an administrative account)");
#ifdef USS_KAUTH_DB
		    printf("%s: Error code from ka_GetAdminToken: %d\n", rn,
			   code);
#endif /* USS_KAUTH_DB */
		    return (code);
		} else {
		    /*
		     * The silly administrator has a long password!  Tell
		     * him or her off in a polite way.
		     */
		    printf
			("%s: Shortened password accepted by the Authentication Server\n",
			 uss_whoami);
		}
	    } /*Try a shorter password */
	    else {
		/*
		 * We failed to get an admin token, but the password is
		 * of a reasonable length, so we're just hosed.
		 */
		afs_com_err(uss_whoami, code,
			"while getting administrator token (possibly wrong password, or not an administrative account)");
#ifdef USS_KAUTH_DB
		printf("%s: Error code from ka_GetAdminToken: %d\n", rn,
		       code);
#endif /* USS_KAUTH_DB */
		return (code);
	    }			/*Even the shorter password didn't work */
	}			/*Key from given password didn't work */
    }

    /*First attempt to get admin token failed */
    /*
     * At this point, we have acquired an administrator token.  Let's
     * proceed to set up a connection to the AuthServer.
     */
#ifdef USS_KAUTH_DB_INSTANCE
    fprintf(stderr,
	    "%s: CreatorInstance after ka_GetAdminToken(): '%s', %d bytes\n",
	    rn, CreatorInstance, strlen(CreatorInstance));
#endif /* USS_KAUTH_DB_INSTANCE */

    /*
     * Set up the connection to the AuthServer read/write site.
     */
    code =
	ka_AuthServerConn(uss_Cell, KA_MAINTENANCE_SERVICE, &token,
			  &uconn_kauthP);
    if (code) {
	afs_com_err(uss_whoami, code,
		"while establishing Authentication Server connection");
#ifdef USS_KAUTH_DB
	printf("%s: Error code from ka_AuthServerConn: %d\n", rn, code);
#endif /* USS_KAUTH_DB */
	return (code);
    }

    if (uss_Administrator[0]) {
	/*
	 * We must check to see if we have local tokens for admin since he'll may do
	 * various pioctl or calls to protection server that require tokens. Remember
	 * to remove this tokens at the end of the program...
	 */
	strcpy(Name.name, "afs");
	Name.instance[0] = '\0';
	strncpy(Name.cell, uss_Cell, sizeof(Name.cell));
	if ((code =
	    ktc_GetToken(&Name, &token, sizeof(struct ktc_token), &tok))) {
	    code =
		ka_UserAuthenticateLife(0, uss_AccountCreator,
					CreatorInstance, uss_Cell,
					longPassBuff, 10 * 60 * 60,
					&reasonString);
	    if (!code)
		doUnlog = 1;
	}
    }

    /*
     * Declare our success.
     */
    initDone = 1;
    return (0);

}				/*InitThisModule */