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_LINUX_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 *auditIFace = NULL;
175 char *auditFileName = NULL;
176 struct logOptions logopts;
178 struct rx_service *tservice;
179 struct rx_securityClass *sca[1];
180 struct rx_securityClass *scm[3];
182 extern int rx_stackSize;
186 * The following signal action for AIX is necessary so that in case of a
187 * crash (i.e. core is generated) we can include the user's data section
188 * in the core dump. Unfortunately, by default, only a partial core is
189 * generated which, in many cases, isn't too useful.
191 struct sigaction nsa;
193 sigemptyset(&nsa.sa_mask);
194 nsa.sa_handler = SIG_DFL;
195 nsa.sa_flags = SA_FULLDUMP;
196 sigaction(SIGABRT, &nsa, NULL);
197 sigaction(SIGSEGV, &nsa, NULL);
201 memset(&logopts, 0, sizeof(logopts));
205 printf("Usage: kaserver [-noAuth] [-database <dbpath>] "
206 "[-auditlog [<interface>:]<path>[:<options>]] "
207 "[-audit-interface <default interface>] "
208 "[-rxbind] [-localfiles <lclpath>] [-minhours <n>] "
209 "[-servers <serverlist>] [-crossrealm] "
210 "[-enable_peer_stats] [-enable_process_stats] "
215 /* initialize winsock */
216 if (afs_winsockInit() < 0) {
217 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
218 fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami);
222 /* Initialize dirpaths */
223 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
225 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
227 fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
232 cellservdb = AFSDIR_SERVER_ETC_DIRPATH;
233 dbpath = AFSDIR_SERVER_KADB_FILEPATH;
235 if (asprintf(&default_lclpath, "%s/%s", AFSDIR_SERVER_LOCAL_DIRPATH,
236 AFSDIR_KADB_FILE) < 0) {
237 fprintf(stderr, "%s: No memory for default local dir path\n", argv[0]);
240 lclpath = default_lclpath;
246 for (a = 1; a < argc; a++) {
247 int arglen = strlen(argv[a]);
248 lcstring(arg, argv[a], sizeof(arg));
249 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
251 if (strcmp(arg, "-database") == 0) {
253 if (strcmp(lclpath, default_lclpath) == 0)
256 else if (strncmp(arg, "-auditlog", arglen) == 0) {
258 fprintf(stderr, "missing argument for -auditlog\n");
261 auditFileName = argv[++a];
263 } else if (strncmp(arg, "-audit-interface", arglen) == 0) {
265 fprintf(stderr, "missing argument for -audit-interface\n");
268 auditIFace = argv[++a];
270 } else if (strcmp(arg, "-localfiles") == 0)
272 else if (strcmp(arg, "-servers") == 0)
273 debugOutput++, servers = 1;
274 else if (strcmp(arg, "-noauth") == 0)
275 debugOutput++, initFlags |= 1;
276 else if (strcmp(arg, "-fastkeys") == 0)
277 debugOutput++, initFlags |= 4;
278 else if (strcmp(arg, "-dbfixup") == 0)
279 debugOutput++, initFlags |= 8;
280 else if (strcmp(arg, "-cellservdb") == 0) {
281 cellservdb = argv[++a];
286 else if (IsArg("-crypt"))
288 else if (IsArg("-safe"))
290 else if (IsArg("-clear"))
292 else if (IsArg("-sorry"))
294 else if (IsArg("-debug"))
296 else if (IsArg("-crossrealm"))
298 else if (IsArg("-rxbind"))
300 else if (IsArg("-minhours")) {
301 MinHours = atoi(argv[++a]);
302 } else if (IsArg("-enable_peer_stats")) {
303 rx_enablePeerRPCStats();
304 } else if (IsArg("-enable_process_stats")) {
305 rx_enableProcessRPCStats();
306 } else if (*arg == '-') {
307 /* hack to support help flag */
313 if (osi_audit_interface(auditIFace)) {
314 fprintf(stderr, "Invalid audit-interface '%s'\n", auditIFace);
319 osi_audit_file(auditFileName);
324 if ((code = ka_CellConfig(cellservdb)))
326 cell = ka_LocalCell();
327 KA_conf = afsconf_Open(cellservdb);
331 afs_com_err(whoami, code, "Failed getting cell info");
337 /* NT & HPUX do not have dbm package support. So we can only do some
338 * text logging. So open the AuthLog file for logging and redirect
339 * stdin and stdout to it
341 logopts.lopt_dest = logDest_file;
342 logopts.lopt_filename = AFSDIR_SERVER_KALOG_FILEPATH;
343 logopts.lopt_rotateOnOpen = 1;
344 logopts.lopt_rotateStyle = logRotate_old;
350 fprintf(stderr, "%s: WARNING: kaserver is deprecated due to its weak security "
351 "properties. Migrating to a Kerberos 5 KDC is advised. "
352 "http://www.openafs.org/no-more-des.html\n", whoami);
353 ViceLog(0, ("WARNING: kaserver is deprecated due to its weak security properties. "
354 "Migrating to a Kerberos 5 KDC is advised. "
355 "http://www.openafs.org/no-more-des.html\n"));
357 code = afsconf_GetExtendedCellInfo(KA_conf, cell, AFSCONF_KAUTHSERVICE,
360 afs_com_err(whoami, code, "Couldn't read cell configuration");
365 if ((code = ubik_ParseServerList(argc, argv, &myHost, serverList))) {
366 afs_com_err(whoami, code, "Couldn't parse server list");
369 cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
370 for (i = 1; i < MAXSERVERS; i++) {
373 if (i >= MAXHOSTSPERCELL) {
375 "Too many ubik servers specified on command line\n");
378 cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
380 cellinfo.numServers = i;
382 code = convert_cell_to_ubik(&cellinfo, &myHost, serverList);
385 ViceLog(0, ("Using server list from %s cell database.\n", cell));
388 /* initialize audit user check */
389 osi_audit_set_user_check(KA_conf, KA_IsLocalRealmMatch);
391 /* initialize ubik */
392 if (level == rxkad_clear)
393 ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate,
395 else if (level == rxkad_crypt)
396 ubik_SetClientSecurityProcs(afsconf_ClientAuthSecure,
397 afsconf_UpToDate, KA_conf);
399 ViceLog(0, ("Unsupported security level %d\n", level));
403 ("Using level %s for Ubik connections.\n",
404 (level == rxkad_crypt ? "crypt" : "clear")));
406 ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects,
414 if (AFSDIR_SERVER_NETRESTRICT_FILEPATH ||
415 AFSDIR_SERVER_NETINFO_FILEPATH) {
417 ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL,
418 ADDRSPERSITE, reason,
419 AFSDIR_SERVER_NETINFO_FILEPATH,
420 AFSDIR_SERVER_NETRESTRICT_FILEPATH);
423 ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE);
426 host = SHostAddrs[0];
430 ViceLog(0, ("kaserver binding rx to %s:%d\n",
431 afs_inet_ntoa_r(host, hoststr), AFSCONF_KAUTHPORT));
432 code = rx_InitHost(host, htons(AFSCONF_KAUTHPORT));
434 afs_com_err(whoami, code, "rx init failed");
438 /* Disable jumbograms */
443 ubik_ServerInit(myHost, htons(AFSCONF_KAUTHPORT), serverList,
447 ubik_ServerInitByInfo(myHost, htons(AFSCONF_KAUTHPORT), &cellinfo,
448 clones, dbpath, &KA_dbase);
451 afs_com_err(whoami, code, "Ubik init failed");
455 sca[RX_SECIDX_NULL] = rxnull_NewServerSecurityObject();
458 rx_NewServiceHost(host, 0, KA_AUTHENTICATION_SERVICE,
459 "AuthenticationService", sca, 1, KAA_ExecuteRequest);
460 if (tservice == (struct rx_service *)0) {
461 ViceLog(0, ("Could not create Authentication rx service\n"));
464 rx_SetMinProcs(tservice, 1);
465 rx_SetMaxProcs(tservice, 1);
469 rx_NewServiceHost(host, 0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService",
470 sca, 1, KAT_ExecuteRequest);
471 if (tservice == (struct rx_service *)0) {
472 ViceLog(0, ("Could not create Ticket Granting rx service\n"));
475 rx_SetMinProcs(tservice, 1);
476 rx_SetMaxProcs(tservice, 1);
478 scm[RX_SECIDX_NULL] = sca[RX_SECIDX_NULL];
479 scm[RX_SECIDX_VAB] = 0;
481 rxkad_NewServerSecurityObject(rxkad_crypt, 0, kvno_admin_key, 0);
483 rx_NewServiceHost(host, 0, KA_MAINTENANCE_SERVICE, "Maintenance", scm, 3,
485 if (tservice == (struct rx_service *)0) {
486 ViceLog(0, ("Could not create Maintenance rx service\n"));
489 rx_SetMinProcs(tservice, 1);
490 rx_SetMaxProcs(tservice, 1);
491 rx_SetStackSize(tservice, 10000);
494 rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", scm, 3,
495 RXSTATS_ExecuteRequest);
496 if (tservice == (struct rx_service *)0) {
497 ViceLog(0, ("Could not create rpc stats rx service\n"));
500 rx_SetMinProcs(tservice, 2);
501 rx_SetMaxProcs(tservice, 4);
505 /* allow super users to manage RX statistics */
506 rx_SetRxStatUserOk(KA_rxstat_userok);
508 rx_StartServer(0); /* start handling req. of all types */
510 if (init_kaprocs(lclpath, initFlags))
513 if ((code = init_krb_udp())) {
515 ("Failed to initialize UDP interface; code = %d.\n", code));
516 ViceLog(0, ("Running without UDP access.\n"));
519 ViceLog(0, ("Starting to process AuthServer requests\n"));
520 rx_ServerProc(NULL); /* donate this LWP */