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>
18 #include <WINNT/afsevent.h>
25 #include <rx/rxstat.h>
27 #include <rx/rx_globals.h>
28 #include <afs/cellconfig.h>
30 #include <afs/afsutil.h>
31 #include <afs/com_err.h>
32 #include <afs/audit.h>
35 #include "kalog.h" /* for OpenLog() */
37 #include "kauth_internal.h"
40 #include "kadatabase.h"
43 struct kadstats dynamic_statistics;
44 struct ubik_dbase *KA_dbase;
45 afs_uint32 myHost = 0;
46 afs_int32 verbose_track = 1;
47 afs_int32 krb4_cross = 0;
50 #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */
51 afs_uint32 SHostAddrs[ADDRSPERSITE];
53 struct afsconf_dir *KA_conf; /* for getting cell info */
56 int npwSums = KA_NPWSUMS; /* needs to be variable sometime */
58 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
60 #define vfprintf(stream,fmt,args) _doprnt(fmt,args,stream)
63 static int debugOutput;
65 /* check whether caller is authorized to manage RX statistics */
67 KA_rxstat_userok(struct rx_call *call)
69 return afsconf_SuperUser(KA_conf, call, NULL);
73 * Return true if this name is a member of the local realm.
76 KA_IsLocalRealmMatch(void *rock, char *name, char *inst, char *cell)
78 struct afsconf_dir *dir = (struct afsconf_dir *)rock;
79 afs_int32 islocal = 0; /* default to no */
82 code = afsconf_IsLocalRealmMatch(dir, &islocal, name, inst, cell);
85 ("Failed local realm check; code=%d, name=%s, inst=%s, cell=%s\n",
86 code, name, inst, cell));
92 es_Report(char *fmt, ...)
99 vfprintf(stderr, fmt, pvar);
105 initialize_dstats(void)
107 memset(&dynamic_statistics, 0, sizeof(dynamic_statistics));
108 dynamic_statistics.start_time = time(0);
109 dynamic_statistics.host = myHost;
113 convert_cell_to_ubik(struct afsconf_cell *cellinfo, afs_uint32 *myHost,
114 afs_uint32 *serverList)
121 gethostname(hostname, sizeof(hostname));
122 th = gethostbyname(hostname);
124 ViceLog(0, ("kaserver: couldn't get address of this host.\n"));
127 memcpy(myHost, th->h_addr, sizeof(afs_uint32));
129 for (i = 0; i < cellinfo->numServers; i++)
130 if (cellinfo->hostAddr[i].sin_addr.s_addr != *myHost) {
131 /* omit my host from serverList */
132 *serverList++ = cellinfo->hostAddr[i].sin_addr.s_addr;
134 *serverList = 0; /* terminate list */
139 kvno_admin_key(void *rock, afs_int32 kvno, struct ktc_encryptionKey *key)
141 return ka_LookupKvno(0, KA_ADMIN_NAME, KA_ADMIN_INST, kvno, key);
143 /* we would like to start a Ubik transaction to fill the cache if that
144 * fails, but may deadlock as Rx is now organized. */
147 /* initFlags: 0x01 Do not require authenticated connections.
148 0x02 Do not check the bos NoAuth flag
149 0x04 Use fast key expiration to test oldkey code.
150 0x08 Temporary flag allowing database inconsistency fixup
153 #include "AFS_component_version_number.c"
156 main(int argc, char *argv[])
159 char *whoami = argv[0];
160 afs_uint32 serverList[MAXSERVERS];
161 struct afsconf_cell cellinfo;
163 const char *cellservdb, *dbpath, *lclpath;
166 char *default_lclpath;
169 int level; /* security level for Ubik */
171 char clones[MAXHOSTSPERCELL];
173 afs_uint32 host = ntohl(INADDR_ANY);
174 char *auditFileName = NULL;
175 struct logOptions logopts;
177 struct rx_service *tservice;
178 struct rx_securityClass *sca[1];
179 struct rx_securityClass *scm[3];
181 extern int rx_stackSize;
185 * The following signal action for AIX is necessary so that in case of a
186 * crash (i.e. core is generated) we can include the user's data section
187 * in the core dump. Unfortunately, by default, only a partial core is
188 * generated which, in many cases, isn't too useful.
190 struct sigaction nsa;
192 sigemptyset(&nsa.sa_mask);
193 nsa.sa_handler = SIG_DFL;
194 nsa.sa_flags = SA_FULLDUMP;
195 sigaction(SIGABRT, &nsa, NULL);
196 sigaction(SIGSEGV, &nsa, NULL);
200 memset(&logopts, 0, sizeof(logopts));
204 printf("Usage: kaserver [-noAuth] [-database <dbpath>] "
205 "[-auditlog <log path>] [-audit-interface <file|sysvmq>] "
206 "[-rxbind] [-localfiles <lclpath>] [-minhours <n>] "
207 "[-servers <serverlist>] [-crossrealm] "
208 "[-enable_peer_stats] [-enable_process_stats] "
213 /* initialize winsock */
214 if (afs_winsockInit() < 0) {
215 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
216 fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami);
220 /* Initialize dirpaths */
221 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
223 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
225 fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
230 cellservdb = AFSDIR_SERVER_ETC_DIRPATH;
231 dbpath = AFSDIR_SERVER_KADB_FILEPATH;
233 if (asprintf(&default_lclpath, "%s/%s", AFSDIR_SERVER_LOCAL_DIRPATH,
234 AFSDIR_KADB_FILE) < 0) {
235 fprintf(stderr, "%s: No memory for default local dir path\n", argv[0]);
238 lclpath = default_lclpath;
244 for (a = 1; a < argc; a++) {
245 int arglen = strlen(argv[a]);
246 lcstring(arg, argv[a], sizeof(arg));
247 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
249 if (strcmp(arg, "-database") == 0) {
251 if (strcmp(lclpath, default_lclpath) == 0)
254 else if (strncmp(arg, "-auditlog", arglen) == 0) {
255 auditFileName = argv[++a];
257 } else if (strncmp(arg, "-audit-interface", arglen) == 0) {
258 char *interface = argv[++a];
260 if (osi_audit_interface(interface)) {
261 printf("Invalid audit interface '%s'\n", interface);
265 } else if (strcmp(arg, "-localfiles") == 0)
267 else if (strcmp(arg, "-servers") == 0)
268 debugOutput++, servers = 1;
269 else if (strcmp(arg, "-noauth") == 0)
270 debugOutput++, initFlags |= 1;
271 else if (strcmp(arg, "-fastkeys") == 0)
272 debugOutput++, initFlags |= 4;
273 else if (strcmp(arg, "-dbfixup") == 0)
274 debugOutput++, initFlags |= 8;
275 else if (strcmp(arg, "-cellservdb") == 0) {
276 cellservdb = argv[++a];
281 else if (IsArg("-crypt"))
283 else if (IsArg("-safe"))
285 else if (IsArg("-clear"))
287 else if (IsArg("-sorry"))
289 else if (IsArg("-debug"))
291 else if (IsArg("-crossrealm"))
293 else if (IsArg("-rxbind"))
295 else if (IsArg("-minhours")) {
296 MinHours = atoi(argv[++a]);
297 } else if (IsArg("-enable_peer_stats")) {
298 rx_enablePeerRPCStats();
299 } else if (IsArg("-enable_process_stats")) {
300 rx_enableProcessRPCStats();
301 } else if (*arg == '-') {
302 /* hack to support help flag */
308 osi_audit_file(auditFileName);
311 if ((code = ka_CellConfig(cellservdb)))
313 cell = ka_LocalCell();
314 KA_conf = afsconf_Open(cellservdb);
318 afs_com_err(whoami, code, "Failed getting cell info");
324 /* NT & HPUX do not have dbm package support. So we can only do some
325 * text logging. So open the AuthLog file for logging and redirect
326 * stdin and stdout to it
328 logopts.lopt_dest = logDest_file;
329 logopts.lopt_filename = AFSDIR_SERVER_KALOG_FILEPATH;
330 logopts.lopt_rotateOnOpen = 1;
331 logopts.lopt_rotateStyle = logRotate_old;
337 fprintf(stderr, "%s: WARNING: kaserver is deprecated due to its weak security "
338 "properties. Migrating to a Kerberos 5 KDC is advised. "
339 "http://www.openafs.org/no-more-des.html\n", whoami);
340 ViceLog(0, ("WARNING: kaserver is deprecated due to its weak security properties. "
341 "Migrating to a Kerberos 5 KDC is advised. "
342 "http://www.openafs.org/no-more-des.html\n"));
344 code = afsconf_GetExtendedCellInfo(KA_conf, cell, AFSCONF_KAUTHSERVICE,
347 afs_com_err(whoami, code, "Couldn't read cell configuration");
352 if ((code = ubik_ParseServerList(argc, argv, &myHost, serverList))) {
353 afs_com_err(whoami, code, "Couldn't parse server list");
356 cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
357 for (i = 1; i < MAXSERVERS; i++) {
360 if (i >= MAXHOSTSPERCELL) {
362 "Too many ubik servers specified on command line\n");
365 cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
367 cellinfo.numServers = i;
369 code = convert_cell_to_ubik(&cellinfo, &myHost, serverList);
372 ViceLog(0, ("Using server list from %s cell database.\n", cell));
375 /* initialize audit user check */
376 osi_audit_set_user_check(KA_conf, KA_IsLocalRealmMatch);
378 /* initialize ubik */
379 if (level == rxkad_clear)
380 ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate,
382 else if (level == rxkad_crypt)
383 ubik_SetClientSecurityProcs(afsconf_ClientAuthSecure,
384 afsconf_UpToDate, KA_conf);
386 ViceLog(0, ("Unsupported security level %d\n", level));
390 ("Using level %s for Ubik connections.\n",
391 (level == rxkad_crypt ? "crypt" : "clear")));
393 ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects,
401 if (AFSDIR_SERVER_NETRESTRICT_FILEPATH ||
402 AFSDIR_SERVER_NETINFO_FILEPATH) {
404 ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL,
405 ADDRSPERSITE, reason,
406 AFSDIR_SERVER_NETINFO_FILEPATH,
407 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
410 ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE);
413 host = SHostAddrs[0];
417 ViceLog(0, ("kaserver binding rx to %s:%d\n",
418 afs_inet_ntoa_r(host, hoststr), AFSCONF_KAUTHPORT));
419 code = rx_InitHost(host, htons(AFSCONF_KAUTHPORT));
421 afs_com_err(whoami, code, "rx init failed");
425 /* Disable jumbograms */
430 ubik_ServerInit(myHost, htons(AFSCONF_KAUTHPORT), serverList,
434 ubik_ServerInitByInfo(myHost, htons(AFSCONF_KAUTHPORT), &cellinfo,
435 clones, dbpath, &KA_dbase);
438 afs_com_err(whoami, code, "Ubik init failed");
442 sca[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject();
445 rx_NewServiceHost(host, 0, KA_AUTHENTICATION_SERVICE,
446 "AuthenticationService", sca, 1, KAA_ExecuteRequest);
447 if (tservice == (struct rx_service *)0) {
448 ViceLog(0, ("Could not create Authentication rx service\n"));
451 rx_SetMinProcs(tservice, 1);
452 rx_SetMaxProcs(tservice, 1);
456 rx_NewServiceHost(host, 0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService",
457 sca, 1, KAT_ExecuteRequest);
458 if (tservice == (struct rx_service *)0) {
459 ViceLog(0, ("Could not create Ticket Granting rx service\n"));
462 rx_SetMinProcs(tservice, 1);
463 rx_SetMaxProcs(tservice, 1);
465 scm[RX_SECIDX_NULL] = sca[RX_SECIDX_NULL];
466 scm[RX_SECIDX_VAB] = 0;
468 rxkad_NewServerSecurityObject(rxkad_crypt, 0, kvno_admin_key, 0);
470 rx_NewServiceHost(host, 0, KA_MAINTENANCE_SERVICE, "Maintenance", scm, 3,
472 if (tservice == (struct rx_service *)0) {
473 ViceLog(0, ("Could not create Maintenance rx service\n"));
476 rx_SetMinProcs(tservice, 1);
477 rx_SetMaxProcs(tservice, 1);
478 rx_SetStackSize(tservice, 10000);
481 rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", scm, 3,
482 RXSTATS_ExecuteRequest);
483 if (tservice == (struct rx_service *)0) {
484 ViceLog(0, ("Could not create rpc stats rx service\n"));
487 rx_SetMinProcs(tservice, 2);
488 rx_SetMaxProcs(tservice, 4);
492 /* allow super users to manage RX statistics */
493 rx_SetRxStatUserOk(KA_rxstat_userok);
495 rx_StartServer(0); /* start handling req. of all types */
497 if (init_kaprocs(lclpath, initFlags))
500 if ((code = init_krb_udp())) {
502 ("Failed to initialize UDP interface; code = %d.\n", code));
503 ViceLog(0, ("Running without UDP access.\n"));
506 ViceLog(0, ("Starting to process AuthServer requests\n"));
507 rx_ServerProc(NULL); /* donate this LWP */