2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
17 #include <sys/types.h>
20 #include <WINNT/afsevent.h>
24 #include <netinet/in.h>
26 #include "kalog.h" /* for OpenLog() */
46 #include <rx/rx_globals.h>
47 #include <afs/cellconfig.h>
49 #include <afs/afsutil.h>
57 struct kadstats dynamic_statistics;
58 struct ubik_dbase *KA_dbase;
60 afs_int32 verbose_track = 1;
61 afs_int32 krb4_cross = 0;
63 struct afsconf_dir *KA_conf; /* for getting cell info */
66 int npwSums = KA_NPWSUMS; /* needs to be variable sometime */
69 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
71 #define vfprintf(stream,fmt,args) _doprnt(fmt,args,stream)
74 static int debugOutput;
76 /* check whether caller is authorized to manage RX statistics */
78 KA_rxstat_userok(call)
81 return afsconf_SuperUser(KA_conf, call, NULL);
85 es_Report(char *fmt, ...)
92 vfprintf(stderr, fmt, pvar);
100 memset(&dynamic_statistics, 0, sizeof(dynamic_statistics));
101 dynamic_statistics.start_time = time(0);
102 dynamic_statistics.host = myHost;
106 convert_cell_to_ubik(cellinfo, myHost, serverList)
107 struct afsconf_cell *cellinfo;
109 afs_int32 *serverList;
116 gethostname(hostname, sizeof(hostname));
117 th = gethostbyname(hostname);
119 ViceLog(0, ("kaserver: couldn't get address of this host.\n"));
122 memcpy(myHost, th->h_addr, sizeof(afs_int32));
124 for (i = 0; i < cellinfo->numServers; i++)
125 if (cellinfo->hostAddr[i].sin_addr.s_addr != *myHost) {
126 /* omit my host from serverList */
127 *serverList++ = cellinfo->hostAddr[i].sin_addr.s_addr;
129 *serverList = 0; /* terminate list */
134 kvno_admin_key(rock, kvno, key)
137 struct ktc_encryptionKey *key;
139 return ka_LookupKvno(0, KA_ADMIN_NAME, KA_ADMIN_INST, kvno, key);
141 /* we would like to start a Ubik transaction to fill the cache if that
142 * fails, but may deadlock as Rx is now organized. */
145 /* initFlags: 0x01 Do not require authenticated connections.
146 0x02 Do not check the bos NoAuth flag
147 0x04 Use fast key expiration to test oldkey code.
148 0x08 Temporary flag allowing database inconsistency fixup
151 #include "AFS_component_version_number.c"
158 char *whoami = argv[0];
159 afs_int32 serverList[MAXSERVERS];
160 struct afsconf_cell cellinfo;
162 const char *cellservdb, *dbpath, *lclpath;
165 char default_lclpath[AFSDIR_PATH_MAX];
168 int level; /* security level for Ubik */
170 char clones[MAXHOSTSPERCELL];
172 struct rx_service *tservice;
173 struct rx_securityClass *sca[1];
174 struct rx_securityClass *scm[3];
176 extern int afsconf_ClientAuthSecure();
177 extern int afsconf_ServerAuth();
178 extern int afsconf_CheckAuth();
180 extern int rx_stackSize;
181 extern int KAA_ExecuteRequest();
182 extern int KAT_ExecuteRequest();
183 extern int KAM_ExecuteRequest();
184 extern int RXSTATS_ExecuteRequest();
188 * The following signal action for AIX is necessary so that in case of a
189 * crash (i.e. core is generated) we can include the user's data section
190 * in the core dump. Unfortunately, by default, only a partial core is
191 * generated which, in many cases, isn't too useful.
193 struct sigaction nsa;
195 sigemptyset(&nsa.sa_mask);
196 nsa.sa_handler = SIG_DFL;
197 nsa.sa_flags = SA_FULLDUMP;
198 sigaction(SIGABRT, &nsa, NULL);
199 sigaction(SIGSEGV, &nsa, NULL);
203 printf("Usage: kaserver [-noAuth] [-fastKeys] [-database <dbpath>] "
204 "[-auditlog <log path>] "
205 "[-localfiles <lclpath>] [-minhours <n>] [-servers <serverlist>] "
207 /*" [-enable_peer_stats] [-enable_process_stats] " */
212 /* initialize winsock */
213 if (afs_winsockInit() < 0) {
214 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
215 fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami);
219 /* Initialize dirpaths */
220 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
222 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
224 fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
229 cellservdb = AFSDIR_SERVER_ETC_DIRPATH;
230 dbpath = AFSDIR_SERVER_KADB_FILEPATH;
231 strcompose(default_lclpath, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH,
232 "/", AFSDIR_KADB_FILE, NULL);
233 lclpath = default_lclpath;
239 for (a = 1; a < argc; a++) {
240 int arglen = strlen(argv[a]);
241 lcstring(arg, argv[a], sizeof(arg));
242 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
244 if (strcmp(arg, "-database") == 0) {
246 if (strcmp(lclpath, default_lclpath) == 0)
249 else if (strncmp(arg, "-auditlog", arglen) == 0) {
252 char oldName[MAXPATHLEN];
253 char *fileName = argv[++a];
258 if ((lstat(fileName, &statbuf) == 0)
259 && (S_ISFIFO(statbuf.st_mode))) {
260 flags = O_WRONLY | O_NONBLOCK;
264 strcpy(oldName, fileName);
265 strcat(oldName, ".old");
266 renamefile(fileName, oldName);
267 flags = O_WRONLY | O_TRUNC | O_CREAT;
269 tempfd = open(fileName, flags, 0666);
271 auditout = fdopen(tempfd, "a");
273 osi_audit_file(auditout);
275 printf("Warning: auditlog %s not writable, ignored.\n", fileName);
277 printf("Warning: auditlog %s not writable, ignored.\n", fileName);
278 } else if (strcmp(arg, "-localfiles") == 0)
280 else if (strcmp(arg, "-servers") == 0)
281 debugOutput++, servers = 1;
282 else if (strcmp(arg, "-noauth") == 0)
283 debugOutput++, initFlags |= 1;
284 else if (strcmp(arg, "-fastkeys") == 0)
285 debugOutput++, initFlags |= 4;
286 else if (strcmp(arg, "-dbfixup") == 0)
287 debugOutput++, initFlags |= 8;
288 else if (strcmp(arg, "-cellservdb") == 0) {
289 cellservdb = argv[++a];
294 else if (IsArg("-crypt"))
296 else if (IsArg("-safe"))
298 else if (IsArg("-clear"))
300 else if (IsArg("-sorry"))
302 else if (IsArg("-debug"))
304 else if (IsArg("-crossrealm"))
306 else if (IsArg("-minhours")) {
307 MinHours = atoi(argv[++a]);
308 } else if (IsArg("-enable_peer_stats")) {
309 rx_enablePeerRPCStats();
310 } else if (IsArg("-enable_process_stats")) {
311 rx_enableProcessRPCStats();
312 } else if (*arg == '-') {
313 /* hack to support help flag */
317 if (code = ka_CellConfig(cellservdb))
319 cell = ka_LocalCell();
320 KA_conf = afsconf_Open(cellservdb);
324 com_err(whoami, code, "Failed getting cell info");
330 /* NT & HPUX do not have dbm package support. So we can only do some
331 * text logging. So open the AuthLog file for logging and redirect
332 * stdin and stdout to it
334 OpenLog(AFSDIR_SERVER_KALOG_FILEPATH);
338 afsconf_GetExtendedCellInfo(KA_conf, cell, AFSCONF_KAUTHSERVICE,
341 if (code = ubik_ParseServerList(argc, argv, &myHost, serverList)) {
342 com_err(whoami, code, "Couldn't parse server list");
345 cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
346 for (i = 1; i < MAXSERVERS; i++) {
349 cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
351 cellinfo.numServers = i;
353 code = convert_cell_to_ubik(&cellinfo, &myHost, serverList);
356 ViceLog(0, ("Using server list from %s cell database.\n", cell));
359 /* initialize ubik */
360 if (level == rxkad_clear)
361 ubik_CRXSecurityProc = afsconf_ClientAuth;
362 else if (level == rxkad_crypt)
363 ubik_CRXSecurityProc = afsconf_ClientAuthSecure;
365 ViceLog(0, ("Unsupported security level %d\n", level));
369 ("Using level %s for Ubik connections.\n",
370 (level == rxkad_crypt ? "crypt" : "clear")));
371 ubik_CRXSecurityRock = (char *)KA_conf;
372 ubik_SRXSecurityProc = afsconf_ServerAuth;
373 ubik_SRXSecurityRock = (char *)KA_conf;
374 ubik_CheckRXSecurityProc = afsconf_CheckAuth;
375 ubik_CheckRXSecurityRock = (char *)KA_conf;
380 ubik_ServerInit(myHost, htons(AFSCONF_KAUTHPORT), serverList,
384 ubik_ServerInitByInfo(myHost, htons(AFSCONF_KAUTHPORT), &cellinfo,
385 &clones, dbpath, &KA_dbase);
388 com_err(whoami, code, "Ubik init failed");
392 sca[RX_SCINDEX_NULL] = rxnull_NewServerSecurityObject();
394 /* Disable jumbograms */
398 rx_NewService(0, KA_AUTHENTICATION_SERVICE, "AuthenticationService",
399 sca, 1, KAA_ExecuteRequest);
400 if (tservice == (struct rx_service *)0) {
401 ViceLog(0, ("Could not create Authentication rx service\n"));
404 rx_SetMinProcs(tservice, 1);
405 rx_SetMaxProcs(tservice, 1);
408 rx_NewService(0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService",
409 sca, 1, KAT_ExecuteRequest);
410 if (tservice == (struct rx_service *)0) {
411 ViceLog(0, ("Could not create Ticket Granting rx service\n"));
414 rx_SetMinProcs(tservice, 1);
415 rx_SetMaxProcs(tservice, 1);
417 scm[RX_SCINDEX_NULL] = sca[RX_SCINDEX_NULL];
418 scm[RX_SCINDEX_VAB] = 0;
419 scm[RX_SCINDEX_KAD] =
420 rxkad_NewServerSecurityObject(rxkad_crypt, 0, kvno_admin_key, 0);
422 rx_NewService(0, KA_MAINTENANCE_SERVICE, "Maintenance", scm, 3,
424 if (tservice == (struct rx_service *)0) {
425 ViceLog(0, ("Could not create Maintenance rx service\n"));
428 rx_SetMinProcs(tservice, 1);
429 rx_SetMaxProcs(tservice, 1);
430 rx_SetStackSize(tservice, 10000);
433 rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", scm, 3,
434 RXSTATS_ExecuteRequest);
435 if (tservice == (struct rx_service *)0) {
436 ViceLog(0, ("Could not create rpc stats rx service\n"));
439 rx_SetMinProcs(tservice, 2);
440 rx_SetMaxProcs(tservice, 4);
444 /* allow super users to manage RX statistics */
445 rx_SetRxStatUserOk(KA_rxstat_userok);
447 rx_StartServer(0); /* start handling req. of all types */
449 if (init_kaprocs(lclpath, initFlags))
452 if (code = init_krb_udp()) {
454 ("Failed to initialize UDP interface; code = %d.\n", code));
455 ViceLog(0, ("Running without UDP access.\n"));
458 ViceLog(0, ("Starting to process AuthServer requests\n"));
459 rx_ServerProc(); /* donate this LWP */