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>
16 #include <sys/types.h>
19 #include <WINNT/afsevent.h>
23 #include <netinet/in.h>
25 #include "kalog.h" /* for OpenLog() */
45 #include <rx/rx_globals.h>
46 #include <afs/cellconfig.h>
48 #include <afs/afsutil.h>
55 struct kadstats dynamic_statistics;
56 struct ubik_dbase *KA_dbase;
58 afs_int32 verbose_track = 1;
59 struct afsconf_dir *KA_conf; /* for getting cell info */
61 extern afs_int32 ubik_lastYesTime;
62 extern afs_int32 ubik_nBuffers;
64 int npwSums = KA_NPWSUMS; /* needs to be variable sometime */
67 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
69 #define vfprintf(stream,fmt,args) _doprnt(fmt,args,stream)
72 static int debugOutput;
74 /* check whether caller is authorized to manage RX statistics */
75 int KA_rxstat_userok(call)
78 return afsconf_SuperUser(KA_conf, call, NULL);
81 afs_int32 es_Report(char *fmt, ...)
85 if (debugOutput == 0) return 0;
87 vfprintf (stderr, fmt, pvar);
92 static void initialize_dstats ()
94 memset(&dynamic_statistics, 0, sizeof(dynamic_statistics));
95 dynamic_statistics.start_time = time(0);
96 dynamic_statistics.host = myHost;
99 static int convert_cell_to_ubik (cellinfo, myHost, serverList)
100 struct afsconf_cell *cellinfo;
102 afs_int32 *serverList;
108 gethostname(hostname,sizeof(hostname));
109 th = gethostbyname(hostname);
111 ViceLog(0, ("kaserver: couldn't get address of this host.\n"));
114 memcpy(myHost, th->h_addr, sizeof(afs_int32));
116 for (i=0; i<cellinfo->numServers; i++)
117 if (cellinfo->hostAddr[i].sin_addr.s_addr != *myHost) {
118 /* omit my host from serverList */
119 *serverList++ = cellinfo->hostAddr[i].sin_addr.s_addr;
121 *serverList = 0; /* terminate list */
125 static afs_int32 kvno_admin_key (rock, kvno, key)
128 struct ktc_encryptionKey *key;
130 return ka_LookupKvno (0, KA_ADMIN_NAME, KA_ADMIN_INST, kvno, key);
132 /* we would like to start a Ubik transaction to fill the cache if that
133 fails, but may deadlock as Rx is now organized. */
136 /* initFlags: 0x01 Do not require authenticated connections.
137 0x02 Do not check the bos NoAuth flag
138 0x04 Use fast key expiration to test oldkey code.
139 0x08 Temporary flag allowing database inconsistency fixup
142 #include "AFS_component_version_number.c"
149 char *whoami = argv[0];
150 afs_int32 serverList[MAXSERVERS];
151 struct afsconf_cell cellinfo;
153 const char *cellservdb, *dbpath, *lclpath;
156 char default_lclpath[AFSDIR_PATH_MAX];
159 int level; /* security level for Ubik */
161 char clones[MAXHOSTSPERCELL];
163 struct rx_service *tservice;
164 struct rx_securityClass *sca[1];
165 struct rx_securityClass *scm[3];
167 extern int afsconf_ClientAuthSecure();
168 extern int afsconf_ServerAuth();
169 extern int afsconf_CheckAuth();
171 extern int rx_stackSize;
172 extern int KAA_ExecuteRequest();
173 extern int KAT_ExecuteRequest();
174 extern int KAM_ExecuteRequest();
175 extern int RXSTATS_ExecuteRequest();
179 * The following signal action for AIX is necessary so that in case of a
180 * crash (i.e. core is generated) we can include the user's data section
181 * in the core dump. Unfortunately, by default, only a partial core is
182 * generated which, in many cases, isn't too useful.
184 struct sigaction nsa;
186 sigemptyset(&nsa.sa_mask);
187 nsa.sa_handler = SIG_DFL;
188 nsa.sa_flags = SA_FULLDUMP;
189 sigaction(SIGABRT, &nsa, NULL);
190 sigaction(SIGSEGV, &nsa, NULL);
194 printf("Usage: kaserver [-noAuth] [-fastKeys] [-database <dbpath>] "
195 "[-localfiles <lclpath>] [-minhours <n>] [-servers <serverlist>] "
196 /*" [-enable_peer_stats] [-enable_process_stats] " */
201 /* initialize winsock */
202 if (afs_winsockInit()<0) {
203 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0,
205 fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami);
209 /* Initialize dirpaths */
210 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
212 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
214 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
218 cellservdb = AFSDIR_SERVER_ETC_DIRPATH;
219 dbpath = AFSDIR_SERVER_KADB_FILEPATH;
220 strcompose(default_lclpath, AFSDIR_PATH_MAX,
221 AFSDIR_SERVER_LOCAL_DIRPATH, "/", AFSDIR_KADB_FILE, NULL);
222 lclpath = default_lclpath;
228 for (a=1; a<argc; a++) {
229 int arglen = strlen(argv[a]);
230 lcstring (arg, argv[a], sizeof(arg));
231 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
233 if (strcmp (arg, "-database") == 0) {
235 if (strcmp(lclpath, default_lclpath) == 0) lclpath = dbpath;
237 else if (strcmp (arg, "-localfiles") == 0) lclpath = argv[++a];
238 else if (strcmp (arg, "-servers") == 0) debugOutput++, servers = 1;
239 else if (strcmp (arg, "-noauth") == 0) debugOutput++, initFlags |= 1;
240 else if (strcmp (arg, "-fastkeys") == 0) debugOutput++, initFlags |= 4;
241 else if (strcmp (arg, "-dbfixup") == 0) debugOutput++, initFlags |= 8;
242 else if (strcmp (arg, "-cellservdb") == 0) {
243 cellservdb = argv[++a];
248 else if (IsArg("-crypt")) level = rxkad_crypt;
249 else if (IsArg("-safe")) level = rxkad_crypt;
250 else if (IsArg("-clear")) level = rxkad_clear;
251 else if (IsArg("-sorry")) level = rxkad_clear;
252 else if (IsArg("-debug")) verbose_track = 0;
253 else if (IsArg("-minhours")) {
254 MinHours = atoi(argv[++a]);
256 else if (IsArg("-enable_peer_stats")) {
257 rx_enablePeerRPCStats();
259 else if (IsArg("-enable_process_stats")) {
260 rx_enableProcessRPCStats();
262 else if (*arg == '-') {
263 /* hack to support help flag */
267 if (code = ka_CellConfig (cellservdb)) goto abort;
268 cell = ka_LocalCell();
269 KA_conf = afsconf_Open (cellservdb);
273 com_err (whoami, code, "Failed getting cell info");
279 /* NT & HPUX do not have dbm package support. So we can only do some
280 * text logging. So open the AuthLog file for logging and redirect
281 * stdin and stdout to it
283 OpenLog(AFSDIR_SERVER_KALOG_FILEPATH);
286 code = afsconf_GetExtendedCellInfo (KA_conf, cell, AFSCONF_KAUTHSERVICE,
289 if (code = ubik_ParseServerList(argc, argv, &myHost, serverList)) {
290 com_err(whoami, code, "Couldn't parse server list");
293 cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
294 for (i=1; i<MAXSERVERS; i++) {
295 if (!serverList[i]) break;
296 cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
298 cellinfo.numServers = i;
301 code = convert_cell_to_ubik (&cellinfo, &myHost, serverList);
302 if (code) goto abort;
303 ViceLog (0, ("Using server list from %s cell database.\n", cell));
306 /* initialize ubik */
307 if (level == rxkad_clear)
308 ubik_CRXSecurityProc = afsconf_ClientAuth;
309 else if (level == rxkad_crypt)
310 ubik_CRXSecurityProc = afsconf_ClientAuthSecure;
312 ViceLog(0, ("Unsupported security level %d\n", level));
315 ViceLog (0, ("Using level %s for Ubik connections.\n", (level == rxkad_crypt ? "crypt": "clear")));
316 ubik_CRXSecurityRock = (char *)KA_conf;
317 ubik_SRXSecurityProc = afsconf_ServerAuth;
318 ubik_SRXSecurityRock = (char *)KA_conf;
319 ubik_CheckRXSecurityProc = afsconf_CheckAuth;
320 ubik_CheckRXSecurityRock = (char *)KA_conf;
324 code = ubik_ServerInit (myHost, htons(AFSCONF_KAUTHPORT), serverList,
327 code = ubik_ServerInitByInfo (myHost, htons(AFSCONF_KAUTHPORT),
328 &cellinfo, &clones, dbpath, &KA_dbase);
331 com_err(whoami, code, "Ubik init failed");
335 sca[RX_SCINDEX_NULL] = rxnull_NewServerSecurityObject();
337 /* Disable jumbograms */
341 rx_NewService (0, KA_AUTHENTICATION_SERVICE, "AuthenticationService",
342 sca, 1, KAA_ExecuteRequest);
343 if (tservice == (struct rx_service *)0) {
344 ViceLog(0, ("Could not create Authentication rx service\n"));
347 rx_SetMinProcs(tservice, 1);
348 rx_SetMaxProcs(tservice, 1);
351 rx_NewService (0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService",
352 sca, 1, KAT_ExecuteRequest);
353 if (tservice == (struct rx_service *)0) {
354 ViceLog(0, ("Could not create Ticket Granting rx service\n"));
357 rx_SetMinProcs(tservice, 1);
358 rx_SetMaxProcs(tservice, 1);
360 scm[RX_SCINDEX_NULL] = sca[RX_SCINDEX_NULL];
361 scm[RX_SCINDEX_VAB] = 0;
362 scm[RX_SCINDEX_KAD] =
363 rxkad_NewServerSecurityObject (rxkad_crypt, 0, kvno_admin_key, 0);
364 tservice = rx_NewService(0, KA_MAINTENANCE_SERVICE, "Maintenance",
365 scm, 3, KAM_ExecuteRequest);
366 if (tservice == (struct rx_service *)0) {
367 ViceLog(0, ("Could not create Maintenance rx service\n"));
370 rx_SetMinProcs(tservice, 1);
371 rx_SetMaxProcs(tservice, 1);
372 rx_SetStackSize(tservice, 10000);
375 rx_NewService (0, RX_STATS_SERVICE_ID, "rpcstats",
376 scm, 3, RXSTATS_ExecuteRequest);
377 if (tservice == (struct rx_service *)0) {
378 ViceLog(0, ("Could not create rpc stats rx service\n"));
381 rx_SetMinProcs(tservice, 2);
382 rx_SetMaxProcs(tservice, 4);
386 /* allow super users to manage RX statistics */
387 rx_SetRxStatUserOk(KA_rxstat_userok);
389 rx_StartServer(0); /* start handling req. of all types */
391 if (init_kaprocs (lclpath, initFlags)) return -1;
393 if (code = init_krb_udp()) {
394 ViceLog (0, ("Failed to initialize UDP interface; code = %d.\n", code));
395 ViceLog (0, ("Running without UDP access.\n"));
398 ViceLog (0, ("Starting to process AuthServer requests\n"));
399 rx_ServerProc(); /* donate this LWP */