rxgen, kauth: Set but not used variables
[openafs.git] / src / kauth / kaserver.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
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
8  */
9
10 #include <afsconfig.h>
11 #include <afs/param.h>
12
13
14 #include <afs/stds.h>
15 #include <sys/types.h>
16 #ifdef AFS_NT40_ENV
17 #include <winsock2.h>
18 #include <WINNT/afsevent.h>
19 #else
20 #include <sys/file.h>
21 #include <netdb.h>
22 #include <netinet/in.h>
23 #endif
24 #include "kalog.h"              /* for OpenLog() */
25 #include <time.h>
26 #include <stdio.h>
27 #include <string.h>
28 #ifdef HAVE_FCNTL_H
29 #include <fcntl.h>
30 #endif
31 #ifdef  AFS_AIX32_ENV
32 #include <signal.h>
33 #endif
34 #include <lwp.h>
35 #include <rx/xdr.h>
36 #include <rx/rx.h>
37 #include <rx/rxstat.h>
38 #include <rx/rxkad.h>
39 #include <rx/rx_globals.h>
40 #include <afs/cellconfig.h>
41 #include <lock.h>
42 #include <afs/afsutil.h>
43 #include <afs/com_err.h>
44 #include <afs/audit.h>
45 #include <ubik.h>
46 #include <sys/stat.h>
47 #include "kauth.h"
48 #include "kauth_internal.h"
49 #include "kautils.h"
50 #include "kaserver.h"
51 #include "kadatabase.h"
52 #include "kaprocs.h"
53
54 struct kadstats dynamic_statistics;
55 struct ubik_dbase *KA_dbase;
56 afs_uint32 myHost = 0;
57 afs_int32 verbose_track = 1;
58 afs_int32 krb4_cross = 0;
59 afs_int32 rxBind = 0;
60
61 #define ADDRSPERSITE 16         /* Same global is in rx/rx_user.c */
62 afs_uint32 SHostAddrs[ADDRSPERSITE];
63
64 struct afsconf_dir *KA_conf;    /* for getting cell info */
65
66 int MinHours = 0;
67 int npwSums = KA_NPWSUMS;       /* needs to be variable sometime */
68
69 #include <stdarg.h>
70 #if !defined(AFS_NT40_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN_ENV) && !defined(AFS_XBSD_ENV)
71 #undef vfprintf
72 #define vfprintf(stream,fmt,args) _doprnt(fmt,args,stream)
73 #endif
74
75 static int debugOutput;
76
77 /* check whether caller is authorized to manage RX statistics */
78 int
79 KA_rxstat_userok(struct rx_call *call)
80 {
81     return afsconf_SuperUser(KA_conf, call, NULL);
82 }
83
84 afs_int32
85 es_Report(char *fmt, ...)
86 {
87     va_list pvar;
88
89     if (debugOutput == 0)
90         return 0;
91     va_start(pvar, fmt);
92     vfprintf(stderr, fmt, pvar);
93     va_end(pvar);
94     return 0;
95 }
96
97 static void
98 initialize_dstats(void)
99 {
100     memset(&dynamic_statistics, 0, sizeof(dynamic_statistics));
101     dynamic_statistics.start_time = time(0);
102     dynamic_statistics.host = myHost;
103 }
104
105 static int
106 convert_cell_to_ubik(struct afsconf_cell *cellinfo, afs_uint32 *myHost,
107                      afs_uint32 *serverList)
108 {
109     int i;
110     char hostname[64];
111     struct hostent *th;
112
113     /* get this host */
114     gethostname(hostname, sizeof(hostname));
115     th = gethostbyname(hostname);
116     if (!th) {
117         ViceLog(0, ("kaserver: couldn't get address of this host.\n"));
118         exit(1);
119     }
120     memcpy(myHost, th->h_addr, sizeof(afs_uint32));
121
122     for (i = 0; i < cellinfo->numServers; i++)
123         if (cellinfo->hostAddr[i].sin_addr.s_addr != *myHost) {
124             /* omit my host from serverList */
125             *serverList++ = cellinfo->hostAddr[i].sin_addr.s_addr;
126         }
127     *serverList = 0;            /* terminate list */
128     return 0;
129 }
130
131 static afs_int32
132 kvno_admin_key(void *rock, afs_int32 kvno, struct ktc_encryptionKey *key)
133 {
134     return ka_LookupKvno(0, KA_ADMIN_NAME, KA_ADMIN_INST, kvno, key);
135
136     /* we would like to start a Ubik transaction to fill the cache if that
137      * fails, but may deadlock as Rx is now organized. */
138 }
139
140 /* initFlags: 0x01  Do not require authenticated connections.
141               0x02  Do not check the bos NoAuth flag
142               0x04  Use fast key expiration to test oldkey code.
143               0x08  Temporary flag allowing database inconsistency fixup
144  */
145
146 #include "AFS_component_version_number.c"
147
148 int
149 main(int argc, char *argv[])
150 {
151     afs_int32 code;
152     char *whoami = argv[0];
153     afs_uint32 serverList[MAXSERVERS];
154     struct afsconf_cell cellinfo;
155     char *cell;
156     const char *cellservdb, *dbpath, *lclpath;
157     int a;
158     char arg[32];
159     char default_lclpath[AFSDIR_PATH_MAX];
160     int servers;
161     int initFlags;
162     int level;                  /* security level for Ubik */
163     afs_int32 i;
164     char clones[MAXHOSTSPERCELL];
165     afs_uint32 host = ntohl(INADDR_ANY);
166     char *auditFileName = NULL;
167
168     struct rx_service *tservice;
169     struct rx_securityClass *sca[1];
170     struct rx_securityClass *scm[3];
171
172     extern int rx_stackSize;
173
174 #ifdef  AFS_AIX32_ENV
175     /*
176      * The following signal action for AIX is necessary so that in case of a
177      * crash (i.e. core is generated) we can include the user's data section
178      * in the core dump. Unfortunately, by default, only a partial core is
179      * generated which, in many cases, isn't too useful.
180      */
181     struct sigaction nsa;
182
183     sigemptyset(&nsa.sa_mask);
184     nsa.sa_handler = SIG_DFL;
185     nsa.sa_flags = SA_FULLDUMP;
186     sigaction(SIGABRT, &nsa, NULL);
187     sigaction(SIGSEGV, &nsa, NULL);
188 #endif
189     osi_audit_init();
190
191     if (argc == 0) {
192       usage:
193         printf("Usage: kaserver [-noAuth] [-database <dbpath>] "
194                "[-auditlog <log path>] [-audit-interface <file|sysvmq>] "
195                "[-rxbind] [-localfiles <lclpath>] [-minhours <n>] "
196                "[-servers <serverlist>] [-crossrealm] "
197                /*" [-enable_peer_stats] [-enable_process_stats] " */
198                "[-help]\n");
199         exit(1);
200     }
201 #ifdef AFS_NT40_ENV
202     /* initialize winsock */
203     if (afs_winsockInit() < 0) {
204         ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0);
205         fprintf(stderr, "%s: Couldn't initialize winsock.\n", whoami);
206         exit(1);
207     }
208 #endif
209     /* Initialize dirpaths */
210     if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
211 #ifdef AFS_NT40_ENV
212         ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0);
213 #endif
214         fprintf(stderr, "%s: Unable to obtain AFS server directory.\n",
215                 argv[0]);
216         exit(2);
217     }
218
219     cellservdb = AFSDIR_SERVER_ETC_DIRPATH;
220     dbpath = AFSDIR_SERVER_KADB_FILEPATH;
221     strcompose(default_lclpath, AFSDIR_PATH_MAX, AFSDIR_SERVER_LOCAL_DIRPATH,
222                "/", AFSDIR_KADB_FILE, NULL);
223     lclpath = default_lclpath;
224
225     debugOutput = 0;
226     servers = 0;
227     initFlags = 0;
228     level = rxkad_crypt;
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)
233
234         if (strcmp(arg, "-database") == 0) {
235             dbpath = argv[++a];
236             if (strcmp(lclpath, default_lclpath) == 0)
237                 lclpath = dbpath;
238         }
239         else if (strncmp(arg, "-auditlog", arglen) == 0) {
240             auditFileName = argv[++a];
241
242         } else if (strncmp(arg, "-audit-interface", arglen) == 0) {
243             char *interface = argv[++a];
244
245             if (osi_audit_interface(interface)) {
246                 printf("Invalid audit interface '%s'\n", interface);
247                 exit(1);
248             }
249
250         } else if (strcmp(arg, "-localfiles") == 0)
251             lclpath = argv[++a];
252         else if (strcmp(arg, "-servers") == 0)
253             debugOutput++, servers = 1;
254         else if (strcmp(arg, "-noauth") == 0)
255             debugOutput++, initFlags |= 1;
256         else if (strcmp(arg, "-fastkeys") == 0)
257             debugOutput++, initFlags |= 4;
258         else if (strcmp(arg, "-dbfixup") == 0)
259             debugOutput++, initFlags |= 8;
260         else if (strcmp(arg, "-cellservdb") == 0) {
261             cellservdb = argv[++a];
262             initFlags |= 2;
263             debugOutput++;
264         }
265
266         else if (IsArg("-crypt"))
267             level = rxkad_crypt;
268         else if (IsArg("-safe"))
269             level = rxkad_crypt;
270         else if (IsArg("-clear"))
271             level = rxkad_clear;
272         else if (IsArg("-sorry"))
273             level = rxkad_clear;
274         else if (IsArg("-debug"))
275             verbose_track = 0;
276         else if (IsArg("-crossrealm"))
277             krb4_cross = 1;
278         else if (IsArg("-rxbind"))
279             rxBind = 1;
280         else if (IsArg("-minhours")) {
281             MinHours = atoi(argv[++a]);
282         } else if (IsArg("-enable_peer_stats")) {
283             rx_enablePeerRPCStats();
284         } else if (IsArg("-enable_process_stats")) {
285             rx_enableProcessRPCStats();
286         } else if (*arg == '-') {
287             /* hack to support help flag */
288             goto usage;
289         }
290     }
291
292     if (auditFileName) {
293         osi_audit_file(auditFileName);
294     }
295
296     if ((code = ka_CellConfig(cellservdb)))
297         goto abort;
298     cell = ka_LocalCell();
299     KA_conf = afsconf_Open(cellservdb);
300     if (!KA_conf) {
301         code = KANOCELLS;
302       abort:
303         afs_com_err(whoami, code, "Failed getting cell info");
304         exit(1);
305     }
306 #ifdef        AUTH_DBM_LOG
307     kalog_Init();
308 #else
309     /* NT & HPUX do not have dbm package support. So we can only do some
310      * text logging. So open the AuthLog file for logging and redirect
311      * stdin and stdout to it
312      */
313     OpenLog(AFSDIR_SERVER_KALOG_FILEPATH);
314     SetupLogSignals();
315 #endif
316
317     fprintf(stderr, "%s: WARNING: kaserver is deprecated due to its weak security "
318             "properties.  Migrating to a Kerberos 5 KDC is advised.  "
319             "http://www.openafs.org/no-more-des.html\n", whoami);
320     ViceLog(0, ("WARNING: kaserver is deprecated due to its weak security properties.  "
321             "Migrating to a Kerberos 5 KDC is advised.  "
322             "http://www.openafs.org/no-more-des.html\n"));
323
324     code =
325         afsconf_GetExtendedCellInfo(KA_conf, cell, AFSCONF_KAUTHSERVICE,
326                                     &cellinfo, clones);
327     if (servers) {
328         if ((code = ubik_ParseServerList(argc, argv, &myHost, serverList))) {
329             afs_com_err(whoami, code, "Couldn't parse server list");
330             exit(1);
331         }
332         cellinfo.hostAddr[0].sin_addr.s_addr = myHost;
333         for (i = 1; i < MAXSERVERS; i++) {
334             if (!serverList[i])
335                 break;
336             cellinfo.hostAddr[i].sin_addr.s_addr = serverList[i];
337         }
338         cellinfo.numServers = i;
339     } else {
340         code = convert_cell_to_ubik(&cellinfo, &myHost, serverList);
341         if (code)
342             goto abort;
343         ViceLog(0, ("Using server list from %s cell database.\n", cell));
344     }
345
346     /* initialize ubik */
347     if (level == rxkad_clear)
348         ubik_CRXSecurityProc = afsconf_ClientAuth;
349     else if (level == rxkad_crypt)
350         ubik_CRXSecurityProc = afsconf_ClientAuthSecure;
351     else {
352         ViceLog(0, ("Unsupported security level %d\n", level));
353         exit(5);
354     }
355     ViceLog(0,
356             ("Using level %s for Ubik connections.\n",
357              (level == rxkad_crypt ? "crypt" : "clear")));
358     ubik_CRXSecurityRock = (char *)KA_conf;
359     ubik_SRXSecurityProc = afsconf_ServerAuth;
360     ubik_SRXSecurityRock = (char *)KA_conf;
361     ubik_CheckRXSecurityProc = afsconf_CheckAuth;
362     ubik_CheckRXSecurityRock = (char *)KA_conf;
363
364     ubik_nBuffers = 80;
365
366     if (rxBind) {
367         afs_int32 ccode;
368         if (AFSDIR_SERVER_NETRESTRICT_FILEPATH ||
369             AFSDIR_SERVER_NETINFO_FILEPATH) {
370             char reason[1024];
371             ccode = parseNetFiles(SHostAddrs, NULL, NULL,
372                                            ADDRSPERSITE, reason,
373                                            AFSDIR_SERVER_NETINFO_FILEPATH,
374                                            AFSDIR_SERVER_NETRESTRICT_FILEPATH);
375         } else
376         {
377             ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE);
378         }
379         if (ccode == 1) {
380             host = SHostAddrs[0];
381             rx_InitHost(host, htons(AFSCONF_KAUTHPORT));
382         }
383     }
384
385     if (servers)
386         code =
387             ubik_ServerInit(myHost, htons(AFSCONF_KAUTHPORT), serverList,
388                             dbpath, &KA_dbase);
389     else
390         code =
391             ubik_ServerInitByInfo(myHost, htons(AFSCONF_KAUTHPORT), &cellinfo,
392                                   clones, dbpath, &KA_dbase);
393
394     if (code) {
395         afs_com_err(whoami, code, "Ubik init failed");
396         exit(2);
397     }
398
399     sca[RX_SCINDEX_NULL] = rxnull_NewServerSecurityObject();
400
401     /* Disable jumbograms */
402     rx_SetNoJumbo();
403
404     tservice =
405         rx_NewServiceHost(host, 0, KA_AUTHENTICATION_SERVICE,
406                           "AuthenticationService", sca, 1, KAA_ExecuteRequest);
407     if (tservice == (struct rx_service *)0) {
408         ViceLog(0, ("Could not create Authentication rx service\n"));
409         exit(3);
410     }
411     rx_SetMinProcs(tservice, 1);
412     rx_SetMaxProcs(tservice, 1);
413
414
415     tservice =
416         rx_NewServiceHost(host, 0, KA_TICKET_GRANTING_SERVICE, "TicketGrantingService",
417                       sca, 1, KAT_ExecuteRequest);
418     if (tservice == (struct rx_service *)0) {
419         ViceLog(0, ("Could not create Ticket Granting rx service\n"));
420         exit(3);
421     }
422     rx_SetMinProcs(tservice, 1);
423     rx_SetMaxProcs(tservice, 1);
424
425     scm[RX_SCINDEX_NULL] = sca[RX_SCINDEX_NULL];
426     scm[RX_SCINDEX_VAB] = 0;
427     scm[RX_SCINDEX_KAD] =
428         rxkad_NewServerSecurityObject(rxkad_crypt, 0, kvno_admin_key, 0);
429     tservice =
430         rx_NewServiceHost(host, 0, KA_MAINTENANCE_SERVICE, "Maintenance", scm, 3,
431                       KAM_ExecuteRequest);
432     if (tservice == (struct rx_service *)0) {
433         ViceLog(0, ("Could not create Maintenance rx service\n"));
434         exit(3);
435     }
436     rx_SetMinProcs(tservice, 1);
437     rx_SetMaxProcs(tservice, 1);
438     rx_SetStackSize(tservice, 10000);
439
440     tservice =
441         rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", scm, 3,
442                       RXSTATS_ExecuteRequest);
443     if (tservice == (struct rx_service *)0) {
444         ViceLog(0, ("Could not create rpc stats rx service\n"));
445         exit(3);
446     }
447     rx_SetMinProcs(tservice, 2);
448     rx_SetMaxProcs(tservice, 4);
449
450     initialize_dstats();
451
452     /* allow super users to manage RX statistics */
453     rx_SetRxStatUserOk(KA_rxstat_userok);
454
455     rx_StartServer(0);          /* start handling req. of all types */
456
457     if (init_kaprocs(lclpath, initFlags))
458         return -1;
459
460     if ((code = init_krb_udp())) {
461         ViceLog(0,
462                 ("Failed to initialize UDP interface; code = %d.\n", code));
463         ViceLog(0, ("Running without UDP access.\n"));
464     }
465
466     ViceLog(0, ("Starting to process AuthServer requests\n"));
467     rx_ServerProc(NULL);                /* donate this LWP */
468     return 0;
469 }