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>
20 #include <WINNT/afsevent.h>
24 #include <netinet/in.h>
26 #include "kalog.h" /* for OpenLog() */
36 #include <rx/rx_globals.h>
37 #include <afs/cellconfig.h>
39 #include <afs/afsutil.h>
46 struct kadstats dynamic_statistics;
47 struct ubik_dbase *KA_dbase;
49 afs_int32 verbose_track = 1;
50 struct afsconf_dir *KA_conf; /* for getting cell info */
52 extern afs_int32 ubik_lastYesTime;
53 extern afs_int32 ubik_nBuffers;
55 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_FBSD_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 */
66 int KA_rxstat_userok(call)
69 return afsconf_SuperUser(KA_conf, call, (char *)0);
72 afs_int32 es_Report(char *fmt, ...)
76 if (debugOutput == 0) return 0;
78 vfprintf (stderr, fmt, pvar);
83 static void initialize_dstats ()
85 memset(&dynamic_statistics, 0, sizeof(dynamic_statistics));
86 dynamic_statistics.start_time = time(0);
87 dynamic_statistics.host = myHost;
90 static int convert_cell_to_ubik (cellinfo, myHost, serverList)
91 struct afsconf_cell *cellinfo;
93 afs_int32 *serverList;
99 gethostname(hostname,sizeof(hostname));
100 th = gethostbyname(hostname);
102 ViceLog(0, ("kaserver: couldn't get address of this host.\n"));
105 memcpy(myHost, th->h_addr, sizeof(afs_int32));
107 for (i=0; i<cellinfo->numServers; i++)
108 if (cellinfo->hostAddr[i].sin_addr.s_addr != *myHost) {
109 /* omit my host from serverList */
110 *serverList++ = cellinfo->hostAddr[i].sin_addr.s_addr;
112 *serverList = 0; /* terminate list */
116 static afs_int32 kvno_admin_key (rock, kvno, key)
119 struct ktc_encryptionKey *key;
121 return ka_LookupKvno (0, KA_ADMIN_NAME, KA_ADMIN_INST, kvno, key);
123 /* we would like to start a Ubik transaction to fill the cache if that
124 fails, but may deadlock as Rx is now organized. */
127 /* initFlags: 0x01 Do not require authenticated connections.
128 0x02 Do not check the bos NoAuth flag
129 0x04 Use fast key expiration to test oldkey code.
130 0x08 Temporary flag allowing database inconsistency fixup
133 #include "AFS_component_version_number.c"
140 char *whoami = argv[0];
141 afs_int32 serverList[MAXSERVERS];
142 struct afsconf_cell cellinfo;
144 const char *cellservdb, *dbpath, *lclpath;
147 char default_lclpath[AFSDIR_PATH_MAX];
150 int level; /* security level for Ubik */
152 char clones[MAXHOSTSPERCELL];
154 struct rx_service *tservice;
155 struct rx_securityClass *sca[1];
156 struct rx_securityClass *scm[3];
158 extern int afsconf_ClientAuthSecure();
159 extern int afsconf_ServerAuth();
160 extern int afsconf_CheckAuth();
162 extern int rx_stackSize;
163 extern struct rx_securityClass *rxnull_NewServerSecurityObject();
164 extern int KAA_ExecuteRequest();
165 extern int KAT_ExecuteRequest();
166 extern int KAM_ExecuteRequest();
167 extern int RXSTATS_ExecuteRequest();
171 * The following signal action for AIX is necessary so that in case of a
172 * crash (i.e. core is generated) we can include the user's data section
173 * in the core dump. Unfortunately, by default, only a partial core is
174 * generated which, in many cases, isn't too useful.
176 struct sigaction nsa;
178 sigemptyset(&nsa.sa_mask);
179 nsa.sa_handler = SIG_DFL;
180 nsa.sa_flags = SA_FULLDUMP;
181 sigaction(SIGABRT, &nsa, NULL);
182 sigaction(SIGSEGV, &nsa, NULL);
186 printf("Usage: kaserver [-noAuth] [-fastKeys] [-database <dbpath>] "
187 "[-localfiles <lclpath>] [-minhours <n>] [-servers <serverlist>] "
188 /*" [-enable_peer_stats] [-enable_process_stats] " */
193 /* initialize winsock */
194 if (afs_winsockInit()<0) {
195 ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0,
197 fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami);
201 /* Initialize dirpaths */
202 if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
204 ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
206 fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
210 cellservdb = AFSDIR_SERVER_ETC_DIRPATH;
211 dbpath = AFSDIR_SERVER_KADB_FILEPATH;
212 strcompose(default_lclpath, AFSDIR_PATH_MAX,
213 AFSDIR_SERVER_LOCAL_DIRPATH, "/", AFSDIR_KADB_FILE, NULL);
214 lclpath = default_lclpath;
220 for (a=1; a<argc; a++) {
221 int arglen = strlen(argv[a]);
222 lcstring (arg, argv[a], sizeof(arg));
223 #define IsArg(a) (strncmp (arg,a, arglen) == 0)
225 if (strcmp (arg, "-database") == 0) {
227 if (strcmp(lclpath, default_lclpath) == 0) lclpath = dbpath;
229 else if (strcmp (arg, "-localfiles") == 0) lclpath = argv[++a];
230 else if (strcmp (arg, "-servers") == 0) debugOutput++, servers = 1;
231 else if (strcmp (arg, "-noauth") == 0) debugOutput++, initFlags |= 1;
232 else if (strcmp (arg, "-fastkeys") == 0) debugOutput++, initFlags |= 4;
233 else if (strcmp (arg, "-dbfixup") == 0) debugOutput++, initFlags |= 8;
234 else if (strcmp (arg, "-cellservdb") == 0) {
235 cellservdb = argv[++a];
240 else if (IsArg("-crypt")) level = rxkad_crypt;
241 else if (IsArg("-safe")) level = rxkad_crypt;
242 else if (IsArg("-clear")) level = rxkad_clear;
243 else if (IsArg("-sorry")) level = rxkad_clear;
244 else if (IsArg("-debug")) verbose_track = 0;
245 else if (IsArg("-minhours")) {
246 MinHours = atoi(argv[++a]);
248 else if (IsArg("-enable_peer_stats")) {
249 rx_enablePeerRPCStats();
251 else if (IsArg("-enable_process_stats")) {
252 rx_enableProcessRPCStats();
254 else if (*arg == '-') {
255 /* hack to support help flag */
259 if (code = ka_CellConfig (cellservdb)) goto abort;
260 cell = ka_LocalCell();
261 KA_conf = afsconf_Open (cellservdb);
265 com_err (whoami, code, "Failed getting cell info");
271 /* NT & HPUX do not have dbm package support. So we can only do some
272 * text logging. So open the AuthLog file for logging and redirect
273 * stdin and stdout to it
275 OpenLog(AFSDIR_SERVER_KALOG_FILEPATH);
278 code = afsconf_GetExtendedCellInfo (KA_conf, cell, AFSCONF_KAUTHSERVICE,
281 if (code = ubik_ParseServerList(argc, argv, &myHost, serverList)) {
282 com_err(whoami, code, "Couldn't parse server list");
285 cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
286 for (i=1; i<MAXSERVERS; i++) {
287 if (!serverList[i]) break;
288 cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
290 cellinfo.numServers = i;
293 code = convert_cell_to_ubik (&cellinfo, &myHost, serverList);
294 if (code) goto abort;
295 ViceLog (0, ("Using server list from %s cell database.\n", cell));
298 /* initialize ubik */
299 if (level == rxkad_clear)
300 ubik_CRXSecurityProc = afsconf_ClientAuth;
301 else if (level == rxkad_crypt)
302 ubik_CRXSecurityProc = afsconf_ClientAuthSecure;
304 ViceLog(0, ("Unsupported security level %d\n", level));
307 ViceLog (0, ("Using level %s for Ubik connections.\n", (level == rxkad_crypt ? "crypt": "clear")));
308 ubik_CRXSecurityRock = (char *)KA_conf;
309 ubik_SRXSecurityProc = afsconf_ServerAuth;
310 ubik_SRXSecurityRock = (char *)KA_conf;
311 ubik_CheckRXSecurityProc = afsconf_CheckAuth;
312 ubik_CheckRXSecurityRock = (char *)KA_conf;
316 code = ubik_ServerInit (myHost, htons(AFSCONF_KAUTHPORT), serverList,
319 code = ubik_ServerInitByInfo (myHost, htons(AFSCONF_KAUTHPORT),
320 &cellinfo, &clones, dbpath, &KA_dbase);
323 com_err(whoami, code, "Ubik init failed");
327 sca[RX_SCINDEX_NULL] = rxnull_NewServerSecurityObject();
329 /* These two lines disallow jumbograms */
330 rx_maxReceiveSize = OLD_MAX_PACKET_SIZE;
331 rxi_nSendFrags = rxi_nRecvFrags = 1;
334 rx_NewService (0, KA_AUTHENTICATION_SERVICE, "AuthenticationService",
335 sca, 1, KAA_ExecuteRequest);
336 if (tservice == (struct rx_service *)0) {
337 ViceLog(0, ("Could not create Authentication rx service\n"));
340 rx_SetMinProcs(tservice, 1);
341 rx_SetMaxProcs(tservice, 1);
344 rx_NewService (0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService",
345 sca, 1, KAT_ExecuteRequest);
346 if (tservice == (struct rx_service *)0) {
347 ViceLog(0, ("Could not create Ticket Granting rx service\n"));
350 rx_SetMinProcs(tservice, 1);
351 rx_SetMaxProcs(tservice, 1);
353 scm[RX_SCINDEX_NULL] = sca[RX_SCINDEX_NULL];
354 scm[RX_SCINDEX_VAB] = 0;
355 scm[RX_SCINDEX_KAD] =
356 rxkad_NewServerSecurityObject (rxkad_crypt, 0, kvno_admin_key, 0);
357 tservice = rx_NewService(0, KA_MAINTENANCE_SERVICE, "Maintenance",
358 scm, 3, KAM_ExecuteRequest);
359 if (tservice == (struct rx_service *)0) {
360 ViceLog(0, ("Could not create Maintenance rx service\n"));
363 rx_SetMinProcs(tservice, 1);
364 rx_SetMaxProcs(tservice, 1);
365 rx_SetStackSize(tservice, 10000);
368 rx_NewService (0, RX_STATS_SERVICE_ID, "rpcstats",
369 scm, 3, RXSTATS_ExecuteRequest);
370 if (tservice == (struct rx_service *)0) {
371 ViceLog(0, ("Could not create rpc stats rx service\n"));
374 rx_SetMinProcs(tservice, 2);
375 rx_SetMaxProcs(tservice, 4);
379 /* allow super users to manage RX statistics */
380 rx_SetRxStatUserOk(KA_rxstat_userok);
382 rx_StartServer(0); /* start handling req. of all types */
384 if (init_kaprocs (lclpath, initFlags)) return -1;
386 if (code = init_krb_udp()) {
387 ViceLog (0, ("Failed to initialize UDP interface; code = %d.\n", code));
388 ViceLog (0, ("Running without UDP access.\n"));
391 ViceLog (0, ("Starting to process AuthServer requests\n"));
392 rx_ServerProc(); /* donate this LWP */