static int GetCellUnix(struct afsconf_dir *adir) { char *rc; char tbuffer[256]; char *start, *p; afsconf_FILE *fp; strcompose(tbuffer, 256, adir->name, "/", AFSDIR_THISCELL_FILE, (char *)NULL); fp = fopen(tbuffer, "r"); if (fp == 0) { return -1; } rc = fgets(tbuffer, 256, fp); fclose(fp); if (rc == NULL) return -1; start = tbuffer; while (*start != '\0' && isspace(*start)) start++; p = start; while (*p != '\0' && !isspace(*p)) p++; *p = '\0'; if (*start == '\0') return -1; adir->cellName = strdup(start); return 0; }
/* returns true iff user is in the UserList file */ static int FindUser(struct afsconf_dir *adir, register char *auser) { char tbuffer[256]; register bufio_p bp; char tname[64 + 1]; register int flag; register afs_int32 code; int rc; strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL); bp = BufioOpen(tbuffer, O_RDONLY, 0); if (!bp) return 0; flag = 0; while (1) { /* check for our user id */ rc = BufioGets(bp, tbuffer, sizeof(tbuffer)); if (rc < 0) break; code = sscanf(tbuffer, "%64s", tname); if (code == 1 && strcmp(tname, auser) == 0) { flag = 1; break; } } BufioClose(bp); return flag; }
/* add a user to the user list, checking for duplicates */ int afsconf_AddUser(struct afsconf_dir *adir, char *aname) { FILE *tf; register afs_int32 code; char tbuffer[256]; LOCK_GLOBAL_MUTEX; if (FindUser(adir, aname)) { UNLOCK_GLOBAL_MUTEX; return EEXIST; /* already in the list */ } strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL); tf = fopen(tbuffer, "a+"); if (!tf) { UNLOCK_GLOBAL_MUTEX; return EIO; } fprintf(tf, "%s\n", aname); code = 0; if (ferror(tf)) code = EIO; if (fclose(tf)) code = EIO; UNLOCK_GLOBAL_MUTEX; return code; }
/* save the key structure in the appropriate file */ static int SaveKeys(struct afsconf_dir *adir) { struct afsconf_keys tkeys; int fd; afs_int32 i; char tbuffer[256]; memcpy(&tkeys, adir->keystr, sizeof(struct afsconf_keys)); /* convert it to net byte order */ for (i = 0; i < tkeys.nkeys; i++) tkeys.key[i].kvno = htonl(tkeys.key[i].kvno); tkeys.nkeys = htonl(tkeys.nkeys); /* rewrite keys file */ strcompose(tbuffer, 256, adir->name, "/", AFSDIR_KEY_FILE, NULL); fd = open(tbuffer, O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd < 0) return AFSCONF_FAILURE; i = write(fd, &tkeys, sizeof(tkeys)); if (i != sizeof(tkeys)) { close(fd); return AFSCONF_FAILURE; } if (close(fd) < 0) return AFSCONF_FAILURE; return 0; }
static void UserListFileName(struct afsconf_dir *adir, char *buffer, size_t len) { strcompose(buffer, len, adir->name, "/", AFSDIR_ULIST_FILE, NULL); }
static int afsconf_Check(struct afsconf_dir *adir) { char tbuffer[256]; #ifdef AFS_NT40_ENV char *p; #endif struct stat tstat; afs_int32 code; #ifdef AFS_NT40_ENV /* NT client CellServDB has different file name than NT server or Unix */ if (IsClientConfigDirectory(adir->name)) { if (!afssw_GetClientCellServDBDir(&p)) { strcompose(tbuffer, sizeof(tbuffer), p, "/", AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL); free(p); } else { int len; strncpy(tbuffer, adir->name, sizeof(tbuffer)); len = (int)strlen(tbuffer); if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') { strncat(tbuffer, "\\", sizeof(tbuffer)); } strncat(tbuffer, AFSDIR_CELLSERVDB_FILE_NTCLIENT, sizeof(tbuffer)); tbuffer[sizeof(tbuffer) - 1] = '\0'; } } else { strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE, NULL); } #else strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE, NULL); #endif /* AFS_NT40_ENV */ code = stat(tbuffer, &tstat); if (code < 0) { return code; } /* did file change? */ if (tstat.st_mtime == adir->timeRead) { return 0; } /* otherwise file has changed, so reopen it */ return afsconf_Reopen(adir); }
/* called during opening of config file */ int afsconf_IntGetKeys(struct afsconf_dir *adir) { char tbuffer[256]; int fd; struct afsconf_keys *tstr; afs_int32 code; #ifdef AFS_NT40_ENV /* NT client config dir has no KeyFile; don't risk attempting open * because there might be a random file of this name if dir is shared. */ if (IsClientConfigDirectory(adir->name)) { adir->keystr = ((struct afsconf_keys *) malloc(sizeof(struct afsconf_keys))); adir->keystr->nkeys = 0; return 0; } #endif /* AFS_NT40_ENV */ LOCK_GLOBAL_MUTEX; /* compute the key name and other setup */ strcompose(tbuffer, 256, adir->name, "/", AFSDIR_KEY_FILE, NULL); tstr = (struct afsconf_keys *)malloc(sizeof(struct afsconf_keys)); adir->keystr = tstr; /* read key file */ fd = open(tbuffer, O_RDONLY); if (fd < 0) { tstr->nkeys = 0; UNLOCK_GLOBAL_MUTEX; return 0; } code = read(fd, tstr, sizeof(struct afsconf_keys)); close(fd); if (code < sizeof(afs_int32)) { tstr->nkeys = 0; UNLOCK_GLOBAL_MUTEX; return 0; } /* convert key structure to host order */ tstr->nkeys = ntohl(tstr->nkeys); if (code < sizeof(afs_int32) + (tstr->nkeys*sizeof(struct afsconf_key))) { tstr->nkeys = 0; UNLOCK_GLOBAL_MUTEX; return 0; } for (fd = 0; fd < tstr->nkeys; fd++) tstr->key[fd].kvno = ntohl(tstr->key[fd].kvno); UNLOCK_GLOBAL_MUTEX; return 0; }
/* set modtime on file */ static int afsconf_Touch(struct afsconf_dir *adir) { char tbuffer[256]; #ifndef AFS_NT40_ENV struct timeval tvp[2]; #else char *p; #endif adir->timeRead = 0; /* just in case */ #ifdef AFS_NT40_ENV /* NT client CellServDB has different file name than NT server or Unix */ if (IsClientConfigDirectory(adir->name)) { if (!afssw_GetClientCellServDBDir(&p)) { strcompose(tbuffer, sizeof(tbuffer), p, "/", AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL); free(p); } else { int len = (int)strlen(tbuffer); if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') { strncat(tbuffer, "\\", sizeof(tbuffer)); } strncat(tbuffer, AFSDIR_CELLSERVDB_FILE_NTCLIENT, sizeof(tbuffer)); tbuffer[sizeof(tbuffer) - 1] = '\0'; } } else { strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE, NULL); } return _utime(tbuffer, NULL); #else strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE, NULL); gettimeofday(&tvp[0], NULL); tvp[1] = tvp[0]; return utimes(tbuffer, tvp); #endif /* AFS_NT40_ENV */ }
/** * fill in sockaddr structure. * * @param[in] endpoint pointer to sync endpoint object * @param[out] addr pointer to sockaddr structure * * @post sockaddr structure populated using information from * endpoint structure. */ void SYNC_getAddr(SYNC_endpoint_t * endpoint, SYNC_sockaddr_t * addr) { #ifdef USE_UNIX_SOCKETS char tbuffer[AFSDIR_PATH_MAX]; #endif /* USE_UNIX_SOCKETS */ memset(addr, 0, sizeof(*addr)); #ifdef USE_UNIX_SOCKETS strcompose(tbuffer, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH, "/", endpoint->un, NULL); addr->sun_family = AF_UNIX; strncpy(addr->sun_path, tbuffer, (sizeof(struct sockaddr_un) - sizeof(short))); #else /* !USE_UNIX_SOCKETS */ #ifdef STRUCT_SOCKADDR_HAS_SA_LEN addr->sin_len = sizeof(struct sockaddr_in); #endif addr->sin_addr.s_addr = htonl(0x7f000001); addr->sin_family = AF_INET; /* was localhost->h_addrtype */ addr->sin_port = htons(endpoint->in); /* XXXX htons not _really_ neccessary */ #endif /* !USE_UNIX_SOCKETS */ }
/* returns nth super user from the UserList file */ int afsconf_GetNthUser(struct afsconf_dir *adir, afs_int32 an, char *abuffer, afs_int32 abufferLen) { char tbuffer[256]; register FILE *tf; char tname[64 + 1]; register char *tp; register int flag; register afs_int32 code; LOCK_GLOBAL_MUTEX; strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL); tf = fopen(tbuffer, "r"); if (!tf) { UNLOCK_GLOBAL_MUTEX; return 1; } flag = 1; while (1) { /* check for our user id */ tp = fgets(tbuffer, sizeof(tbuffer), tf); if (tp == NULL) break; code = sscanf(tbuffer, "%64s", tname); if (code == 1 && an-- == 0) { flag = 0; break; } } if (flag == 0) strcpy(abuffer, tname); fclose(tf); UNLOCK_GLOBAL_MUTEX; return flag; }
/** * Load the cell configuration into memory. * * Read the cell configuration into a newly allocated or cleared afsconf_dir * structure. Reads the CellServDB file, and if present, the cell alias file, * the key files, and kerberos related files. * * If the configuration cannot be loaded for any reason, any partial changes * are freed. The name member is preserved. * * @param[in,out] adir pointer to the cell configuration * the name member must be set to the pathname of the * cell configuration to be loaded. All other members * must be unassigned. * * @returns 0 on success */ static int LoadConfig(struct afsconf_dir *adir) { afsconf_FILE *tf; char *tp, *bp; struct afsconf_entry *curEntry; struct afsconf_aliasentry *curAlias; afs_int32 code; afs_int32 i; char tbuffer[256]; struct stat tstat; #ifdef AFS_NT40_ENV cm_enumCellRegistry_t enumCellRegistry = {0, 0}; #endif /* AFS_NT40_ENV */ /* init the keys queue before any call to UnloadConfig() */ _afsconf_InitKeys(adir); /* figure out the local cell name */ #ifdef AFS_NT40_ENV i = GetCellNT(adir); enumCellRegistry.adir = adir; #else i = GetCellUnix(adir); #endif #ifndef AFS_FREELANCE_CLIENT /* no local cell not fatal in freelance */ if (i) { return i; } #endif /* now parse the individual lines */ curEntry = 0; _afsconf_CellServDBPath(adir, &adir->cellservDB); #ifdef AFS_NT40_ENV if (_afsconf_IsClientConfigDirectory(adir->name)) enumCellRegistry.client = 1; #endif /* AFS_NT40_ENV */ if (!stat(adir->cellservDB, &tstat)) { adir->timeRead = tstat.st_mtime; } else { adir->timeRead = 0; } tf = fopen(adir->cellservDB, "r"); if (!tf) { return -1; } /* The CellServDB file is now open. * The following code parses the contents of the * file and creates a list with the first cell entry * in the CellServDB file at the end of the list. * * No checking is performed for duplicates. * The side effects of this process are that duplicate * entries appended to the end of the CellServDB file * take precedence and are found in a shorter period * of time. */ while (1) { tp = fgets(tbuffer, sizeof(tbuffer), tf); if (!tp) break; TrimLine(tbuffer, sizeof tbuffer); /* remove white space */ if (tbuffer[0] == 0 || tbuffer[0] == '\n') continue; /* empty line */ if (tbuffer[0] == '>') { char linkedcell[MAXCELLCHARS]; /* start new cell item */ if (curEntry) { /* thread this guy on the list */ curEntry->next = adir->entries; adir->entries = curEntry; curEntry = 0; } curEntry = calloc(1, sizeof(struct afsconf_entry)); code = ParseCellLine(tbuffer, curEntry->cellInfo.name, linkedcell); if (code) { UnloadConfig(adir); fclose(tf); free(curEntry); return -1; } if (linkedcell[0] != '\0') curEntry->cellInfo.linkedCell = strdup(linkedcell); } else { /* new host in the current cell */ if (!curEntry) { UnloadConfig(adir); fclose(tf); return -1; } i = curEntry->cellInfo.numServers; if (i < MAXHOSTSPERCELL) { code = ParseHostLine(tbuffer, &curEntry->cellInfo.hostAddr[i], curEntry->cellInfo.hostName[i], &curEntry->cellInfo.clone[i]); if (code) { if (code == AFSCONF_SYNTAX) { for (bp = tbuffer; *bp != '\n'; bp++) { /* Take out the <cr> from the buffer */ if (!*bp) break; } *bp = '\0'; fprintf(stderr, "Can't properly parse host line \"%s\" in configuration file %s\n", tbuffer, adir->cellservDB); } free(curEntry); fclose(tf); UnloadConfig(adir); return -1; } curEntry->cellInfo.numServers = ++i; } else { fprintf(stderr, "Too many hosts for cell %s in configuration file %s\n", curEntry->cellInfo.name, adir->cellservDB); } } } fclose(tf); /* close the file now */ /* end the last partially-completed cell */ if (curEntry) { curEntry->next = adir->entries; adir->entries = curEntry; } #ifdef AFS_NT40_ENV /* * Windows maintains a CellServDB list in the Registry * that supercedes the contents of the CellServDB file. * Prepending these entries to the head of the list * is sufficient to enforce the precedence. */ cm_EnumerateCellRegistry( enumCellRegistry.client, cm_enumCellRegistryProc, &enumCellRegistry); #endif /* AFS_NT40_ENV */ /* Read in the alias list */ strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLALIAS_FILE, (char *)NULL); tf = fopen(tbuffer, "r"); while (tf) { char *aliasPtr; tp = fgets(tbuffer, sizeof(tbuffer), tf); if (!tp) break; TrimLine(tbuffer, sizeof tbuffer); /* remove white space */ if (tbuffer[0] == '\0' || tbuffer[0] == '\n' || tbuffer[0] == '#') continue; /* empty line */ tp = tbuffer; while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t') tp++; if (tp[0] == '\0') continue; /* invalid line */ while (tp[0] != '\0' && (tp[0] == ' ' || tp[0] == '\t')) 0[tp++] = '\0'; if (tp[0] == '\0') continue; /* invalid line */ aliasPtr = tp; while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t' && tp[0] != '\r' && tp[0] != '\n') tp++; tp[0] = '\0'; curAlias = calloc(1, sizeof(*curAlias)); strlcpy(curAlias->aliasInfo.aliasName, aliasPtr, sizeof curAlias->aliasInfo.aliasName); strlcpy(curAlias->aliasInfo.realName, tbuffer, sizeof curAlias->aliasInfo.realName); curAlias->next = adir->alias_entries; adir->alias_entries = curAlias; } if (tf != NULL) fclose(tf); /* now read the fs keys, if possible */ code = _afsconf_LoadKeys(adir); if (code) { return code; } code = _afsconf_LoadRealms(adir); return code; }
/* deletes a user from the UserList file */ int afsconf_DeleteUser(struct afsconf_dir *adir, register char *auser) { char tbuffer[1024]; char nbuffer[1024]; register FILE *tf; register FILE *nf; register int flag; char tname[64 + 1]; char *tp; int found; struct stat tstat; register afs_int32 code; LOCK_GLOBAL_MUTEX; strcompose(tbuffer, sizeof tbuffer, adir->name, "/", AFSDIR_ULIST_FILE, NULL); #ifndef AFS_NT40_ENV { /* * We attempt to fully resolve this pathname, so that the rename * of the temporary file will work even if UserList is a symlink * into a different filesystem. */ char resolved_path[1024]; if (realpath(tbuffer, resolved_path)) { strcpy(tbuffer, resolved_path); } } #endif /* AFS_NT40_ENV */ tf = fopen(tbuffer, "r"); if (!tf) { UNLOCK_GLOBAL_MUTEX; return -1; } code = stat(tbuffer, &tstat); if (code < 0) { UNLOCK_GLOBAL_MUTEX; return code; } strcpy(nbuffer, tbuffer); strcat(nbuffer, ".NXX"); nf = fopen(nbuffer, "w+"); if (!nf) { fclose(tf); UNLOCK_GLOBAL_MUTEX; return EIO; } flag = 0; found = 0; while (1) { /* check for our user id */ tp = fgets(nbuffer, sizeof(nbuffer), tf); if (tp == NULL) break; code = sscanf(nbuffer, "%64s", tname); if (code == 1 && strcmp(tname, auser) == 0) { /* found the guy, don't copy to output file */ found = 1; } else { /* otherwise copy original line to output */ fprintf(nf, "%s", nbuffer); } } fclose(tf); if (ferror(nf)) flag = 1; if (fclose(nf) == EOF) flag = 1; strcpy(nbuffer, tbuffer); strcat(nbuffer, ".NXX"); /* generate new file name again */ if (flag == 0) { /* try the rename */ flag = renamefile(nbuffer, tbuffer); if (flag == 0) flag = chmod(tbuffer, tstat.st_mode); } else unlink(nbuffer); /* finally, decide what to return to the caller */ UNLOCK_GLOBAL_MUTEX; if (flag) return EIO; /* something mysterious went wrong */ if (!found) return ENOENT; /* entry wasn't found, no changes made */ return 0; /* everything was fine */ }
int main(int argc, char **argv) { struct cmd_syndesc *ts; struct cmd_item *ti; #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); sigaction(SIGABRT, &nsa, NULL); #endif setlinebuf(stdout); ts = cmd_CreateSyntax(NULL, WorkerBee, NULL, "tape coordinator"); cmd_AddParm(ts, "-port", CMD_SINGLE, CMD_OPTIONAL, "port offset"); cmd_AddParm(ts, "-debuglevel", CMD_SINGLE, CMD_OPTIONAL, "0 | 1 | 2"); cmd_AddParm(ts, "-cell", CMD_SINGLE, CMD_OPTIONAL, "cell name"); cmd_AddParm(ts, "-device", CMD_SINGLE, (CMD_OPTIONAL | CMD_HIDE), "tape device path"); cmd_AddParm(ts, "-noautoquery", CMD_FLAG, CMD_OPTIONAL, "do not query operator for first tape"); cmd_AddParm(ts, "-localauth", CMD_FLAG, CMD_OPTIONAL, "create tickets from KeyFile"); cmd_AddParm(ts, "-restoretofile", CMD_SINGLE, (CMD_OPTIONAL | CMD_HIDE), "file to restore to"); cmd_AddParm(ts, "-xbsaforcemultiple", CMD_FLAG, (CMD_OPTIONAL | CMD_HIDE), "Force multiple XBSA server support"); cmd_AddParm(ts, "-rxbind", CMD_FLAG, CMD_OPTIONAL, "bind Rx socket"); /* 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, "Unable to obtain AFS server directory.\n"); exit(2); } /* setup the file paths */ strcompose(eFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", TE_PREFIX, NULL); strcompose(lFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", TL_PREFIX, NULL); strcompose(pFile, AFSDIR_PATH_MAX, AFSDIR_SERVER_BACKUP_DIRPATH, "/", CFG_PREFIX, NULL); strcpy(tapeConfigFile, AFSDIR_SERVER_TAPECONFIG_FILEPATH); /* special case "no args" case since cmd_dispatch gives help message * instead */ if (argc == 1) { ts = (struct cmd_syndesc *)malloc(sizeof(struct cmd_syndesc)); memset(ts, 0, sizeof(*ts)); ti = (struct cmd_item *)malloc(sizeof(struct cmd_item)); ti->next = 0; ti->data = "0"; ts->parms[0].items = ti; ti = (struct cmd_item *)malloc(sizeof(struct cmd_item)); ti->next = 0; ti->data = "0"; ts->parms[1].items = ti; ts->parms[2].items = (struct cmd_item *)NULL; ts->parms[3].items = (struct cmd_item *)NULL; ts->parms[4].items = (struct cmd_item *)NULL; ts->parms[5].items = (struct cmd_item *)NULL; return WorkerBee(ts, NULL); } else return cmd_Dispatch(argc, argv); }
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; }
static int afsconf_OpenInternal(struct afsconf_dir *adir, char *cell, char clones[]) { afsconf_FILE *tf; char *tp, *bp; struct afsconf_entry *curEntry; struct afsconf_aliasentry *curAlias; afs_int32 code; afs_int32 i; char tbuffer[256], tbuf1[256]; struct stat tstat; #ifdef AFS_NT40_ENV cm_enumCellRegistry_t enumCellRegistry = {0, 0}; #endif /* AFS_NT40_ENV */ /* figure out the local cell name */ #ifdef AFS_NT40_ENV i = GetCellNT(adir); enumCellRegistry.adir = adir; #else i = GetCellUnix(adir); #endif #ifndef AFS_FREELANCE_CLIENT /* no local cell not fatal in freelance */ if (i) { return i; } #endif /* now parse the individual lines */ curEntry = 0; #ifdef AFS_NT40_ENV /* NT client/server have a CellServDB that is the same format as Unix. * However, the NT client uses a different file name */ if (IsClientConfigDirectory(adir->name)) { /* NT client config dir */ char *p; enumCellRegistry.client = 1; if (!afssw_GetClientCellServDBDir(&p)) { strcompose(tbuffer, sizeof(tbuffer), p, "/", AFSDIR_CELLSERVDB_FILE_NTCLIENT, NULL); free(p); } else { int len; strncpy(tbuffer, adir->name, sizeof(tbuffer)); len = (int)strlen(tbuffer); if (tbuffer[len - 1] != '\\' && tbuffer[len - 1] != '/') { strncat(tbuffer, "\\", sizeof(tbuffer)); } strncat(tbuffer, AFSDIR_CELLSERVDB_FILE_NTCLIENT, sizeof(tbuffer)); tbuffer[sizeof(tbuffer) - 1] = '\0'; } } else { /* NT server config dir */ strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE, NULL); } #else strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLSERVDB_FILE, NULL); #endif /* AFS_NT40_ENV */ if (!stat(tbuffer, &tstat)) { adir->timeRead = tstat.st_mtime; } else { adir->timeRead = 0; } strlcpy(tbuf1, tbuffer, sizeof tbuf1); tf = fopen(tbuffer, "r"); if (!tf) { return -1; } /* The CellServDB file is now open. * The following code parses the contents of the * file and creates a list with the first cell entry * in the CellServDB file at the end of the list. * * No checking is performed for duplicates. * The side effects of this process are that duplicate * entries appended to the end of the CellServDB file * take precedence and are found in a shorter period * of time. */ while (1) { tp = fgets(tbuffer, sizeof(tbuffer), tf); if (!tp) break; TrimLine(tbuffer, sizeof tbuffer); /* remove white space */ if (tbuffer[0] == 0 || tbuffer[0] == '\n') continue; /* empty line */ if (tbuffer[0] == '>') { char linkedcell[MAXCELLCHARS]; /* start new cell item */ if (curEntry) { /* thread this guy on the list */ curEntry->next = adir->entries; adir->entries = curEntry; curEntry = 0; } curEntry = (struct afsconf_entry *)malloc(sizeof(struct afsconf_entry)); memset(curEntry, 0, sizeof(struct afsconf_entry)); code = ParseCellLine(tbuffer, curEntry->cellInfo.name, linkedcell); if (code) { afsconf_CloseInternal(adir); fclose(tf); free(curEntry); return -1; } if (linkedcell[0] != '\0') curEntry->cellInfo.linkedCell = strdup(linkedcell); } else { /* new host in the current cell */ if (!curEntry) { afsconf_CloseInternal(adir); fclose(tf); return -1; } i = curEntry->cellInfo.numServers; if (i < MAXHOSTSPERCELL) { if (cell && !strcmp(cell, curEntry->cellInfo.name)) code = ParseHostLine(tbuffer, &curEntry->cellInfo.hostAddr[i], curEntry->cellInfo.hostName[i], &clones[i]); else code = ParseHostLine(tbuffer, &curEntry->cellInfo.hostAddr[i], curEntry->cellInfo.hostName[i], 0); if (code) { if (code == AFSCONF_SYNTAX) { for (bp = tbuffer; *bp != '\n'; bp++) { /* Take out the <cr> from the buffer */ if (!*bp) break; } *bp = '\0'; fprintf(stderr, "Can't properly parse host line \"%s\" in configuration file %s\n", tbuffer, tbuf1); } free(curEntry); fclose(tf); afsconf_CloseInternal(adir); return -1; } curEntry->cellInfo.numServers = ++i; } else { fprintf(stderr, "Too many hosts for cell %s in configuration file %s\n", curEntry->cellInfo.name, tbuf1); } } } fclose(tf); /* close the file now */ /* end the last partially-completed cell */ if (curEntry) { curEntry->next = adir->entries; adir->entries = curEntry; } #ifdef AFS_NT40_ENV /* * Windows maintains a CellServDB list in the Registry * that supercedes the contents of the CellServDB file. * Prepending these entries to the head of the list * is sufficient to enforce the precedence. */ cm_EnumerateCellRegistry( enumCellRegistry.client, cm_enumCellRegistryProc, &enumCellRegistry); #endif /* AFS_NT40_ENV */ /* Read in the alias list */ strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLALIAS_FILE, NULL); tf = fopen(tbuffer, "r"); while (tf) { char *aliasPtr; tp = fgets(tbuffer, sizeof(tbuffer), tf); if (!tp) break; TrimLine(tbuffer, sizeof tbuffer); /* remove white space */ if (tbuffer[0] == '\0' || tbuffer[0] == '\n' || tbuffer[0] == '#') continue; /* empty line */ tp = tbuffer; while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t') tp++; if (tp[0] == '\0') continue; /* invalid line */ while (tp[0] != '\0' && (tp[0] == ' ' || tp[0] == '\t')) 0[tp++] = '\0'; if (tp[0] == '\0') continue; /* invalid line */ aliasPtr = tp; while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t' && tp[0] != '\r' && tp[0] != '\n') tp++; tp[0] = '\0'; curAlias = malloc(sizeof(*curAlias)); memset(curAlias, 0, sizeof(*curAlias)); strlcpy(curAlias->aliasInfo.aliasName, aliasPtr, sizeof curAlias->aliasInfo.aliasName); strlcpy(curAlias->aliasInfo.realName, tbuffer, sizeof curAlias->aliasInfo.realName); curAlias->next = adir->alias_entries; adir->alias_entries = curAlias; } if (tf != NULL) fclose(tf); /* now read the fs keys, if possible */ adir->keystr = (struct afsconf_keys *)0; afsconf_IntGetKeys(adir); return 0; }