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);
205 printf("Usage: kaserver [-noAuth] [-fastKeys] [-database <dbpath>] "
206 "[-auditlog <log path>] "
207 "[-localfiles <lclpath>] [-minhours <n>] [-servers <serverlist>] "
209 /*" [-enable_peer_stats] [-enable_process_stats] " */
214 /* initialize winsock */
215 if (afs_winsockInit() < 0) {
216 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
217 fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami);
221 /* Initialize dirpaths */
222 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
224 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
226 fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
231 cellservdb = AFSDIR_SERVER_ETC_DIRPATH;
232 dbpath = AFSDIR_SERVER_KADB_FILEPATH;
233 strcompose(default_lclpath, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH,
234 "/", AFSDIR_KADB_FILE, NULL);
235 lclpath = default_lclpath;
241 for (a = 1; a < argc; a++) {
242 int arglen = strlen(argv[a]);
243 lcstring(arg, argv[a], sizeof(arg));
244 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
246 if (strcmp(arg, "-database") == 0) {
248 if (strcmp(lclpath, default_lclpath) == 0)
251 else if (strncmp(arg, "-auditlog", arglen) == 0) {
254 char oldName[MAXPATHLEN];
255 char *fileName = argv[++a];
260 if ((lstat(fileName, &statbuf) == 0)
261 && (S_ISFIFO(statbuf.st_mode))) {
262 flags = O_WRONLY | O_NONBLOCK;
266 strcpy(oldName, fileName);
267 strcat(oldName, ".old");
268 renamefile(fileName, oldName);
269 flags = O_WRONLY | O_TRUNC | O_CREAT;
271 tempfd = open(fileName, flags, 0666);
273 auditout = fdopen(tempfd, "a");
275 osi_audit_file(auditout);
277 printf("Warning: auditlog %s not writable, ignored.\n", fileName);
279 printf("Warning: auditlog %s not writable, ignored.\n", fileName);
280 } else if (strcmp(arg, "-localfiles") == 0)
282 else if (strcmp(arg, "-servers") == 0)
283 debugOutput++, servers = 1;
284 else if (strcmp(arg, "-noauth") == 0)
285 debugOutput++, initFlags |= 1;
286 else if (strcmp(arg, "-fastkeys") == 0)
287 debugOutput++, initFlags |= 4;
288 else if (strcmp(arg, "-dbfixup") == 0)
289 debugOutput++, initFlags |= 8;
290 else if (strcmp(arg, "-cellservdb") == 0) {
291 cellservdb = argv[++a];
296 else if (IsArg("-crypt"))
298 else if (IsArg("-safe"))
300 else if (IsArg("-clear"))
302 else if (IsArg("-sorry"))
304 else if (IsArg("-debug"))
306 else if (IsArg("-crossrealm"))
308 else if (IsArg("-minhours")) {
309 MinHours = atoi(argv[++a]);
310 } else if (IsArg("-enable_peer_stats")) {
311 rx_enablePeerRPCStats();
312 } else if (IsArg("-enable_process_stats")) {
313 rx_enableProcessRPCStats();
314 } else if (*arg == '-') {
315 /* hack to support help flag */
319 if (code = ka_CellConfig(cellservdb))
321 cell = ka_LocalCell();
322 KA_conf = afsconf_Open(cellservdb);
326 com_err(whoami, code, "Failed getting cell info");
332 /* NT & HPUX do not have dbm package support. So we can only do some
333 * text logging. So open the AuthLog file for logging and redirect
334 * stdin and stdout to it
336 OpenLog(AFSDIR_SERVER_KALOG_FILEPATH);
340 afsconf_GetExtendedCellInfo(KA_conf, cell, AFSCONF_KAUTHSERVICE,
343 if (code = ubik_ParseServerList(argc, argv, &myHost, serverList)) {
344 com_err(whoami, code, "Couldn't parse server list");
347 cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
348 for (i = 1; i < MAXSERVERS; i++) {
351 cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
353 cellinfo.numServers = i;
355 code = convert_cell_to_ubik(&cellinfo, &myHost, serverList);
358 ViceLog(0, ("Using server list from %s cell database.\n", cell));
361 /* initialize ubik */
362 if (level == rxkad_clear)
363 ubik_CRXSecurityProc = afsconf_ClientAuth;
364 else if (level == rxkad_crypt)
365 ubik_CRXSecurityProc = afsconf_ClientAuthSecure;
367 ViceLog(0, ("Unsupported security level %d\n", level));
371 ("Using level %s for Ubik connections.\n",
372 (level == rxkad_crypt ? "crypt" : "clear")));
373 ubik_CRXSecurityRock = (char *)KA_conf;
374 ubik_SRXSecurityProc = afsconf_ServerAuth;
375 ubik_SRXSecurityRock = (char *)KA_conf;
376 ubik_CheckRXSecurityProc = afsconf_CheckAuth;
377 ubik_CheckRXSecurityRock = (char *)KA_conf;
382 ubik_ServerInit(myHost, htons(AFSCONF_KAUTHPORT), serverList,
386 ubik_ServerInitByInfo(myHost, htons(AFSCONF_KAUTHPORT), &cellinfo,
387 &clones, dbpath, &KA_dbase);
390 com_err(whoami, code, "Ubik init failed");
394 sca[RX_SCINDEX_NULL] = rxnull_NewServerSecurityObject();
396 /* Disable jumbograms */
400 rx_NewService(0, KA_AUTHENTICATION_SERVICE, "AuthenticationService",
401 sca, 1, KAA_ExecuteRequest);
402 if (tservice == (struct rx_service *)0) {
403 ViceLog(0, ("Could not create Authentication rx service\n"));
406 rx_SetMinProcs(tservice, 1);
407 rx_SetMaxProcs(tservice, 1);
410 rx_NewService(0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService",
411 sca, 1, KAT_ExecuteRequest);
412 if (tservice == (struct rx_service *)0) {
413 ViceLog(0, ("Could not create Ticket Granting rx service\n"));
416 rx_SetMinProcs(tservice, 1);
417 rx_SetMaxProcs(tservice, 1);
419 scm[RX_SCINDEX_NULL] = sca[RX_SCINDEX_NULL];
420 scm[RX_SCINDEX_VAB] = 0;
421 scm[RX_SCINDEX_KAD] =
422 rxkad_NewServerSecurityObject(rxkad_crypt, 0, kvno_admin_key, 0);
424 rx_NewService(0, KA_MAINTENANCE_SERVICE, "Maintenance", scm, 3,
426 if (tservice == (struct rx_service *)0) {
427 ViceLog(0, ("Could not create Maintenance rx service\n"));
430 rx_SetMinProcs(tservice, 1);
431 rx_SetMaxProcs(tservice, 1);
432 rx_SetStackSize(tservice, 10000);
435 rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", scm, 3,
436 RXSTATS_ExecuteRequest);
437 if (tservice == (struct rx_service *)0) {
438 ViceLog(0, ("Could not create rpc stats rx service\n"));
441 rx_SetMinProcs(tservice, 2);
442 rx_SetMaxProcs(tservice, 4);
446 /* allow super users to manage RX statistics */
447 rx_SetRxStatUserOk(KA_rxstat_userok);
449 rx_StartServer(0); /* start handling req. of all types */
451 if (init_kaprocs(lclpath, initFlags))
454 if (code = init_krb_udp()) {
456 ("Failed to initialize UDP interface; code = %d.\n", code));
457 ViceLog(0, ("Running without UDP access.\n"));
460 ViceLog(0, ("Starting to process AuthServer requests\n"));
461 rx_ServerProc(); /* donate this LWP */