void ka_StringToKey(char *str, char *cell, /* cell for password */ struct ktc_encryptionKey *key) { char realm[MAXKTCREALMLEN]; afs_int32 code; LOCK_GLOBAL_MUTEX; code = ka_CellToRealm(cell, realm, 0 /*local */ ); if (code) /* just take his word for it */ strncpy(realm, cell, sizeof(realm)); else /* for backward compatibility */ lcstring(realm, realm, sizeof(realm)); if (strlen(str) > 8) StringToKey(str, realm, key); else Andrew_StringToKey(str, realm, key); UNLOCK_GLOBAL_MUTEX; }
int unlog_NormalizeCellNames(char **list, int size) { char *newCellName; unsigned index; struct afsconf_dir *conf; int code; struct afsconf_cell cellinfo; if (!(conf = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) { fprintf(stderr, "Cannot get cell configuration info!\n"); exit(1); } for (index = 0; index < size; index++, list++) { newCellName = malloc(MAXKTCREALMLEN); if (!newCellName) { perror("unlog_NormalizeCellNames --- malloc failed"); exit(1); } lcstring(newCellName, *list, MAXKTCREALMLEN); code = afsconf_GetCellInfo(conf, newCellName, 0, &cellinfo); if (code) { if (code == AFSCONF_NOTFOUND) { fprintf(stderr, "Unrecognized cell name %s\n", newCellName); } else { fprintf(stderr, "unlog_NormalizeCellNames - afsconf_GetCellInfo"); fprintf(stderr, " failed, code = %d\n", code); } exit(1); } strcpy(newCellName, cellinfo.name); *list = newCellName; } afsconf_Close(conf); return 0; }
int main(int argc, char **argv) { char *p, *ename; char const *const *cpp; int got_language = 0; char *got_include = 0; char *got_prefix = "."; char lcname[6]; #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 /* argument parsing */ debug = 0; filename = 0; whoami = argv[0]; p = strrchr(whoami, '/'); if (p) whoami = p + 1; while (argv++, --argc) { char *arg = *argv; if (arg[0] != '-') { if (filename) dup_err("filenames", filename, arg); filename = arg; } else { arg++; if (check_arg(debug_args, arg)) debug++; else if (check_arg(lang_args, arg)) { got_language++; arg = *++argv, argc--; if (!arg) usage(); if (language) dup_err("languanges", language_names[(int)language], arg); #define check_lang(x,v) if (!strcasecmp(arg,x)) language = v check_lang("c", lang_C); check_lang("ansi_c", lang_C); check_lang("ansi-c", lang_C); check_lang("krc", lang_KRC); check_lang("kr_c", lang_KRC); check_lang("kr-c", lang_KRC); check_lang("k&r-c", lang_KRC); check_lang("k&r_c", lang_KRC); check_lang("c++", lang_CPP); check_lang("cplusplus", lang_CPP); check_lang("c-plus-plus", lang_CPP); #undef check_lang if (!language) { fprintf(stderr, "%s: unknown language name `%s'\n", whoami, arg); fprintf(stderr, "\tpick one of: C K&R-C\n"); exit(1); } } else if (strcmp(arg, "h") == 0) { arg = *++argv, argc--; if (!arg) usage(); got_include = arg; } else if (strcmp(arg, "p") == 0) { arg = *++argv, argc--; if (!arg) usage(); got_prefix = arg; } else if (strcmp(arg, "v") == 0) { arg = *++argv, argc--; version = atoi(arg); if (version != 1 && version != 2) { fprintf(stderr, "%s: unknown control argument -`%s'\n", whoami, arg); usage(); exit(1); } if (version == 2) use_msf = 1; } else { fprintf(stderr, "%s: unknown control argument -`%s'\n", whoami, arg); usage(); } } } if (!filename) usage(); if (!got_language) language = lang_C; else if (language == lang_CPP) { fprintf(stderr, "%s: Sorry, C++ support is not yet finished.\n", whoami); exit(1); } p = strrchr(filename, '/'); if (p == (char *)NULL) p = filename; else p++; ename = xmalloc(strlen(p) + 5); strcpy(ename, p); /* Now, flush .et suffix if it exists. */ p = strrchr(ename, '.'); if (p != NULL) { if (strcmp(p, ".et") == 0) *p = 0; } if (use_msf) { sprintf(msf_file, "%s.msf", ename); } else { sprintf(c_file, "%s.c", ename); } if (got_include) { sprintf(h_file, "%s.h", got_include); } else { sprintf(h_file, "%s.h", ename); } p = strrchr(filename, '.'); if (p == NULL) { p = xmalloc(strlen(filename) + 4); sprintf(p, "%s.et", filename); filename = p; } sprintf(et_file, "%s/%s", got_prefix, filename); yyin = fopen(et_file, "r"); if (!yyin) { perror(et_file); exit(1); } /* on NT, yyout is not initialized to stdout */ if (!yyout) { yyout = stdout; } hfile = fopen(h_file, "w"); if (hfile == (FILE *) NULL) { perror(h_file); exit(1); } fprintf(hfile, warning, h_file); if (got_include) { char buffer[BUFSIZ]; char prolog_h_file[MAXPATHLEN]; FILE *prolog_hfile; int count, written; strcpy(prolog_h_file, got_prefix); strcat(prolog_h_file, "/"); strcat(prolog_h_file, got_include); strcat(prolog_h_file, ".p.h"); prolog_hfile = fopen(prolog_h_file, "r"); if (prolog_hfile) { fprintf(stderr, "Including %s at beginning of %s file.\n", prolog_h_file, h_file); fprintf(hfile, "/* Including %s at beginning of %s file. */\n\n", prolog_h_file, h_file); do { count = fread(buffer, sizeof(char), sizeof(buffer), prolog_hfile); if (count == EOF) { perror(prolog_h_file); exit(1); } written = fwrite(buffer, sizeof(char), count, hfile); if (count != written) { perror(prolog_h_file); exit(1); } } while (count > 0); fprintf(hfile, "\n/* End of prolog file %s. */\n\n", prolog_h_file); } } if (use_msf) { msfile = fopen(msf_file, "w"); if (msfile == (FILE *) NULL) { perror(msf_file); exit(1); } fprintf(msfile, msf_warning, msf_file); } else { cfile = fopen(c_file, "w"); if (cfile == (FILE *) NULL) { perror(c_file); exit(1); } fprintf(cfile, warning, c_file); /* prologue */ if (language == lang_C) cpp = c_src_prolog; else if (language == lang_KRC) cpp = krc_src_prolog; else abort(); while (*cpp) fputs(*cpp++, cfile); } /* parse it */ yyparse(); fclose(yyin); /* bye bye input file */ if (!use_msf) { fputs(" 0\n};\n\n", cfile); fprintf(cfile, "static const struct error_table et = { text, %ldL, %d };\n\n", (long int)table_number, current); fputs("static struct et_list etlink = { 0, &et};\n\n", cfile); fprintf(cfile, "void initialize_%s_error_table(void) {\n", table_name); fputs(" afs_add_to_error_table(&etlink);\n", cfile); fputs("}\n", cfile); fclose(cfile); fprintf(hfile, "extern void initialize_%s_error_table(void);\n", table_name); } else { fprintf(hfile, "#define initialize_%s_error_table(void)\n", table_name); } fprintf(hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n", table_name, (long int)table_number); /* compatibility... */ fprintf(hfile, "\n/* for compatibility with older versions... */\n"); fprintf(hfile, "#define init_%s_err_tbl initialize_%s_error_table\n", table_name, table_name); fprintf(hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", table_name, table_name); fprintf(hfile, "\n/* for compatibility with other users... */\n"); lcstring(lcname, table_name, sizeof(lcname)); fprintf(hfile, "#define ERROR_TABLE_BASE_%s (%ldL)\n", lcname, (long int)table_number); fprintf(hfile, "#define init_%s_err_tbl initialize_%s_error_table\n", lcname, table_name); fprintf(hfile, "#define initialize_%s_error_table initialize_%s_error_table\n", lcname, table_name); fprintf(hfile, "#define %s_err_base ERROR_TABLE_BASE_%s\n", lcname, lcname); fclose(hfile); /* bye bye include file */ if (use_msf) fclose(msfile); return 0; }
int afsconf_GetCellInfo(struct afsconf_dir *adir, char *acellName, char *aservice, struct afsconf_cell *acellInfo) { struct afsconf_entry *tce; struct afsconf_aliasentry *tcae; struct afsconf_entry *bestce; afs_int32 i; int tservice; char *tcell; int cnLen; int ambig; char tbuffer[64]; LOCK_GLOBAL_MUTEX; if (adir) _afsconf_Check(adir); if (acellName) { tcell = acellName; cnLen = (int)(strlen(tcell) + 1); lcstring(tcell, tcell, cnLen); afsconf_SawCell = 1; /* will ignore the AFSCELL switch on future */ /* call to afsconf_GetLocalCell: like klog */ } else { i = afsconf_GetLocalCell(adir, tbuffer, sizeof(tbuffer)); if (i) { UNLOCK_GLOBAL_MUTEX; return i; } tcell = tbuffer; } cnLen = strlen(tcell); bestce = (struct afsconf_entry *)0; ambig = 0; if (!adir) { UNLOCK_GLOBAL_MUTEX; return 0; } /* Look through the list of aliases */ for (tcae = adir->alias_entries; tcae; tcae = tcae->next) { if (strcasecmp(tcae->aliasInfo.aliasName, tcell) == 0) { tcell = tcae->aliasInfo.realName; break; } } for (tce = adir->entries; tce; tce = tce->next) { if (strcasecmp(tce->cellInfo.name, tcell) == 0) { /* found our cell */ bestce = tce; ambig = 0; break; } if (strlen(tce->cellInfo.name) < cnLen) continue; /* clearly wrong */ if (strncasecmp(tce->cellInfo.name, tcell, cnLen) == 0) { if (bestce) ambig = 1; /* ambiguous unless we get exact match */ bestce = tce; } } if (!ambig && bestce && bestce->cellInfo.numServers) { *acellInfo = bestce->cellInfo; /* structure assignment */ if (aservice) { tservice = afsconf_FindService(aservice); if (tservice < 0) { UNLOCK_GLOBAL_MUTEX; return AFSCONF_NOTFOUND; /* service not found */ } for (i = 0; i < acellInfo->numServers; i++) { acellInfo->hostAddr[i].sin_port = tservice; } } acellInfo->timeout = 0; /* * Until we figure out how to separate out ubik server * queries from other server queries, only perform gethostbyname() * lookup on the specified hostnames for the client CellServDB files. */ if (_afsconf_IsClientConfigDirectory(adir->name) && !(acellInfo->flags & AFSCONF_CELL_FLAG_DNS_QUERIED)) { int j; short numServers=0; /*Num active servers for the cell */ struct sockaddr_in hostAddr[MAXHOSTSPERCELL]; /*IP addresses for cell's servers */ char hostName[MAXHOSTSPERCELL][MAXHOSTCHARS]; /*Names for cell's servers */ char clone[MAXHOSTSPERCELL]; /*Indicates which ones are clones. */ memset(&hostAddr, 0, sizeof(hostAddr)); memset(&hostName, 0, sizeof(hostName)); memset(&clone, 0, sizeof(clone)); for ( j=0; j<acellInfo->numServers && numServers < MAXHOSTSPERCELL; j++ ) { struct hostent *he = gethostbyname(acellInfo->hostName[j]); int foundAddr = 0; if (he && he->h_addrtype == AF_INET) { int i; /* obtain all the valid address from the list */ for (i=0 ; he->h_addr_list[i] && numServers < MAXHOSTSPERCELL; i++) { /* check to see if this is a new address; if so insert it into the list */ int k, dup; afs_uint32 addr; memcpy(&addr, he->h_addr_list[i], sizeof(addr)); for (k=0, dup=0; !dup && k < numServers; k++) { if (hostAddr[k].sin_addr.s_addr == addr) { dup = 1; } } if (dup) continue; hostAddr[numServers].sin_family = AF_INET; hostAddr[numServers].sin_port = acellInfo->hostAddr[0].sin_port; #ifdef STRUCT_SOCKADDR_HAS_SA_LEN hostAddr[numServers].sin_len = sizeof(struct sockaddr_in); #endif memcpy(&hostAddr[numServers].sin_addr.s_addr, he->h_addr_list[i], sizeof(afs_uint32)); strcpy(hostName[numServers], acellInfo->hostName[j]); clone[numServers] = acellInfo->clone[j]; foundAddr = 1; numServers++; } } if (!foundAddr) { hostAddr[numServers] = acellInfo->hostAddr[j]; strcpy(hostName[numServers], acellInfo->hostName[j]); clone[numServers] = acellInfo->clone[j]; numServers++; } } for (i=0; i<numServers; i++) { acellInfo->hostAddr[i] = hostAddr[i]; strcpy(acellInfo->hostName[i], hostName[i]); acellInfo->clone[i] = clone[i]; } acellInfo->numServers = numServers; acellInfo->flags |= AFSCONF_CELL_FLAG_DNS_QUERIED; } UNLOCK_GLOBAL_MUTEX; return 0; } else { UNLOCK_GLOBAL_MUTEX; return afsconf_GetAfsdbInfo(tcell, aservice, acellInfo); } }
int main(int argc, char *argv[]) { afs_int32 code; char *whoami = argv[0]; afs_uint32 serverList[MAXSERVERS]; struct afsconf_cell cellinfo; char *cell; const char *cellservdb, *dbpath, *lclpath; int a; char arg[32]; char default_lclpath[AFSDIR_PATH_MAX]; int servers; int initFlags; int level; /* security level for Ubik */ afs_int32 i; char clones[MAXHOSTSPERCELL]; afs_uint32 host = ntohl(INADDR_ANY); char *auditFileName = NULL; struct rx_service *tservice; struct rx_securityClass *sca[1]; struct rx_securityClass *scm[3]; extern int rx_stackSize; #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(SIGABRT, &nsa, NULL); sigaction(SIGSEGV, &nsa, NULL); #endif osi_audit_init(); if (argc == 0) { usage: printf("Usage: kaserver [-noAuth] [-database <dbpath>] " "[-auditlog <log path>] [-audit-interface <file|sysvmq>] " "[-rxbind] [-localfiles <lclpath>] [-minhours <n>] " "[-servers <serverlist>] [-crossrealm] " /*" [-enable_peer_stats] [-enable_process_stats] " */ "[-help]\n"); exit(1); } #ifdef AFS_NT40_ENV /* initialize winsock */ if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami); exit(1); } #endif /* Initialize dirpaths */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { #ifdef AFS_NT40_ENV ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); #endif fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", argv[0]); exit(2); } cellservdb = AFSDIR_SERVER_ETC_DIRPATH; dbpath = AFSDIR_SERVER_KADB_FILEPATH; strcompose(default_lclpath, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/", AFSDIR_KADB_FILE, NULL); lclpath = default_lclpath; debugOutput = 0; servers = 0; initFlags = 0; level = rxkad_crypt; for (a = 1; a < argc; a++) { int arglen = strlen(argv[a]); lcstring(arg, argv[a], sizeof(arg)); #define IsArg(a) (strncmp (arg,a, arglen) == 0) if (strcmp(arg, "-database") == 0) { dbpath = argv[++a]; if (strcmp(lclpath, default_lclpath) == 0) lclpath = dbpath; } else if (strncmp(arg, "-auditlog", arglen) == 0) { auditFileName = argv[++a]; } else if (strncmp(arg, "-audit-interface", arglen) == 0) { char *interface = argv[++a]; if (osi_audit_interface(interface)) { printf("Invalid audit interface '%s'\n", interface); exit(1); } } else if (strcmp(arg, "-localfiles") == 0) lclpath = argv[++a]; else if (strcmp(arg, "-servers") == 0) debugOutput++, servers = 1; else if (strcmp(arg, "-noauth") == 0) debugOutput++, initFlags |= 1; else if (strcmp(arg, "-fastkeys") == 0) debugOutput++, initFlags |= 4; else if (strcmp(arg, "-dbfixup") == 0) debugOutput++, initFlags |= 8; else if (strcmp(arg, "-cellservdb") == 0) { cellservdb = argv[++a]; initFlags |= 2; debugOutput++; } else if (IsArg("-crypt")) level = rxkad_crypt; else if (IsArg("-safe")) level = rxkad_crypt; else if (IsArg("-clear")) level = rxkad_clear; else if (IsArg("-sorry")) level = rxkad_clear; else if (IsArg("-debug")) verbose_track = 0; else if (IsArg("-crossrealm")) krb4_cross = 1; else if (IsArg("-rxbind")) rxBind = 1; else if (IsArg("-minhours")) { MinHours = atoi(argv[++a]); } else if (IsArg("-enable_peer_stats")) { rx_enablePeerRPCStats(); } else if (IsArg("-enable_process_stats")) { rx_enableProcessRPCStats(); } else if (*arg == '-') { /* hack to support help flag */ goto usage; } } if (auditFileName) { osi_audit_file(auditFileName); } if ((code = ka_CellConfig(cellservdb))) goto abort; cell = ka_LocalCell(); KA_conf = afsconf_Open(cellservdb); if (!KA_conf) { code = KANOCELLS; abort: afs_com_err(whoami, code, "Failed getting cell info"); exit(1); } #ifdef AUTH_DBM_LOG kalog_Init(); #else /* NT & HPUX do not have dbm package support. So we can only do some * text logging. So open the AuthLog file for logging and redirect * stdin and stdout to it */ OpenLog(AFSDIR_SERVER_KALOG_FILEPATH); SetupLogSignals(); #endif fprintf(stderr, "%s: WARNING: kaserver is deprecated due to its weak security " "properties. Migrating to a Kerberos 5 KDC is advised. " "http://www.openafs.org/no-more-des.html\n", whoami); ViceLog(0, ("WARNING: kaserver is deprecated due to its weak security properties. " "Migrating to a Kerberos 5 KDC is advised. " "http://www.openafs.org/no-more-des.html\n")); code = afsconf_GetExtendedCellInfo(KA_conf, cell, AFSCONF_KAUTHSERVICE, &cellinfo, clones); if (servers) { if ((code = ubik_ParseServerList(argc, argv, &myHost, serverList))) { afs_com_err(whoami, code, "Couldn't parse server list"); exit(1); } cellinfo.hostAddr[0].sin_addr.s_addr = myHost; for (i = 1; i < MAXSERVERS; i++) { if (!serverList[i]) break; cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i]; } cellinfo.numServers = i; } else { code = convert_cell_to_ubik(&cellinfo, &myHost, serverList); if (code) goto abort; ViceLog(0, ("Using server list from %s cell database.\n", cell)); } /* initialize audit user check */ osi_audit_set_user_check(KA_conf, KA_IsLocalRealmMatch); /* initialize ubik */ if (level == rxkad_clear) ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate, KA_conf); else if (level == rxkad_crypt) ubik_SetClientSecurityProcs(afsconf_ClientAuthSecure, afsconf_UpToDate, KA_conf); else { ViceLog(0, ("Unsupported security level %d\n", level)); exit(5); } ViceLog(0, ("Using level %s for Ubik connections.\n", (level == rxkad_crypt ? "crypt" : "clear"))); ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects, afsconf_CheckAuth, KA_conf); ubik_nBuffers = 80; if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = parseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) { host = SHostAddrs[0]; rx_InitHost(host, htons(AFSCONF_KAUTHPORT)); } } /* Disable jumbograms */ rx_SetNoJumbo(); if (servers) code = ubik_ServerInit(myHost, htons(AFSCONF_KAUTHPORT), serverList, dbpath, &KA_dbase); else code = ubik_ServerInitByInfo(myHost, htons(AFSCONF_KAUTHPORT), &cellinfo, clones, dbpath, &KA_dbase); if (code) { afs_com_err(whoami, code, "Ubik init failed"); exit(2); } sca[RX_SCINDEX_NULL] = rxnull_NewServerSecurityObject(); tservice = rx_NewServiceHost(host, 0, KA_AUTHENTICATION_SERVICE, "AuthenticationService", sca, 1, KAA_ExecuteRequest); if (tservice == (struct rx_service *)0) { ViceLog(0, ("Could not create Authentication rx service\n")); exit(3); } rx_SetMinProcs(tservice, 1); rx_SetMaxProcs(tservice, 1); tservice = rx_NewServiceHost(host, 0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService", sca, 1, KAT_ExecuteRequest); if (tservice == (struct rx_service *)0) { ViceLog(0, ("Could not create Ticket Granting rx service\n")); exit(3); } rx_SetMinProcs(tservice, 1); rx_SetMaxProcs(tservice, 1); scm[RX_SCINDEX_NULL] = sca[RX_SCINDEX_NULL]; scm[RX_SCINDEX_VAB] = 0; scm[RX_SCINDEX_KAD] = rxkad_NewServerSecurityObject(rxkad_crypt, 0, kvno_admin_key, 0); tservice = rx_NewServiceHost(host, 0, KA_MAINTENANCE_SERVICE, "Maintenance", scm, 3, KAM_ExecuteRequest); if (tservice == (struct rx_service *)0) { ViceLog(0, ("Could not create Maintenance rx service\n")); exit(3); } rx_SetMinProcs(tservice, 1); rx_SetMaxProcs(tservice, 1); rx_SetStackSize(tservice, 10000); tservice = rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", scm, 3, RXSTATS_ExecuteRequest); if (tservice == (struct rx_service *)0) { ViceLog(0, ("Could not create rpc stats rx service\n")); exit(3); } rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, 4); initialize_dstats(); /* allow super users to manage RX statistics */ rx_SetRxStatUserOk(KA_rxstat_userok); rx_StartServer(0); /* start handling req. of all types */ if (init_kaprocs(lclpath, initFlags)) return -1; if ((code = init_krb_udp())) { ViceLog(0, ("Failed to initialize UDP interface; code = %d.\n", code)); ViceLog(0, ("Running without UDP access.\n")); } ViceLog(0, ("Starting to process AuthServer requests\n")); rx_ServerProc(NULL); /* donate this LWP */ return 0; }
int main(int argc, char **argv) { register afs_int32 code; afs_uint32 myHost; register struct hostent *th; char hostname[64]; struct rx_service *tservice; struct rx_securityClass **securityClasses; afs_int32 numClasses; int kerberosKeys; /* set if found some keys */ int lwps = 3; char clones[MAXHOSTSPERCELL]; afs_uint32 host = htonl(INADDR_ANY); const char *pr_dbaseName; char *whoami = "ptserver"; int a; char arg[100]; char *auditFileName = NULL; #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(SIGABRT, &nsa, NULL); sigaction(SIGSEGV, &nsa, NULL); #endif osi_audit_init(); osi_audit(PTS_StartEvent, 0, AUD_END); /* Initialize dirpaths */ if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { #ifdef AFS_NT40_ENV ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); #endif fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", argv[0]); exit(2); } pr_dbaseName = AFSDIR_SERVER_PRDB_FILEPATH; #if defined(SUPERGROUPS) /* make sure the structures for database records are the same size */ if ((sizeof(struct prentry) != ENTRYSIZE) || (sizeof(struct prentryg) != ENTRYSIZE)) { fprintf(stderr, "The structures for the database records are different" " sizes\n" "struct prentry = %" AFS_SIZET_FMT "\n" "struct prentryg = %" AFS_SIZET_FMT "\n" "ENTRYSIZE = %d\n", sizeof(struct prentry), sizeof(struct prentryg), ENTRYSIZE); PT_EXIT(1); } #endif for (a = 1; a < argc; a++) { int alen; lcstring(arg, argv[a], sizeof(arg)); alen = strlen(arg); if (strcmp(argv[a], "-d") == 0) { if ((a + 1) >= argc) { fprintf(stderr, "missing argument for -d\n"); return -1; } debuglevel = atoi(argv[++a]); LogLevel = debuglevel; } else if ((strncmp(arg, "-database", alen) == 0) || (strncmp(arg, "-db", alen) == 0)) { pr_dbaseName = argv[++a]; /* specify a database */ } else if (strncmp(arg, "-p", alen) == 0) { lwps = atoi(argv[++a]); if (lwps > 16) { /* maximum of 16 */ printf("Warning: '-p %d' is too big; using %d instead\n", lwps, 16); lwps = 16; } else if (lwps < 3) { /* minimum of 3 */ printf("Warning: '-p %d' is too small; using %d instead\n", lwps, 3); lwps = 3; } #if defined(SUPERGROUPS) } else if ((strncmp(arg, "-groupdepth", alen) == 0) || (strncmp(arg, "-depth", alen) == 0)) { depthsg = atoi(argv[++a]); /* Max search depth for supergroups */ #endif } else if (strncmp(arg, "-default_access", alen) == 0) { prp_user_default = prp_access_mask(argv[++a]); prp_group_default = prp_access_mask(argv[++a]); } else if (strncmp(arg, "-restricted", alen) == 0) { restricted = 1; } else if (strncmp(arg, "-rxbind", alen) == 0) { rxBind = 1; } else if (strncmp(arg, "-allow-dotted-principals", alen) == 0) { rxkadDisableDotCheck = 1; } else if (strncmp(arg, "-enable_peer_stats", alen) == 0) { rx_enablePeerRPCStats(); } else if (strncmp(arg, "-enable_process_stats", alen) == 0) { rx_enableProcessRPCStats(); } #ifndef AFS_NT40_ENV else if (strncmp(arg, "-syslog", alen) == 0) { /* set syslog logging flag */ serverLogSyslog = 1; } else if (strncmp(arg, "-syslog=", MIN(8, alen)) == 0) { serverLogSyslog = 1; serverLogSyslogFacility = atoi(arg + 8); } #endif else if (strncmp(arg, "-auditlog", alen) == 0) { auditFileName = argv[++a]; } else if (strncmp(arg, "-audit-interface", alen) == 0) { char *interface = argv[++a]; if (osi_audit_interface(interface)) { printf("Invalid audit interface '%s'\n", interface); PT_EXIT(1); } } else if (!strncmp(arg, "-rxmaxmtu", alen)) { if ((a + 1) >= argc) { fprintf(stderr, "missing argument for -rxmaxmtu\n"); PT_EXIT(1); } rxMaxMTU = atoi(argv[++a]); if ((rxMaxMTU < RX_MIN_PACKET_SIZE) || (rxMaxMTU > RX_MAX_PACKET_DATA_SIZE)) { printf("rxMaxMTU %d invalid; must be between %d-%" AFS_SIZET_FMT "\n", rxMaxMTU, RX_MIN_PACKET_SIZE, RX_MAX_PACKET_DATA_SIZE); PT_EXIT(1); } } else if (*arg == '-') { /* hack in help flag support */ #if defined(SUPERGROUPS) #ifndef AFS_NT40_ENV printf("Usage: ptserver [-database <db path>] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-syslog[=FACILITY]] [-d <debug level>] " "[-p <number of processes>] [-rebuild] " "[-groupdepth <depth>] " "[-restricted] [-rxmaxmtu <bytes>] [-rxbind] " "[-allow-dotted-principals] " "[-enable_peer_stats] [-enable_process_stats] " "[-default_access default_user_access default_group_access] " "[-help]\n"); #else /* AFS_NT40_ENV */ printf("Usage: ptserver [-database <db path>] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-d <debug level>] " "[-p <number of processes>] [-rebuild] [-rxbind] " "[-allow-dotted-principals] " "[-default_access default_user_access default_group_access] " "[-restricted] [-rxmaxmtu <bytes>] [-rxbind] " "[-groupdepth <depth>] " "[-help]\n"); #endif #else #ifndef AFS_NT40_ENV printf("Usage: ptserver [-database <db path>] " "[-auditlog <log path>] " "[-audit-interface <file|sysvmq> (default is file)] " "[-d <debug level>] " "[-syslog[=FACILITY]] " "[-p <number of processes>] [-rebuild] " "[-enable_peer_stats] [-enable_process_stats] " "[-default_access default_user_access default_group_access] " "[-restricted] [-rxmaxmtu <bytes>] [-rxbind] " "[-allow-dotted-principals] " "[-help]\n"); #else /* AFS_NT40_ENV */ printf("Usage: ptserver [-database <db path>] " "[-auditlog <log path>] [-d <debug level>] " "[-default_access default_user_access default_group_access] " "[-restricted] [-rxmaxmtu <bytes>] [-rxbind] " "[-allow-dotted-principals] " "[-p <number of processes>] [-rebuild] " "[-help]\n"); #endif #endif fflush(stdout); PT_EXIT(1); } #if defined(SUPERGROUPS) else { fprintf(stderr, "Unrecognized arg: '%s' ignored!\n", arg); } #endif } if (auditFileName) { osi_audit_file(auditFileName); osi_audit(PTS_StartEvent, 0, AUD_END); } #ifndef AFS_NT40_ENV serverLogSyslogTag = "ptserver"; #endif OpenLog(AFSDIR_SERVER_PTLOG_FILEPATH); /* set up logging */ SetupLogSignals(); prdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); if (!prdir) { fprintf(stderr, "ptserver: can't open configuration directory.\n"); PT_EXIT(1); } if (afsconf_GetNoAuthFlag(prdir)) printf("ptserver: running unauthenticated\n"); #ifdef AFS_NT40_ENV /* initialize winsock */ if (afs_winsockInit() < 0) { ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); fprintf(stderr, "ptserver: couldn't initialize winsock. \n"); PT_EXIT(1); } #endif /* get this host */ gethostname(hostname, sizeof(hostname)); th = gethostbyname(hostname); if (!th) { fprintf(stderr, "ptserver: couldn't get address of this host.\n"); PT_EXIT(1); } memcpy(&myHost, th->h_addr, sizeof(afs_uint32)); /* get list of servers */ code = afsconf_GetExtendedCellInfo(prdir, NULL, "afsprot", &info, clones); if (code) { afs_com_err(whoami, code, "Couldn't get server list"); PT_EXIT(2); } pr_realmName = info.name; { afs_int32 kvno; /* see if there is a KeyFile here */ struct ktc_encryptionKey key; code = afsconf_GetLatestKey(prdir, &kvno, &key); kerberosKeys = (code == 0); if (!kerberosKeys) printf ("ptserver: can't find any Kerberos keys, code = %d, ignoring\n", code); } if (kerberosKeys) { /* initialize ubik */ ubik_CRXSecurityProc = afsconf_ClientAuth; ubik_CRXSecurityRock = prdir; ubik_SRXSecurityProc = afsconf_ServerAuth; ubik_SRXSecurityRock = prdir; ubik_CheckRXSecurityProc = afsconf_CheckAuth; ubik_CheckRXSecurityRock = prdir; } /* The max needed is when deleting an entry. A full CoEntry deletion * required removal from 39 entries. Each of which may refers to the entry * being deleted in one of its CoEntries. If a CoEntry is freed its * predecessor CoEntry will be modified as well. Any freed blocks also * modifies the database header. Counting the entry being deleted and its * CoEntry this adds up to as much as 1+1+39*3 = 119. If all these entries * and the header are in separate Ubik buffers then 120 buffers may be * required. */ ubik_nBuffers = 120 + /*fudge */ 40; if (rxBind) { afs_int32 ccode; if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || AFSDIR_SERVER_NETINFO_FILEPATH) { char reason[1024]; ccode = parseNetFiles(SHostAddrs, NULL, NULL, ADDRSPERSITE, reason, AFSDIR_SERVER_NETINFO_FILEPATH, AFSDIR_SERVER_NETRESTRICT_FILEPATH); } else { ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); } if (ccode == 1) { host = SHostAddrs[0]; /* the following call is idempotent so if/when it gets called * again by the ubik init stuff, it doesn't really matter * -- klm */ rx_InitHost(host, htons(AFSCONF_PROTPORT)); } } code = ubik_ServerInitByInfo(myHost, htons(AFSCONF_PROTPORT), &info, clones, pr_dbaseName, &dbase); if (code) { afs_com_err(whoami, code, "Ubik init failed"); PT_EXIT(2); } #if defined(SUPERGROUPS) pt_hook_write(); #endif afsconf_BuildServerSecurityObjects(prdir, 0, &securityClasses, &numClasses); /* Disable jumbograms */ rx_SetNoJumbo(); if (rxMaxMTU != -1) { rx_SetMaxMTU(rxMaxMTU); } tservice = rx_NewServiceHost(host, 0, PRSRV, "Protection Server", securityClasses, numClasses, PR_ExecuteRequest); if (tservice == (struct rx_service *)0) { fprintf(stderr, "ptserver: Could not create new rx service.\n"); PT_EXIT(3); } rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, lwps); if (rxkadDisableDotCheck) { rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS, (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); } tservice = rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", securityClasses, numClasses, RXSTATS_ExecuteRequest); if (tservice == (struct rx_service *)0) { fprintf(stderr, "ptserver: Could not create new rx service.\n"); PT_EXIT(3); } rx_SetMinProcs(tservice, 2); rx_SetMaxProcs(tservice, 4); /* allow super users to manage RX statistics */ rx_SetRxStatUserOk(pr_rxstat_userok); LogCommandLine(argc, argv, "ptserver", #if defined(SUPERGROUPS) "1.1", #else "1.0", #endif "Starting AFS", FSLog); rx_StartServer(1); osi_audit(PTS_FinishEvent, -1, AUD_END); exit(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; }
int main(int argc, char **argv) { register afs_int32 code; char op[8]; char name[PR_MAXNAMELEN]; afs_int32 id, oid = ANONYMOUSID, gid; afs_int32 pos; unsigned int i; int n; struct prentry entry; prlist alist; idlist lid; namelist lnames; struct hostent *hostinfo; struct in_addr *hostaddr; afs_int32 *ptr; char *foo; afs_int32 over; char *cell; #ifdef AFS_AIX32_ENV /* * The following signal action for AIX is necessary so that in case of a * crash (i.e. core is generated) we can include the user's data section * in the core dump. Unfortunately, by default, only a partial core is * generated which, in many cases, isn't too useful. */ struct sigaction nsa; sigemptyset(&nsa.sa_mask); nsa.sa_handler = SIG_DFL; nsa.sa_flags = SA_FULLDUMP; sigaction(SIGSEGV, &nsa, NULL); #endif whoami = argv[0]; initialize_PT_error_table(); strcpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH); cell = 0; n = 1; while (n < argc) { int arglen = strlen(argv[n]); char arg[256]; lcstring(arg, argv[n], sizeof(arg)); #define IsArg(a) (strncmp (arg,a, arglen) == 0) if (IsArg("-testconfdir")) strncpy(confdir, argv[++n], sizeof(confdir)); else if (IsArg("client")) strncpy(confdir, AFSDIR_CLIENT_ETC_DIRPATH, sizeof(confdir)); else if (IsArg("server")) strncpy(confdir, AFSDIR_SERVER_ETC_DIRPATH, sizeof(confdir)); else if (IsArg("0") || IsArg("1") || IsArg("2")) security = atoi(argv[n]); else if (IsArg("-ignoreexist")) ignoreExist++; else if (IsArg("-cell")) cell = argv[++n]; else { printf ("Usage is: 'prclient [-testconfdir <dir> | server | client] [0 | 1 | 2] [-ignoreExist] [-cell <cellname>]\n"); exit(1); } n++; } printf("Using CellServDB file in %s\n", confdir); if (security == 0) printf("Making unauthenticated connection to prserver\n"); code = pr_Initialize(security, confdir, cell); if (code) { afs_com_err(whoami, code, "Couldn't initialize protection library"); exit(1); } while (1) { char *s; printf("pr> "); s = fgets(line, sizeof(line), stdin); if (s == NULL) break; lineProgress = 0; code = GetString(op, sizeof(op)); if (code) { afs_com_err(whoami, PRBADARG, "error reading opcode in line '%s', got '%.*s'", line, sizeof(op), op); exit(1); } if (strlen(op) == 0) continue; /* no input */ if (!strcmp(op, "cr")) { if (GetString(name, sizeof(name)) || GetInt32(&id) || GetInt32(&oid)) code = PRBADARG; /* use ubik_Call to do the work, finding an up server and handling * the job of finding a sync site, if need be */ else code = ubik_PR_INewEntry(pruclient, 0, name, id, oid); if (CodeOk(code)) afs_com_err(whoami, code, "on %s %s %d %d", op, name, id, oid); } else if (!strcmp(op, "sf")) { afs_int32 mask, access, gq, uq; if (GetInt32(&id) || GetXInt32(&mask) || GetXInt32(&access) || GetInt32(&gq) || GetInt32(&uq)) code = PRBADARG; else code = ubik_PR_SetFieldsEntry(pruclient, 0, id, mask, access, gq, uq, 0, 0); if (CodeOk(code)) afs_com_err(whoami, code, "on %s %d %x %x %d %d", op, id, mask, access, gq, uq); } else if (!strcmp(op, "ce")) { char newname[PR_MAXNAMELEN]; afs_int32 newid; if (GetInt32(&id) || GetString(newname, sizeof(newname)) || GetInt32(&oid) || GetInt32(&newid)) code = PRBADARG; else code = ubik_PR_ChangeEntry(pruclient, 0, id, newname, oid, newid); if (CodeOk(code)) afs_com_err(whoami, code, "on %s %d %s %d %d", op, id, newname, oid, newid); } else if (!strcmp(op, "wh")) { /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = ubik_PR_WhereIsIt(pruclient, 0, id, &pos); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); else printf("location %d\n", pos); } else if (!strcmp(op, "du")) { memset(&entry, 0, sizeof(entry)); /* scanf("%d",&pos); */ if (GetInt32(&pos)) code = PRBADARG; else code = ubik_PR_DumpEntry(pruclient, 0, pos, (struct prdebugentry *)&entry); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) { PrintEntry(pos, &entry, /*indent */ 0); #if 0 printf("The contents of the entry for %d are:\n", entry.id); printf("flags %d next %d\n", entry.flags, entry.next); printf("Groups (or members) \n"); for (i = 0; i < PRSIZE; i++) printf("%d\n", entry.entries[i]); printf("nextID %d nextname %d name %s\n", entry.nextID, entry.nextName, entry.name); printf("owner %d creator %d\n", entry.owner, entry.creator); #endif } } else if (!strcmp(op, "add") || !strcmp(op, "au")) { /* scanf("%d %d",&id,&gid); */ if (GetInt32(&id) || GetInt32(&gid)) code = PRBADARG; else code = ubik_PR_AddToGroup(pruclient, 0, id, gid); if (CodeOk(code)) afs_com_err(whoami, code, "on %s %d %d", op, id, gid); } else if (!strcmp(op, "iton")) { lid.idlist_val = (afs_int32 *) malloc(20 * sizeof(afs_int32)); ptr = lid.idlist_val; lid.idlist_len = 0; foo = line; skip(&foo); while ((lid.idlist_len < 20) && (sscanf(foo, "%d", ptr) != EOF)) { lid.idlist_len++; skip(&foo); ptr++; } if (*foo) { fprintf(stderr, "too many values specified; max is %d\n", 20); } lnames.namelist_val = 0; lnames.namelist_len = 0; code = ubik_PR_IDToName(pruclient, 0, &lid, &lnames); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) { for (i = 0; i < lnames.namelist_len; i++) { printf("id %d name %s\n", lid.idlist_val[i], lnames.namelist_val[i]); } free(lnames.namelist_val); } free(lid.idlist_val); lid.idlist_val = 0; lid.idlist_len = 0; } else if (!strcmp(op, "ntoi")) { lnames.namelist_val = (prname *) malloc(PR_MAXLIST * PR_MAXNAMELEN); lnames.namelist_len = 0; foo = line; skip(&foo); for (i = 0; ((lnames.namelist_len < PR_MAXLIST) && (sscanf(foo, "%s", lnames.namelist_val[i]) != EOF)); i++) { lnames.namelist_len++; skip(&foo); } if (*foo) { fprintf(stderr, "too many values specified; max is %d\n", PR_MAXLIST); } lid.idlist_val = 0; lid.idlist_len = 0; code = ubik_PR_NameToID(pruclient, 0, &lnames, &lid); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) { for (i = 0; i < lid.idlist_len; i++) printf("name %s id %d\n", lnames.namelist_val[i], lid.idlist_val[i]); free(lid.idlist_val); } free(lnames.namelist_val); lnames.namelist_val = 0; lnames.namelist_len = 0; } else if (!strcmp(op, "del")) { /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = ubik_PR_Delete(pruclient, 0, id); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); } else if (!strcmp(op, "dg")) { /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = ubik_PR_Delete(pruclient, 0, id); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); } else if (!strcmp(op, "rm")) { /* scanf("%d %d",&id,&gid); */ if (GetInt32(&id) || GetInt32(&gid)) code = PRBADARG; else code = ubik_PR_RemoveFromGroup(pruclient, 0, id, gid); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); } #if defined(SUPERGROUPS) else if (!strcmp(op, "lsg")) { alist.prlist_len = 0; alist.prlist_val = 0; /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = ubik_PR_ListSuperGroups(pruclient, 0, id, &alist, &over); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) { ptr = alist.prlist_val; if (over) { printf("Number of groups greater than PR_MAXGROUPS!\n"); printf("Excess of %d.\n", over); } for (i = 0; i < alist.prlist_len; i++, ptr++) printf("%d\n", *ptr); free(alist.prlist_val); alist.prlist_len = 0; alist.prlist_val = 0; } } #endif /* SUPERGROUPS */ else if (!strcmp(op, "l")) { alist.prlist_len = 0; alist.prlist_val = 0; /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = ubik_PR_GetCPS(pruclient, 0, id, &alist, &over); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) { ptr = alist.prlist_val; if (over) { printf("Number of groups greater than PR_MAXGROUPS!\n"); printf("Excess of %d.\n", over); } for (i = 0; i < alist.prlist_len; i++, ptr++) printf("%d\n", *ptr); free(alist.prlist_val); alist.prlist_len = 0; alist.prlist_val = 0; } } else if (!strcmp(op, "lh")) { alist.prlist_len = 0; alist.prlist_val = 0; /* scanf("%d",&id); */ if (GetString(name, sizeof(name))) code = PRBADARG; else if (!(hostinfo = gethostbyname(name))) code = PRBADARG; else { hostaddr = (struct in_addr *)hostinfo->h_addr_list[0]; id = ntohl(hostaddr->s_addr); code = ubik_PR_GetHostCPS(pruclient, 0, id, &alist, &over); } if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) { ptr = alist.prlist_val; if (over) { printf("Number of groups greater than PR_MAXGROUPS!\n"); printf("Excess of %d.\n", over); } for (i = 0; i < alist.prlist_len; i++, ptr++) printf("%d\n", *ptr); free(alist.prlist_val); alist.prlist_len = 0; alist.prlist_val = 0; } } #if defined(SUPERGROUPS) else if (!strcmp(op, "m")) { alist.prlist_len = 0; alist.prlist_val = 0; /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = ubik_PR_ListElements(pruclient, 0, id, &alist, &over); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) { ptr = alist.prlist_val; if (over) { printf("Number of groups greater than PR_MAXGROUPS!\n"); printf("Excess of %d.\n", over); } for (i = 0; i < alist.prlist_len; i++, ptr++) printf("%d\n", *ptr); free(alist.prlist_val); alist.prlist_len = 0; alist.prlist_val = 0; } } #endif /* SUPERGROUPS */ else if (!strcmp(op, "nu")) { /* scanf("%s",name); */ if (GetString(name, sizeof(name))) code = PRBADARG; else code = pr_CreateUser(name, &id); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) printf("Id is %d.\n", id); } else if (!strcmp(op, "ng")) { /* scanf("%s",name); */ if (GetString(name, sizeof(name))) code = PRBADARG; else code = ubik_PR_NewEntry(pruclient, 0, name, 1, oid, &id); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) printf("Id is %d.\n", id); } else if (!strcmp(op, "lm")) { code = ubik_PR_ListMax(pruclient, 0, &id, &gid); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) printf("Max user id is %d, max (really min) group is %d.\n", id, gid); } else if (!strcmp(op, "smu")) { /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = ubik_PR_SetMax(pruclient, 0, id, 0); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); } else if (!strcmp(op, "smg")) { /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = ubik_PR_SetMax(pruclient, 0, id, 1); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); } else if (!strcmp(op, "sin")) { /* scanf("%d",&id); */ if (GetInt32(&id)) code = PRBADARG; else code = pr_SIdToName(id, name); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) printf("id %d name %s\n", id, name); } else if (!strcmp(op, "sni")) { /* scanf("%s",name); */ if (GetString(name, sizeof(name))) code = PRBADARG; else code = pr_SNameToId(name, &id); if (CodeOk(code)) printf("%s\n", pr_ErrorMsg(code)); if (code == PRSUCCESS) printf("name %s id %d\n", name, id); } else if (!strcmp(op, "fih")) { char tname[128]; struct PrUpdateEntry uentry; memset(&uentry, 0, sizeof(uentry)); /* scanf("%s",name); */ if (GetString(name, sizeof(name))) { code = PRBADARG; continue; } code = pr_SNameToId(name, &id); if (CodeOk(code)) { printf("%s\n", pr_ErrorMsg(code)); continue; } code = pr_SIdToName(id, tname); if (code == PRSUCCESS) { printf ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n", name, id); /* continue;*/ } uentry.Mask = PRUPDATE_IDHASH; code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry); if (code) { printf("Failed to update entry %s (err=%d)\n", name, code); continue; } } else if (!strcmp(op, "fnh")) { int tid; struct PrUpdateEntry uentry; memset(&uentry, 0, sizeof(uentry)); /* scanf("%d", &id); */ if (GetInt32(&id)) { code = PRBADARG; continue; } code = pr_SIdToName(id, name); if (CodeOk(code)) { printf("%s\n", pr_ErrorMsg(code)); continue; } code = pr_SNameToId(name, &tid); if (code == PRSUCCESS) { printf ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n", id, name); /* continue;*/ } uentry.Mask = PRUPDATE_NAMEHASH; code = ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry); if (code) { printf("Failed to update entry with id %d (err=%d)\n", id, code); continue; } } #if defined(SUPERGROUPS) else if (!strcmp(op, "fih")) { char tname[128]; struct PrUpdateEntry uentry; memset(&uentry, 0, sizeof(uentry)); /* scanf("%s",name); */ if (GetString(name, sizeof(name))) { code = PRBADARG; continue; } code = pr_SNameToId(name, &id); if (CodeOk(code)) { printf("%s\n", pr_ErrorMsg(code)); continue; } code = pr_SIdToName(id, tname); if (code == PRSUCCESS) { printf ("Warning: Id hash for %s (id %d) seems correct at the db; rehashing it anyway\n", name, id); /* continue;*/ } uentry.Mask = PRUPDATE_IDHASH; code = ubik_PR_UpdateEntry(pruclient, 0, 0, name, &uentry); if (code) { printf("Failed to update entry %s (err=%d)\n", name, code); continue; } } else if (!strcmp(op, "fnh")) { int tid; struct PrUpdateEntry uentry; memset(&uentry, 0, sizeof(uentry)); /* scanf("%d", &id); */ if (GetInt32(&id)) { code = PRBADARG; continue; } code = pr_SIdToName(id, name); if (CodeOk(code)) { printf("%s\n", pr_ErrorMsg(code)); continue; } code = pr_SNameToId(name, &tid); if (code == PRSUCCESS) { printf ("Name hash for %d (name is %s) seems correct at the db; rehashing it anyway\n", id, name); /* continue;*/ } uentry.Mask = PRUPDATE_NAMEHASH; code = ubik_PR_UpdateEntry(pruclient, 0, id, "_foo_", &uentry); if (code) { printf("Failed to update entry with id %d (err=%d)\n", id, code); continue; } } #endif /* SUPERGROUPS */ else if (!strcmp(op, "?")) PrintHelp(); else if (!strcmp(op, "q")) exit(0); else printf("Unknown op: '%s'! ? for help\n", op); } }
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); }