int sudo_afs_verify(struct passwd *pw, char *pass, sudo_auth *auth) { struct ktc_encryptionKey afs_key; struct ktc_token afs_token; debug_decl(sudo_afs_verify, SUDO_DEBUG_AUTH) /* Try to just check the password */ ka_StringToKey(pass, NULL, &afs_key); if (ka_GetAdminToken(pw->pw_name, /* name */ NULL, /* instance */ NULL, /* realm */ &afs_key, /* key (contains password) */ 0, /* lifetime */ &afs_token, /* token */ 0) == 0) /* new */ debug_return_int(AUTH_SUCCESS); /* Fall back on old method XXX - needed? */ setpag(); if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION+KA_USERAUTH_DOSETPAG, pw->pw_name, /* name */ NULL, /* instance */ NULL, /* realm */ pass, /* password */ 0, /* lifetime */ NULL, /* expiration ptr (unused) */ 0, /* spare */ NULL) == 0) /* reason */ debug_return_int(AUTH_SUCCESS); debug_return_int(AUTH_FAILURE); }
struct passwd *checkpw (struct passwd *pw,char *pass,int argc,char *argv[]) { char *reason; /* faster validation for POP servers */ if (!strcmp ((char *) mail_parameters (NIL,GET_SERVICENAME,NIL),"pop")) { struct ktc_encryptionKey key; struct ktc_token token; /* just check the password */ ka_StringToKey (pass,NIL,&key); if (ka_GetAdminToken (pw->pw_name,"","",&key,600,&token,1)) return NIL; } /* check password and get AFS token */ else if (ka_UserAuthenticateGeneral (KA_USERAUTH_VERSION + KA_USERAUTH_DOSETPAG,pw->pw_name,NIL,NIL, pass,0,0,0,&reason)) return NIL; /* arm hook to delete credentials */ mail_parameters (NIL,SET_LOGOUTHOOK,(void *) checkpw_cleanup); return pw; }
afs_int32 ka_ReadPassword(char *prompt, int verify, char *cell, struct ktc_encryptionKey *key) { char password[BUFSIZ]; afs_int32 code; LOCK_GLOBAL_MUTEX; memset(key, 0, sizeof(struct ktc_encryptionKey)); code = UI_UTIL_read_pw_string(password, sizeof(password), prompt, verify); if (code) { UNLOCK_GLOBAL_MUTEX; return KAREADPW; } if (strlen(password) == 0) { UNLOCK_GLOBAL_MUTEX; return KANULLPASSWORD; } ka_StringToKey(password, cell, key); UNLOCK_GLOBAL_MUTEX; return 0; }
int main(int argc, char **argv) { struct afsconf_dir *tdir; afs_int32 code; if (argc == 1) { printf("bos_util: usage is 'bos_util <opcode> options, e.g.\n"); printf(" bos_util add <kvno>\n"); printf(" bos_util adddes <kvno>\n"); #ifdef KERBEROS printf(" bos_util srvtab2keyfile <kvno> <keyfile> <princ>\n"); #endif printf(" bos_util delete <kvno>\n"); printf(" bos_util list\n"); exit(1); } tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIR); if (!tdir) { printf("bos_util: can't initialize conf dir '%s'\n", AFSDIR_SERVER_ETC_DIR); exit(1); } if (strcmp(argv[1], "add") == 0) { struct ktc_encryptionKey tkey; int kvno; char buf[BUFSIZ], ver[BUFSIZ]; char *tcell = NULL; if (argc != 3) { printf("bos_util add: usage is 'bos_util add <kvno>\n"); exit(1); } kvno = atoi(argv[2]); memset(&tkey, 0, sizeof(struct ktc_encryptionKey)); /* prompt for key */ code = des_read_pw_string(buf, sizeof(buf), "input key: ", 0); if (code || strlen(buf) == 0) { printf("Bad key: \n"); exit(1); } code = des_read_pw_string(ver, sizeof(ver), "Retype input key: ", 0); if (code || strlen(ver) == 0) { printf("Bad key: \n"); exit(1); } if (strcmp(ver, buf) != 0) { printf("\nInput key mismatch\n"); exit(1); } ka_StringToKey(buf, tcell, &tkey); code = afsconf_AddKey(tdir, kvno, ktc_to_charptr(&tkey), 0); if (code) { printf("bos_util: failed to set key, code %d.\n", code); exit(1); } } else if (strcmp(argv[1], "adddes") == 0) { struct ktc_encryptionKey tkey; int kvno; afs_int32 code; char buf[BUFSIZ], ver[BUFSIZ]; if (argc != 3) { printf("bos_util adddes: usage is 'bos_util adddes <kvno>\n"); exit(1); } kvno = atoi(argv[2]); memset(&tkey, 0, sizeof(struct ktc_encryptionKey)); /* prompt for key */ code = des_read_pw_string(buf, sizeof(buf), "input key: ", 0); if (code || strlen(buf) == 0) { printf("Bad key: \n"); exit(1); } code = des_read_pw_string(ver, sizeof(ver), "Retype input key: ", 0); if (code || strlen(ver) == 0) { printf("Bad key: \n"); exit(1); } if (strcmp(ver, buf) != 0) { printf("\nInput key mismatch\n"); exit(1); } des_string_to_key(buf, ktc_to_cblockptr(&tkey)); code = afsconf_AddKey(tdir, kvno, ktc_to_charptr(&tkey), 0); if (code) { printf("bos_util: failed to set key, code %d.\n", code); exit(1); } } #ifdef KERBEROS else if (strcmp(argv[1], "srvtab2keyfile") == 0) { char tkey[8], name[255], inst[255], realm[255]; int kvno; if (argc != 5) { printf ("bos_util add: usage is 'bos_util srvtab2keyfile <kvno> <keyfile> <princ>\n"); exit(1); } kvno = atoi(argv[2]); bzero(tkey, sizeof(tkey)); code = kname_parse(name, inst, realm, argv[4]); if (code != 0) { printf("Invalid kerberos name\n"); exit(1); } code = read_service_key(name, inst, realm, kvno, argv[3], tkey); if (code != 0) { printf("Can't find key in %s\n", argv[3]); exit(1); } code = afsconf_AddKey(tdir, kvno, tkey, 0); if (code) { printf("bos_util: failed to set key, code %d.\n", code); exit(1); } } #endif else if (strcmp(argv[1], "delete") == 0) { long kvno; if (argc != 3) { printf("bos_util delete: usage is 'bos_util delete <kvno>\n"); exit(1); } kvno = atoi(argv[2]); code = afsconf_DeleteKey(tdir, kvno); if (code) { printf("bos_util: failed to delete key %ld, (code %d)\n", kvno, code); exit(1); } } else if (strcmp(argv[1], "list") == 0) { struct afsconf_keys tkeys; int i; unsigned char tbuffer[9]; code = afsconf_GetKeys(tdir, &tkeys); if (code) { printf("bos_util: failed to get keys, code %d\n", code); exit(1); } for (i = 0; i < tkeys.nkeys; i++) { if (tkeys.key[i].kvno != -1) { int count; unsigned char x[8]; memcpy(tbuffer, tkeys.key[i].key, 8); tbuffer[8] = 0; printf("kvno %4d: key is '%s' '", tkeys.key[i].kvno, tbuffer); strcpy((char *)x, (char *)tbuffer); for (count = 0; count < 8; count++) printf("\\%03o", x[count]); printf("'\n"); } } printf("All done.\n"); } else { printf ("bos_util: unknown operation '%s', type 'bos_util' for assistance\n", argv[1]); exit(1); } exit(0); }
afs_int32 ka_UserAuthenticateGeneral(afs_int32 flags, char *name, char *instance, char *realm, char *password, Date lifetime, afs_int32 * password_expires, /* days 'til, or don't change if not set */ afs_int32 spare2, char **reasonP) { int remainingTime = 0; struct ktc_encryptionKey key; afs_int32 code, dosetpag = 0; if (reasonP) *reasonP = ""; if ((flags & KA_USERAUTH_VERSION_MASK) != KA_USERAUTH_VERSION) return KAOLDINTERFACE; if ((strcmp(name, "root") == 0) && (instance == 0)) { if (reasonP) *reasonP = "root is only authenticated locally"; return KANOENT; } code = ka_Init(0); if (code) return code; ka_StringToKey(password, realm, &key); /* * alarm is set by kpasswd only so ignore for * NT */ #ifndef AFS_NT40_ENV { /* Rx uses timers, save to be safe */ if (rx_socket) { /* don't reset alarms, rx already running */ remainingTime = 0; } else remainingTime = alarm(0); } #endif #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_USR_LINUX20_ENV) && (!defined(AFS_XBSD_ENV) || defined(AFS_FBSD_ENV)) /* handle smoothly the case where no AFS system calls exists (yet) */ (void)signal(SIGSYS, SIG_IGN); #endif #ifdef AFS_DECOSF_ENV (void)signal(SIGTRAP, SIG_IGN); #endif /* AFS_DECOSF_ENV */ if (instance == 0) instance = ""; if (flags & KA_USERAUTH_ONLY_VERIFY) { code = ka_VerifyUserToken(name, instance, realm, &key); if (code == KABADREQUEST) { DES_string_to_key(password, ktc_to_cblockptr(&key)); code = ka_VerifyUserToken(name, instance, realm, &key); } } else { #ifdef AFS_DUX40_ENV if (flags & KA_USERAUTH_DOSETPAG) afs_setpag(); #else #if !defined(UKERNEL) && !defined(AFS_NT40_ENV) if (flags & KA_USERAUTH_DOSETPAG) setpag(); #endif #endif if (flags & KA_USERAUTH_DOSETPAG2) dosetpag = 1; #ifdef AFS_KERBEROS_ENV if ((flags & KA_USERAUTH_DOSETPAG) || dosetpag) ktc_newpag(); #endif if (lifetime == 0) lifetime = MAXKTCTICKETLIFETIME; code = GetTickets(name, instance, realm, &key, lifetime, password_expires, dosetpag); if (code == KABADREQUEST) { DES_string_to_key(password, ktc_to_cblockptr(&key)); code = GetTickets(name, instance, realm, &key, lifetime, password_expires, dosetpag); } } #ifndef AFS_NT40_ENV if (remainingTime) { pr_End(); rx_Finalize(); alarm(remainingTime); /* restore timer, if any */ } #endif if (code && reasonP) switch (code) { case KABADREQUEST: *reasonP = "password was incorrect"; break; case KAUBIKCALL: *reasonP = "Authentication Server was unavailable"; break; default: *reasonP = (char *)afs_error_message(code); } return code; }
static int Main(struct cmd_syndesc *as, void *arock) { int code; char name[MAXKTCNAMELEN]; char instance[MAXKTCNAMELEN]; char newCell[MAXKTCREALMLEN]; char *cell; long serverList[MAXSERVERS]; extern struct passwd *getpwuid(); struct passwd *pw; struct ktc_encryptionKey key; char passwd[BUFSIZ]; int cellSpecified; int i; int verbose = (as->parms[1].items != 0); int hostUsage = (as->parms[2].items != 0); int waitReap = (as->parms[4].items != 0); int doAuth = (as->parms[5].items != 0); int number; /* number of iterations */ int callsPerSecond; /* to allow conn GC to run */ unsigned long lo, hi; /* mem usage */ unsigned long highWater; /* mem usage after reap period */ unsigned long lastWater; /* mem usage after last msg */ int serversUse[MAXSERVERS]; /* usage of each server */ long serversHost[MAXSERVERS]; /* host addr */ unsigned long startTime; unsigned long now; lo = 0; whoami = as->a0name; newCell[0] = 0; if (as->parms[0].items) number = atoi(as->parms[0].items->data); else number = 100; if (as->parms[3].items) callsPerSecond = atoi(as->parms[3].items->data); else callsPerSecond = 1; if (doAuth && hostUsage) { fprintf(stderr, "Can't report host usage when calling UserAuthenticate\n"); return -1; } if (as->parms[12].items) { /* if username specified */ code = ka_ParseLoginName(as->parms[12].items->data, name, instance, newCell); if (code) { afs_com_err(whoami, code, "parsing user's name '%s'", as->parms[12].items->data); return code; } if (strlen(newCell) > 0) cellSpecified = 1; } else { /* No explicit name provided: use Unix uid. */ pw = getpwuid(getuid()); if (pw == 0) { printf("Can't figure out your name from your user id.\n"); return KABADCMD; } strncpy(name, pw->pw_name, sizeof(name)); strcpy(instance, ""); strcpy(newCell, ""); } if (strcmp(as->parms[14].name, "-cell") == 0) { if (as->parms[14].items) { /* if cell specified */ if (cellSpecified) printf("Duplicate cell specification not allowed\n"); else strncpy(newCell, as->parms[14].items->data, sizeof(newCell)); } } code = ka_ExpandCell(newCell, newCell, 0 /*local */ ); if (code) { afs_com_err(whoami, code, "Can't expand cell name"); return code; } cell = newCell; if (as->parms[13].items) { /* if password specified */ strncpy(passwd, as->parms[13].items->data, sizeof(passwd)); memset(as->parms[13].items->data, 0, strlen(as->parms[13].items->data)); } else { char msg[sizeof(name) + 15]; if (as->parms[12].items) strcpy(msg, "Admin Password: "******"Password for %s: ", name); code = read_pw_string(passwd, sizeof(passwd), msg, 0); if (code) code = KAREADPW; else if (strlen(passwd) == 0) code = KANULLPASSWORD; if (code) { afs_com_err(whoami, code, "reading password"); return code; } } if (as->parms[15].items) { struct cmd_item *ip; char *ap[MAXSERVERS + 2]; for (ip = as->parms[15].items, i = 2; ip; ip = ip->next, i++) ap[i] = ip->data; ap[0] = ""; ap[1] = "-servers"; code = ubik_ParseClientList(i, ap, serverList); if (code) { afs_com_err(whoami, code, "could not parse server list"); return code; } ka_ExplicitCell(cell, serverList); } if (!doAuth) { ka_StringToKey(passwd, cell, &key); memset(passwd, 0, sizeof(passwd)); } if (hostUsage) { memset(serversUse, 0, sizeof(serversUse)); memset(serversHost, 0, sizeof(serversHost)); } startTime = time(0); for (i = 0; i < number; i++) { if (doAuth) { char *reason; code = ka_UserAuthenticateLife(0, name, instance, cell, passwd, 0, &reason); if (code) { fprintf(stderr, "Unable to authenticate to AFS because %s.\n", reason); return code; } } else { struct ktc_token token; struct ktc_token *pToken; struct ubik_client *ubikConn; struct kaentryinfo tentry; int c; code = ka_GetAdminToken(name, instance, cell, &key, 3600, &token, 1 /*new */ ); if (code) { afs_com_err(whoami, code, "getting admin token"); return code; } pToken = &token; if (token.ticketLen == 0) { fprintf("Can't get admin token\n"); return -1; } code = ka_AuthServerConn(cell, KA_MAINTENANCE_SERVICE, pToken, &ubikConn); if (code) { afs_com_err(whoami, code, "Getting AuthServer ubik conn"); return code; } if (verbose) for (c = 0; c < MAXSERVERS; c++) { struct rx_connection *rxConn = ubik_GetRPCConn(ubikConn, c); struct rx_peer *peer; if (rxConn == 0) break; peer = rx_PeerOf(rxConn); printf("conn to %s:%d secObj:%x\n", inet_ntoa(rx_HostOf(peer)), ntohs(rx_PortOf(peer)), rxConn->securityObject); } code = ubik_Call(KAM_GetEntry, ubikConn, 0, name, instance, KAMAJORVERSION, &tentry); if (code) { afs_com_err(whoami, code, "getting information for %s.%s", name, instance); return code; } for (c = 0; c < MAXSERVERS; c++) { struct rx_connection *rxConn = ubik_GetRPCConn(ubikConn, c); int d; if (rxConn == 0) break; if (rxConn->serial > 0) { long host = rx_HostOf(rx_PeerOf(rxConn)); for (d = 0; d < MAXSERVERS; d++) { if (serversHost[d] == 0) serversHost[d] = host; if (host == serversHost[d]) { serversUse[d]++; break; } } } if (verbose) printf("serial is %d\n", rxConn->serial); } ubik_ClientDestroy(ubikConn); } now = time(0); if (!lo) lo = sbrk(0); if (i && ((i & 0x3f) == 0)) { unsigned long this = sbrk(0); printf(" mem after %d: lo=%x, cur=%x => %d (@ %d)\n", i, lo, this, this - lo, (this - lo) / i); if (highWater && (lastWater != this)) { lastWater = this; printf(" core leaking (after %d) should be %x, is %x\n", i, highWater, this); } } if ((highWater == 0) && ((now - startTime) > 61)) { highWater = sbrk(0); lastWater = highWater; printf(" mem highWater mark (after %d) should be %x\n", i, highWater); } if (callsPerSecond) { long target; if (callsPerSecond > 0) target = i / callsPerSecond; else /* if negative interpret as seconds per call */ target = i * (-callsPerSecond); target = (startTime + target) - now; if (target > 0) IOMGR_Sleep(target); } }
afs_int32 ka_UserAuthenticateGeneral2(afs_int32 flags, char *name, char *instance, char *realm, char *password, char *smbname, Date lifetime, afs_int32 * password_expiresP, afs_int32 spare, char **reasonP) { int code; struct ktc_encryptionKey key1, key2; char *ticket = NULL; int ticketLen; struct ktc_encryptionKey sessionKey; long kvno; long expirationTime; char fullRealm[256]; char upperRealm[256]; struct servent *sp; int ttl; struct ktc_principal server; struct ktc_principal client; struct ktc_token token; if (instance == NULL) instance = ""; if (lifetime == 0) lifetime = MAXKTCTICKETLIFETIME; code = cm_SearchCellFile(realm, fullRealm, ka_AddHostProc, NULL); #ifdef AFS_AFSDB_ENV if (code) { code = cm_SearchCellByDNS(realm, fullRealm, &ttl, ka_AddHostProc, NULL); } #endif if (code) { *reasonP = "specified realm is unknown"; return (code); } strcpy(upperRealm, fullRealm); _strupr(upperRealm); /* encrypt password, both ways */ ka_StringToKey(password, upperRealm, &key1); des_string_to_key(password, &key2); /* set port number */ sp = getservbyname("kerberos", "udp"); if (sp) krb_set_port(ntohs(sp->s_port)); *reasonP = NULL; code = krb_get_in_tkt_ext(name, instance, upperRealm, "afs", "", lifetime, &key1, &key2, &ticket, &ticketLen, &sessionKey, &kvno, &expirationTime, reasonP); if (code && *reasonP == NULL) *reasonP = ka_MapKerberosError(code); if (code) return code; strcpy(server.name, "afs"); strcpy(server.instance, ""); strcpy(server.cell, fullRealm); /* Would like to use Vice ID's; using raw names for now. */ strcpy(client.name, name); strcpy(client.instance, instance); strcpy(client.cell, upperRealm); if (smbname) strcpy(client.smbname, smbname); token.startTime = 0; /* XXX */ token.endTime = expirationTime; token.sessionKey = sessionKey; token.kvno = (short)kvno; token.ticketLen = ticketLen; memcpy(token.ticket, ticket, ticketLen); code = ktc_SetToken(&server, &token, &client, (flags & KA_USERAUTH_AUTHENT_LOGON) ? AFS_SETTOK_LOGON : 0); if (code) { if (code == KTC_NOCM || code == KTC_NOCMRPC) *reasonP = "AFS service may not have started"; else if (code == KTC_RPC) *reasonP = "RPC failure in AFS gateway"; else if (code == KTC_NOCELL) *reasonP = "unknown cell"; else *reasonP = "unknown error"; } return code; }
int CommandProc(struct cmd_syndesc *as, void *arock) { char name[MAXKTCNAMELEN] = ""; char instance[MAXKTCNAMELEN] = ""; char cell[MAXKTCREALMLEN] = ""; char realm[MAXKTCREALMLEN] = ""; afs_int32 serverList[MAXSERVERS]; char *lcell; /* local cellname */ int code; int i; struct ubik_client *conn = 0; struct ktc_encryptionKey key; struct ktc_encryptionKey mitkey; struct ktc_encryptionKey newkey; struct ktc_encryptionKey newmitkey; struct ktc_token token; struct passwd pwent; struct passwd *pw = &pwent; int insist; /* insist on good password quality */ int lexplicit = 0; /* servers specified explicitly */ int local; /* explicit cell is same a local cell */ int foundPassword = 0; /*Not yet, anyway */ int foundNewPassword = 0; /*Not yet, anyway */ int foundExplicitCell = 0; /*Not yet, anyway */ #ifdef DEFAULT_MITV4_STRINGTOKEY int dess2k = 1; #elif DEFAULT_AFS_STRINGTOKEY int dess2k = 0; #else int dess2k = -1; #endif /* blow away command line arguments */ for (i = 1; i < zero_argc; i++) memset(zero_argv[i], 0, strlen(zero_argv[i])); zero_argc = 0; /* first determine quiet flag based on -pipe switch */ Pipe = (as->parms[aPIPE].items ? 1 : 0); #if TIMEOUT signal(SIGALRM, timedout); alarm(30); #endif code = ka_Init(0); if (code || !(lcell = ka_LocalCell())) { #ifndef AFS_FREELANCE_CLIENT if (!Pipe) afs_com_err(rn, code, "Can't get local cell name!"); exit(1); #endif } code = rx_Init(0); if (code) { if (!Pipe) afs_com_err(rn, code, "Failed to initialize Rx"); exit(1); } strcpy(instance, ""); /* Parse our arguments. */ if (as->parms[aCELL].items) { /* * cell name explicitly mentioned; take it in if no other cell name * has already been specified and if the name actually appears. If * the given cell name differs from our own, we don't do a lookup. */ foundExplicitCell = 1; strncpy(realm, as->parms[aCELL].items->data, sizeof(realm)); } if (as->parms[aSERVERS].items) { /* explicit server list */ int i; struct cmd_item *ip; char *ap[MAXSERVERS + 2]; for (ip = as->parms[aSERVERS].items, i = 2; ip; ip = ip->next, i++) ap[i] = ip->data; ap[0] = ""; ap[1] = "-servers"; code = ubik_ParseClientList(i, ap, serverList); if (code) { if (!Pipe) afs_com_err(rn, code, "could not parse server list"); return code; } lexplicit = 1; } if (as->parms[aPRINCIPAL].items) { ka_ParseLoginName(as->parms[aPRINCIPAL].items->data, name, instance, cell); if (strlen(instance) > 0) if (!Pipe) fprintf(stderr, "Non-null instance (%s) may cause strange behavior.\n", instance); if (strlen(cell) > 0) { if (foundExplicitCell) { if (!Pipe) fprintf(stderr, "%s: May not specify an explicit cell twice.\n", rn); return -1; } foundExplicitCell = 1; strncpy(realm, cell, sizeof(realm)); } pw->pw_name = name; } else { /* No explicit name provided: use Unix uid. */ #ifdef AFS_NT40_ENV userNameLen = 128; if (GetUserName(userName, &userNameLen) == 0) { if (!Pipe) { fprintf(stderr, "Can't figure out your name in local cell %s from your user id.\n", lcell); fprintf(stderr, "Try providing the user name.\n"); } exit(1); } pw->pw_name = userName; #else pw = getpwuid(getuid()); if (pw == 0) { if (!Pipe) { fprintf(stderr, "Can't figure out your name in local cell %s from your user id.\n", lcell); fprintf(stderr, "Try providing the user name.\n"); } exit(1); } #endif } if (as->parms[aPASSWORD].items) { /* * Current argument is the desired password string. Remember it in * our local buffer, and zero out the argument string - anyone can * see it there with ps! */ foundPassword = 1; strncpy(passwd, as->parms[aPASSWORD].items->data, sizeof(passwd)); memset(as->parms[aPASSWORD].items->data, 0, strlen(as->parms[aPASSWORD].items->data)); } if (as->parms[aNEWPASSWORD].items) { /* * Current argument is the new password string. Remember it in * our local buffer, and zero out the argument string - anyone can * see it there with ps! */ foundNewPassword = 1; strncpy(npasswd, as->parms[aNEWPASSWORD].items->data, sizeof(npasswd)); memset(as->parms[aNEWPASSWORD].items->data, 0, strlen(as->parms[aNEWPASSWORD].items->data)); } #ifdef AFS_FREELANCE_CLIENT if (!foundExplicitCell && !lcell) { if (!Pipe) afs_com_err(rn, code, "no cell name provided"); exit(1); } #else if (!foundExplicitCell) strcpy(realm, lcell); #endif /* freelance */ if ((code = ka_CellToRealm(realm, realm, &local))) { if (!Pipe) afs_com_err(rn, code, "Can't convert cell to realm"); exit(1); } lcstring(cell, realm, sizeof(cell)); ka_PrintUserID("Changing password for '", pw->pw_name, instance, "'"); printf(" in cell '%s'.\n", cell); /* Get the password if it wasn't provided. */ if (!foundPassword) { if (Pipe) getpipepass(passwd, sizeof(passwd)); else { code = read_pass(passwd, sizeof(passwd), "Old password: "******"reading password"); exit(1); } } } ka_StringToKey(passwd, realm, &key); des_string_to_key(passwd, ktc_to_cblockptr(&mitkey)); give_to_child(passwd); /* Get new password if it wasn't provided. */ insist = 0; if (!foundNewPassword) { if (Pipe) getpipepass(npasswd, sizeof(npasswd)); else { do { code = read_pass(npasswd, sizeof(npasswd), "New password (RETURN to abort): ", 0); if (code || (strlen(npasswd) == 0)) { if (code) code = KAREADPW; goto no_change; } } while (password_bad(npasswd)); code = read_pass(verify, sizeof(verify), "Retype new password: "******"Mismatch - "); goto no_change; } memset(verify, 0, sizeof(verify)); } } if ((code = password_bad(npasswd))) { /* assmt here! */ goto no_change_no_msg; } #if TRUNCATEPASSWORD if (strlen(npasswd) > 8) { npasswd[8] = 0; fprintf(stderr, "%s: password too long, only the first 8 chars will be used.\n", rn); } else npasswd[8] = 0; /* in case the password was exactly 8 chars long */ #endif ka_StringToKey(npasswd, realm, &newkey); des_string_to_key(npasswd, ktc_to_cblockptr(&newmitkey)); memset(npasswd, 0, sizeof(npasswd)); if (lexplicit) ka_ExplicitCell(realm, serverList); /* Get an connection to kaserver's admin service in desired cell. Set the * lifetime above the time uncertainty so that badly skewed clocks are * reported when the ticket is decrypted. Then give us 10 seconds to * actually get our work done if the clocks are skewed by only 14:59. * NOTE: Kerberos lifetime encoding will round this up to next 5 minute * interval, namely 20 minutes. */ #define ADMIN_LIFETIME (KTC_TIME_UNCERTAINTY+1) code = ka_GetAdminToken(pw->pw_name, instance, realm, &key, ADMIN_LIFETIME, &token, /*!new */ 0); if (code == KABADREQUEST) { code = ka_GetAdminToken(pw->pw_name, instance, realm, &mitkey, ADMIN_LIFETIME, &token, /*!new */ 0); if ((code == KABADREQUEST) && (strlen(passwd) > 8)) { /* try with only the first 8 characters incase they set their password * with an old style passwd program. */ char pass8[9]; strncpy(pass8, passwd, 8); pass8[8] = 0; ka_StringToKey(pass8, realm, &key); memset(pass8, 0, sizeof(pass8)); memset(passwd, 0, sizeof(passwd)); code = ka_GetAdminToken(pw->pw_name, instance, realm, &key, ADMIN_LIFETIME, &token, /*!new */ 0); #ifdef notdef /* the folks in testing really *hate* this message */ if (code == 0) { fprintf(stderr, "Warning: only the first 8 characters of your old password were significant.\n"); } #endif if (code == 0) { if (dess2k == -1) dess2k = 0; } } else { if (dess2k == -1) dess2k = 1; } } else { if (dess2k == -1) dess2k = 0; } memset(&mitkey, 0, sizeof(mitkey)); memset(&key, 0, sizeof(key)); if (code == KAUBIKCALL) afs_com_err(rn, code, "(Authentication Server unavailable, try later)"); else if (code) { if (code == KABADREQUEST) fprintf(stderr, "%s: Incorrect old password.\n", rn); else afs_com_err(rn, code, "so couldn't change password"); } else { code = ka_AuthServerConn(realm, KA_MAINTENANCE_SERVICE, &token, &conn); if (code) afs_com_err(rn, code, "contacting Admin Server"); else { if (dess2k == 1) code = ka_ChangePassword(pw->pw_name, instance, conn, 0, &newmitkey); else code = ka_ChangePassword(pw->pw_name, instance, conn, 0, &newkey); memset(&newkey, 0, sizeof(newkey)); memset(&newmitkey, 0, sizeof(newmitkey)); if (code) { char *reason; reason = (char *)afs_error_message(code); fprintf(stderr, "%s: Password was not changed because %s\n", rn, reason); } else printf("Password changed.\n\n"); } } memset(&newkey, 0, sizeof(newkey)); memset(&newmitkey, 0, sizeof(newmitkey)); /* Might need to close down the ubik_Client connection */ if (conn) { ubik_ClientDestroy(conn); conn = 0; } rx_Finalize(); terminate_child(); exit(code); no_change: /* yuck, yuck, yuck */ if (code) afs_com_err(rn, code, "getting new password"); no_change_no_msg: memset(&key, 0, sizeof(key)); memset(npasswd, 0, sizeof(npasswd)); printf("Password for '%s' in cell '%s' unchanged.\n\n", pw->pw_name, cell); terminate_child(); exit(code ? code : 1); }
afs_int32 uss_kauth_AddUser(char *a_user, char *a_passwd) { /*uss_kauth_AddUser */ #ifdef USS_KAUTH_DB static char rn[] = "uss_kauth_AddUser"; /*Routine name */ #endif struct ktc_encryptionKey ktc_key; EncryptionKey key; afs_int32 code; if (uss_SkipKaserver) { /* * Don't talk to the kaserver; assume calls succeded and simply return. * Amasingly people want to update it (most likely kerberos) themselves... */ if (uss_verbose) printf ("[Skip Kaserver option - Adding of user %s in Authentication DB not done]\n", a_user); return 0; } /* * Make sure the module has been initialized before we start trying * to talk to AuthServers. */ if (!initDone) { code = InitThisModule(); if (code) exit(code); } /* * Given the (unencrypted) password and cell, generate a key to * pass to the AuthServer. */ ka_StringToKey(a_passwd, uss_Cell, &ktc_key); memcpy(&key, &ktc_key, sizeof(key)); /* XXX - we could just cast */ if (!uss_DryRun) { if (uss_verbose) fprintf(stderr, "Adding user '%s' to the Authentication DB\n", a_user); #ifdef USS_KAUTH_DB_INSTANCE fprintf(stderr, "%s: KAM_CreateUser: user='******', CreatorInstance='%s', %d bytes\n", rn, a_user, CreatorInstance, strlen(CreatorInstance)); #endif /* USS_KAUTH_DB_INSTANCE */ code = ubik_KAM_CreateUser(uconn_kauthP, 0, a_user, UserInstance, /*set by CheckUsername() */ key); if (code) { if (code == KAEXIST) { if (uss_verbose) fprintf(stderr, "%s: Warning: User '%s' already in Authentication DB\n", uss_whoami, a_user); } else { afs_com_err(uss_whoami, code, "while adding user '%s' to Authentication DB", a_user); #ifdef USS_KAUTH_DB printf("%s: Error code from KAM_CreateUser: %d\n", rn, code); #endif /* USS_KAUTH_DB */ return (code); } } /*KAM_CreateUser failed */ } /*Not a dry run */ else fprintf(stderr, "\t[Dry run - user '%s' NOT added to Authentication DB]\n", a_user); return (0); } /*uss_kauth_AddUser */
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 */