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, (char *)0);
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 struct rx_securityClass *rxnull_NewServerSecurityObject();
173 extern int KAA_ExecuteRequest();
174 extern int KAT_ExecuteRequest();
175 extern int KAM_ExecuteRequest();
176 extern int RXSTATS_ExecuteRequest();
180 * The following signal action for AIX is necessary so that in case of a
181 * crash (i.e. core is generated) we can include the user's data section
182 * in the core dump. Unfortunately, by default, only a partial core is
183 * generated which, in many cases, isn't too useful.
185 struct sigaction nsa;
187 sigemptyset(&nsa.sa_mask);
188 nsa.sa_handler = SIG_DFL;
189 nsa.sa_flags = SA_FULLDUMP;
190 sigaction(SIGABRT, &nsa, NULL);
191 sigaction(SIGSEGV, &nsa, NULL);
195 printf("Usage: kaserver [-noAuth] [-fastKeys] [-database <dbpath>] "
196 "[-localfiles <lclpath>] [-minhours <n>] [-servers <serverlist>] "
197 /*" [-enable_peer_stats] [-enable_process_stats] " */
202 /* initialize winsock */
203 if (afs_winsockInit()<0) {
204 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0,
206 fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami);
210 /* Initialize dirpaths */
211 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
213 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
215 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
219 cellservdb = AFSDIR_SERVER_ETC_DIRPATH;
220 dbpath = AFSDIR_SERVER_KADB_FILEPATH;
221 strcompose(default_lclpath, AFSDIR_PATH_MAX,
222 AFSDIR_SERVER_LOCAL_DIRPATH, "/", AFSDIR_KADB_FILE, NULL);
223 lclpath = default_lclpath;
229 for (a=1; a<argc; a++) {
230 int arglen = strlen(argv[a]);
231 lcstring (arg, argv[a], sizeof(arg));
232 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
234 if (strcmp (arg, "-database") == 0) {
236 if (strcmp(lclpath, default_lclpath) == 0) lclpath = dbpath;
238 else if (strcmp (arg, "-localfiles") == 0) lclpath = argv[++a];
239 else if (strcmp (arg, "-servers") == 0) debugOutput++, servers = 1;
240 else if (strcmp (arg, "-noauth") == 0) debugOutput++, initFlags |= 1;
241 else if (strcmp (arg, "-fastkeys") == 0) debugOutput++, initFlags |= 4;
242 else if (strcmp (arg, "-dbfixup") == 0) debugOutput++, initFlags |= 8;
243 else if (strcmp (arg, "-cellservdb") == 0) {
244 cellservdb = argv[++a];
249 else if (IsArg("-crypt")) level = rxkad_crypt;
250 else if (IsArg("-safe")) level = rxkad_crypt;
251 else if (IsArg("-clear")) level = rxkad_clear;
252 else if (IsArg("-sorry")) level = rxkad_clear;
253 else if (IsArg("-debug")) verbose_track = 0;
254 else if (IsArg("-minhours")) {
255 MinHours = atoi(argv[++a]);
257 else if (IsArg("-enable_peer_stats")) {
258 rx_enablePeerRPCStats();
260 else if (IsArg("-enable_process_stats")) {
261 rx_enableProcessRPCStats();
263 else if (*arg == '-') {
264 /* hack to support help flag */
268 if (code = ka_CellConfig (cellservdb)) goto abort;
269 cell = ka_LocalCell();
270 KA_conf = afsconf_Open (cellservdb);
274 com_err (whoami, code, "Failed getting cell info");
280 /* NT & HPUX do not have dbm package support. So we can only do some
281 * text logging. So open the AuthLog file for logging and redirect
282 * stdin and stdout to it
284 OpenLog(AFSDIR_SERVER_KALOG_FILEPATH);
287 code = afsconf_GetExtendedCellInfo (KA_conf, cell, AFSCONF_KAUTHSERVICE,
290 if (code = ubik_ParseServerList(argc, argv, &myHost, serverList)) {
291 com_err(whoami, code, "Couldn't parse server list");
294 cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
295 for (i=1; i<MAXSERVERS; i++) {
296 if (!serverList[i]) break;
297 cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
299 cellinfo.numServers = i;
302 code = convert_cell_to_ubik (&cellinfo, &myHost, serverList);
303 if (code) goto abort;
304 ViceLog (0, ("Using server list from %s cell database.\n", cell));
307 /* initialize ubik */
308 if (level == rxkad_clear)
309 ubik_CRXSecurityProc = afsconf_ClientAuth;
310 else if (level == rxkad_crypt)
311 ubik_CRXSecurityProc = afsconf_ClientAuthSecure;
313 ViceLog(0, ("Unsupported security level %d\n", level));
316 ViceLog (0, ("Using level %s for Ubik connections.\n", (level == rxkad_crypt ? "crypt": "clear")));
317 ubik_CRXSecurityRock = (char *)KA_conf;
318 ubik_SRXSecurityProc = afsconf_ServerAuth;
319 ubik_SRXSecurityRock = (char *)KA_conf;
320 ubik_CheckRXSecurityProc = afsconf_CheckAuth;
321 ubik_CheckRXSecurityRock = (char *)KA_conf;
325 code = ubik_ServerInit (myHost, htons(AFSCONF_KAUTHPORT), serverList,
328 code = ubik_ServerInitByInfo (myHost, htons(AFSCONF_KAUTHPORT),
329 &cellinfo, &clones, dbpath, &KA_dbase);
332 com_err(whoami, code, "Ubik init failed");
336 sca[RX_SCINDEX_NULL] = rxnull_NewServerSecurityObject();
338 /* Disable jumbograms */
342 rx_NewService (0, KA_AUTHENTICATION_SERVICE, "AuthenticationService",
343 sca, 1, KAA_ExecuteRequest);
344 if (tservice == (struct rx_service *)0) {
345 ViceLog(0, ("Could not create Authentication rx service\n"));
348 rx_SetMinProcs(tservice, 1);
349 rx_SetMaxProcs(tservice, 1);
352 rx_NewService (0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService",
353 sca, 1, KAT_ExecuteRequest);
354 if (tservice == (struct rx_service *)0) {
355 ViceLog(0, ("Could not create Ticket Granting rx service\n"));
358 rx_SetMinProcs(tservice, 1);
359 rx_SetMaxProcs(tservice, 1);
361 scm[RX_SCINDEX_NULL] = sca[RX_SCINDEX_NULL];
362 scm[RX_SCINDEX_VAB] = 0;
363 scm[RX_SCINDEX_KAD] =
364 rxkad_NewServerSecurityObject (rxkad_crypt, 0, kvno_admin_key, 0);
365 tservice = rx_NewService(0, KA_MAINTENANCE_SERVICE, "Maintenance",
366 scm, 3, KAM_ExecuteRequest);
367 if (tservice == (struct rx_service *)0) {
368 ViceLog(0, ("Could not create Maintenance rx service\n"));
371 rx_SetMinProcs(tservice, 1);
372 rx_SetMaxProcs(tservice, 1);
373 rx_SetStackSize(tservice, 10000);
376 rx_NewService (0, RX_STATS_SERVICE_ID, "rpcstats",
377 scm, 3, RXSTATS_ExecuteRequest);
378 if (tservice == (struct rx_service *)0) {
379 ViceLog(0, ("Could not create rpc stats rx service\n"));
382 rx_SetMinProcs(tservice, 2);
383 rx_SetMaxProcs(tservice, 4);
387 /* allow super users to manage RX statistics */
388 rx_SetRxStatUserOk(KA_rxstat_userok);
390 rx_StartServer(0); /* start handling req. of all types */
392 if (init_kaprocs (lclpath, initFlags)) return -1;
394 if (code = init_krb_udp()) {
395 ViceLog (0, ("Failed to initialize UDP interface; code = %d.\n", code));
396 ViceLog (0, ("Running without UDP access.\n"));
399 ViceLog (0, ("Starting to process AuthServer requests\n"));
400 rx_ServerProc(); /* donate this LWP */