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