Commit | Line | Data |
---|---|---|
805e021f CE |
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 | /* | |
11 | * A general description of the supergroup changes | |
12 | * to ptserver: | |
13 | * | |
14 | * In AFS users can be members of groups. When you add | |
15 | * a user, u1, to a group, g1, you add the user id for u1 | |
16 | * to an entries list in g1. This is a list of all the | |
17 | * members of g1. | |
18 | * You also add the id for g1 to an entries list in u1. | |
19 | * This is a list of all the groups this user is a | |
20 | * member of. | |
21 | * The list has room for 10 entries. If more are required, | |
22 | * a continuation record is created. | |
23 | * | |
24 | * With UMICH mods, u1 can be a group. When u1 is a group | |
25 | * a new field is required to list the groups this group | |
26 | * is a member of (since the entries field is used to | |
27 | * list it's members). This new field is supergroups and | |
28 | * has two entries. If more are required, a continuation | |
29 | * record is formed. | |
30 | * There are two additional fields required, nextsg is | |
31 | * an address of the next continuation record for this | |
32 | * group, and countsg is the count for the number of | |
33 | * groups this group is a member of. | |
34 | * | |
35 | * | |
36 | * | |
37 | * 09/18/95 jjm Add mdw's changes to afs-3.3a Changes: | |
38 | * (1) Add the parameter -groupdepth or -depth to | |
39 | * define the maximum search depth for supergroups. | |
40 | * Define the variable depthsg to be the value of | |
41 | * the parameter. The default value is set to 5. | |
42 | * | |
43 | * (3) Make sure the sizes of the struct prentry and | |
44 | * struct prentryg are equal. If they aren't equal | |
45 | * the pt database will be corrupted. | |
46 | * The error is reported with an fprintf statement, | |
47 | * but this doesn't print when ptserver is started by | |
48 | * bos, so all you see is an error message in the | |
49 | * /usr/afs/logs/BosLog file. If you start the | |
50 | * ptserver without bos the fprintf will print | |
51 | * on stdout. | |
52 | * The program will terminate with a PT_EXIT(1). | |
53 | * | |
54 | * | |
55 | * Transarc does not currently use opcodes past 520, but | |
56 | * they *could* decide at any time to use more opcodes. | |
57 | * If they did, then one part of our local mods, | |
58 | * ListSupergroups, would break. I've therefore | |
59 | * renumbered it to 530, and put logic in to enable the | |
60 | * old opcode to work (for now). | |
61 | * | |
62 | * 2/1/98 jjm Add mdw's changes for bit mapping for supergroups | |
63 | * Overview: | |
64 | * Before fetching a supergroup, this version of ptserver | |
65 | * checks to see if it was marked "found" and "not a | |
66 | * member". If and only if so, it doesn't fetch the group. | |
67 | * Since this should be the case with most groups, this | |
68 | * should save a significant amount of CPU in redundant | |
69 | * fetches of the same group. After fetching the group, | |
70 | * it sets "found", and either sets or clears "not a | |
71 | * member", depending on if the group was a member of | |
72 | * other groups. When it writes group entries to the | |
73 | * database, it clears the "found" flag. | |
74 | */ | |
75 | ||
76 | #if defined(SUPERGROUPS) | |
77 | /* | |
78 | * A general description of the supergroup changes | |
79 | * to ptserver: | |
80 | * | |
81 | * In AFS users can be members of groups. When you add a user, u1, | |
82 | * to a group, g1, you add the user id for u1 to an entries list | |
83 | * in g1. This is a list of all the members of g1. You also add | |
84 | * the id for g1 to an entries list in u1. This is a list of all | |
85 | * the groups this user is a member of. The list has room for 10 | |
86 | * entries. If more are required, a continuation record is created. | |
87 | * | |
88 | * With UMICH mods, u1 can be a group. When u1 is a group a new | |
89 | * field is required to list the groups this group is a member of | |
90 | * (since the entries field is used to list it's members). This | |
91 | * new field is supergroups and has two entries. If more are | |
92 | * required, a continuation record is formed. | |
93 | * | |
94 | * There are two additional fields required, nextsg is an address | |
95 | * of the next continuation record for this group, and countsg is | |
96 | * the count for the number of groups this group is a member of. | |
97 | * | |
98 | * Bit mapping support for supergroups: | |
99 | * | |
100 | * Before fetching a supergroup, this version of ptserver checks to | |
101 | * see if it was marked "found" and "not a member". If and only if | |
102 | * so, it doesn't fetch the group. Since this should be the case | |
103 | * with most groups, this should save a significant amount of CPU in | |
104 | * redundant fetches of the same group. After fetching the group, it | |
105 | * sets "found", and either sets or clears "not a member", depending | |
106 | * on if the group was a member of other groups. When it writes | |
107 | * group entries to the database, it clears the "found" flag. | |
108 | */ | |
109 | #endif | |
110 | ||
111 | #include <afsconfig.h> | |
112 | #include <afs/param.h> | |
113 | #include <afs/stds.h> | |
114 | ||
115 | #include <roken.h> | |
116 | #include <afs/opr.h> | |
117 | #ifdef AFS_PTHREAD_ENV | |
118 | # include <opr/softsig.h> | |
119 | # include <afs/procmgmt_softsig.h> /* must come after softsig.h */ | |
120 | #endif | |
121 | ||
122 | #ifdef AFS_NT40_ENV | |
123 | #include <WINNT/afsevent.h> | |
124 | #endif | |
125 | ||
126 | #include <rx/xdr.h> | |
127 | #include <rx/rx.h> | |
128 | #include <rx/rx_globals.h> | |
129 | #include <rx/rxstat.h> | |
130 | #include <lock.h> | |
131 | #include <ubik.h> | |
132 | #include <afs/cmd.h> | |
133 | #include <afs/cellconfig.h> | |
134 | #include <afs/auth.h> | |
135 | #include <afs/keys.h> | |
136 | #include <afs/afsutil.h> | |
137 | #include <afs/audit.h> | |
138 | #include <afs/com_err.h> | |
139 | ||
140 | #include "ptserver.h" | |
141 | #include "ptprototypes.h" | |
142 | #include "error_macros.h" | |
143 | ||
144 | /* make all of these into a structure if you want */ | |
145 | struct prheader cheader; | |
146 | struct ubik_dbase *dbase; | |
147 | struct afsconf_dir *prdir; | |
148 | ||
149 | #if defined(SUPERGROUPS) | |
150 | extern afs_int32 depthsg; | |
151 | #endif | |
152 | ||
153 | int restricted = 0; | |
154 | int restrict_anonymous = 0; | |
155 | int rxMaxMTU = -1; | |
156 | int rxBind = 0; | |
157 | int rxkadDisableDotCheck = 0; | |
158 | ||
159 | #define ADDRSPERSITE 16 /* Same global is in rx/rx_user.c */ | |
160 | afs_uint32 SHostAddrs[ADDRSPERSITE]; | |
161 | ||
162 | static struct afsconf_cell info; | |
163 | ||
164 | extern int prp_group_default; | |
165 | extern int prp_user_default; | |
166 | ||
167 | #include "AFS_component_version_number.c" | |
168 | ||
169 | int | |
170 | prp_access_mask(char *s) | |
171 | { | |
172 | int r; | |
173 | if (*s >= '0' && *s <= '9') { | |
174 | return strtol(s, NULL, 0); | |
175 | } | |
176 | r = 0; | |
177 | while (*s) switch(*s++) | |
178 | { | |
179 | case 'S': r |= PRP_STATUS_ANY; break; | |
180 | case 's': r |= PRP_STATUS_MEM; break; | |
181 | case 'O': r |= PRP_OWNED_ANY; break; | |
182 | case 'M': r |= PRP_MEMBER_ANY; break; | |
183 | case 'm': r |= PRP_MEMBER_MEM; break; | |
184 | case 'A': r |= PRP_ADD_ANY; break; | |
185 | case 'a': r |= PRP_ADD_MEM; break; | |
186 | case 'r': r |= PRP_REMOVE_MEM; break; | |
187 | } | |
188 | return r; | |
189 | } | |
190 | ||
191 | /* check whether caller is authorized to manage RX statistics */ | |
192 | int | |
193 | pr_rxstat_userok(struct rx_call *call) | |
194 | { | |
195 | return afsconf_SuperUser(prdir, call, NULL); | |
196 | } | |
197 | ||
198 | /** | |
199 | * Return true if this name is a member of the local realm. | |
200 | */ | |
201 | int | |
202 | pr_IsLocalRealmMatch(void *rock, char *name, char *inst, char *cell) | |
203 | { | |
204 | struct afsconf_dir *dir = (struct afsconf_dir *)rock; | |
205 | afs_int32 islocal = 0; /* default to no */ | |
206 | int code; | |
207 | ||
208 | code = afsconf_IsLocalRealmMatch(dir, &islocal, name, inst, cell); | |
209 | if (code) { | |
210 | ViceLog(0, ("Failed local realm check; code=%d, name=%s, inst=%s, cell=%s\n", | |
211 | code, name, inst, cell)); | |
212 | } | |
213 | return islocal; | |
214 | } | |
215 | ||
216 | ||
217 | enum optionsList { | |
218 | OPT_database, | |
219 | OPT_access, | |
220 | OPT_groupdepth, | |
221 | OPT_restricted, | |
222 | OPT_restrict_anonymous, | |
223 | OPT_auditlog, | |
224 | OPT_auditiface, | |
225 | OPT_config, | |
226 | OPT_debug, | |
227 | OPT_logfile, | |
228 | OPT_threads, | |
229 | #ifdef HAVE_SYSLOG | |
230 | OPT_syslog, | |
231 | #endif | |
232 | OPT_peer, | |
233 | OPT_process, | |
234 | OPT_rxbind, | |
235 | OPT_rxmaxmtu, | |
236 | OPT_dotted, | |
237 | OPT_transarc_logs | |
238 | }; | |
239 | ||
240 | int | |
241 | main(int argc, char **argv) | |
242 | { | |
243 | afs_int32 code; | |
244 | afs_uint32 myHost; | |
245 | struct hostent *th; | |
246 | char hostname[64]; | |
247 | struct rx_service *tservice; | |
248 | struct rx_securityClass **securityClasses; | |
249 | afs_int32 numClasses; | |
250 | int lwps = 3; | |
251 | char clones[MAXHOSTSPERCELL]; | |
252 | afs_uint32 host = htonl(INADDR_ANY); | |
253 | struct cmd_syndesc *opts; | |
254 | struct cmd_item *list; | |
255 | ||
256 | char *pr_dbaseName; | |
257 | char *configDir; | |
258 | struct logOptions logopts; | |
259 | char *whoami = "ptserver"; | |
260 | ||
261 | char *auditFileName = NULL; | |
262 | char *interface = NULL; | |
263 | ||
264 | #ifdef AFS_AIX32_ENV | |
265 | /* | |
266 | * The following signal action for AIX is necessary so that in case of a | |
267 | * crash (i.e. core is generated) we can include the user's data section | |
268 | * in the core dump. Unfortunately, by default, only a partial core is | |
269 | * generated which, in many cases, isn't too useful. | |
270 | */ | |
271 | struct sigaction nsa; | |
272 | ||
273 | sigemptyset(&nsa.sa_mask); | |
274 | nsa.sa_handler = SIG_DFL; | |
275 | nsa.sa_flags = SA_FULLDUMP; | |
276 | sigaction(SIGABRT, &nsa, NULL); | |
277 | sigaction(SIGSEGV, &nsa, NULL); | |
278 | #endif | |
279 | osi_audit_init(); | |
280 | osi_audit(PTS_StartEvent, 0, AUD_END); | |
281 | ||
282 | /* Initialize dirpaths */ | |
283 | if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) { | |
284 | #ifdef AFS_NT40_ENV | |
285 | ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0], 0); | |
286 | #endif | |
287 | fprintf(stderr, "%s: Unable to obtain AFS server directory.\n", | |
288 | argv[0]); | |
289 | exit(2); | |
290 | } | |
291 | ||
292 | pr_dbaseName = strdup(AFSDIR_SERVER_PRDB_FILEPATH); | |
293 | configDir = strdup(AFSDIR_SERVER_ETC_DIRPATH); | |
294 | memset(&logopts, 0, sizeof(logopts)); | |
295 | ||
296 | #if defined(SUPERGROUPS) | |
297 | /* make sure the structures for database records are the same size */ | |
298 | if ((sizeof(struct prentry) != ENTRYSIZE) | |
299 | || (sizeof(struct prentryg) != ENTRYSIZE)) { | |
300 | fprintf(stderr, | |
301 | "The structures for the database records are different" | |
302 | " sizes\n" "struct prentry = %" AFS_SIZET_FMT "\n" | |
303 | "struct prentryg = %" AFS_SIZET_FMT "\n" | |
304 | "ENTRYSIZE = %d\n", sizeof(struct prentry), | |
305 | sizeof(struct prentryg), ENTRYSIZE); | |
306 | PT_EXIT(1); | |
307 | } | |
308 | #endif | |
309 | ||
310 | cmd_DisableAbbreviations(); | |
311 | cmd_DisablePositionalCommands(); | |
312 | opts = cmd_CreateSyntax(NULL, NULL, NULL, 0, NULL); | |
313 | ||
314 | /* ptserver specific options */ | |
315 | cmd_AddParmAtOffset(opts, OPT_database, "-database", CMD_SINGLE, | |
316 | CMD_OPTIONAL, "database file"); | |
317 | cmd_AddParmAlias(opts, OPT_database, "-db"); | |
318 | ||
319 | cmd_AddParmAtOffset(opts, OPT_access, "-default_access", CMD_LIST, | |
320 | CMD_OPTIONAL, "default access flags for new entries"); | |
321 | #if defined(SUPERGROUPS) | |
322 | cmd_AddParmAtOffset(opts, OPT_groupdepth, "-groupdepth", CMD_SINGLE, | |
323 | CMD_OPTIONAL, "max search depth for supergroups"); | |
324 | cmd_AddParmAlias(opts, OPT_groupdepth, "-depth"); | |
325 | #endif | |
326 | cmd_AddParmAtOffset(opts, OPT_restricted, "-restricted", CMD_FLAG, | |
327 | CMD_OPTIONAL, "enable restricted mode"); | |
328 | cmd_AddParmAtOffset(opts, OPT_restrict_anonymous, "-restrict_anonymous", | |
329 | CMD_FLAG, CMD_OPTIONAL, "enable restricted anonymous mode"); | |
330 | ||
331 | /* general server options */ | |
332 | cmd_AddParmAtOffset(opts, OPT_auditlog, "-auditlog", CMD_SINGLE, | |
333 | CMD_OPTIONAL, "location of audit log"); | |
334 | cmd_AddParmAtOffset(opts, OPT_auditiface, "-audit-interface", CMD_SINGLE, | |
335 | CMD_OPTIONAL, "interface to use for audit logging"); | |
336 | cmd_AddParmAtOffset(opts, OPT_config, "-config", CMD_SINGLE, | |
337 | CMD_OPTIONAL, "configuration location"); | |
338 | cmd_AddParmAtOffset(opts, OPT_debug, "-d", CMD_SINGLE, | |
339 | CMD_OPTIONAL, "debug level"); | |
340 | cmd_AddParmAtOffset(opts, OPT_logfile, "-logfile", CMD_SINGLE, | |
341 | CMD_OPTIONAL, "location of logfile"); | |
342 | cmd_AddParmAtOffset(opts, OPT_threads, "-p", CMD_SINGLE, | |
343 | CMD_OPTIONAL, "number of threads"); | |
344 | #ifdef HAVE_SYSLOG | |
345 | cmd_AddParmAtOffset(opts, OPT_syslog, "-syslog", CMD_SINGLE_OR_FLAG, | |
346 | CMD_OPTIONAL, "log to syslog"); | |
347 | #endif | |
348 | cmd_AddParmAtOffset(opts, OPT_transarc_logs, "-transarc-logs", CMD_FLAG, | |
349 | CMD_OPTIONAL, "enable Transarc style logging"); | |
350 | ||
351 | /* rx options */ | |
352 | cmd_AddParmAtOffset(opts, OPT_peer, "-enable_peer_stats", CMD_FLAG, | |
353 | CMD_OPTIONAL, "enable RX transport statistics"); | |
354 | cmd_AddParmAtOffset(opts, OPT_process, "-enable_process_stats", CMD_FLAG, | |
355 | CMD_OPTIONAL, "enable RX RPC statistics"); | |
356 | cmd_AddParmAtOffset(opts, OPT_rxbind, "-rxbind", CMD_FLAG, | |
357 | CMD_OPTIONAL, "bind only to the primary interface"); | |
358 | cmd_AddParmAtOffset(opts, OPT_rxmaxmtu, "-rxmaxmtu", CMD_SINGLE, | |
359 | CMD_OPTIONAL, "maximum MTU for RX"); | |
360 | ||
361 | /* rxkad options */ | |
362 | cmd_AddParmAtOffset(opts, OPT_dotted, "-allow-dotted-principals", | |
363 | CMD_FLAG, CMD_OPTIONAL, | |
364 | "permit Kerberos 5 principals with dots"); | |
365 | ||
366 | code = cmd_Parse(argc, argv, &opts); | |
367 | if (code == CMD_HELP) { | |
368 | PT_EXIT(0); | |
369 | } | |
370 | if (code) | |
371 | PT_EXIT(1); | |
372 | ||
373 | cmd_OptionAsString(opts, OPT_config, &configDir); | |
374 | ||
375 | cmd_OpenConfigFile(AFSDIR_SERVER_CONFIG_FILE_FILEPATH); | |
376 | cmd_SetCommandName("ptserver"); | |
377 | ||
378 | if (cmd_OptionAsList(opts, OPT_access, &list) == 0) { | |
379 | prp_user_default = prp_access_mask(list->data); | |
380 | if (list->next == NULL || list->next->data == NULL) { | |
381 | fprintf(stderr, "Missing second argument for -default_access\n"); | |
382 | PT_EXIT(1); | |
383 | } | |
384 | prp_group_default = prp_access_mask(list->next->data); | |
385 | } | |
386 | ||
387 | #if defined(SUPERGROUPS) | |
388 | cmd_OptionAsInt(opts, OPT_groupdepth, &depthsg); | |
389 | #endif | |
390 | ||
391 | cmd_OptionAsFlag(opts, OPT_restricted, &restricted); | |
392 | cmd_OptionAsFlag(opts, OPT_restrict_anonymous, &restrict_anonymous); | |
393 | ||
394 | /* general server options */ | |
395 | cmd_OptionAsString(opts, OPT_auditlog, &auditFileName); | |
396 | ||
397 | if (cmd_OptionAsString(opts, OPT_auditiface, &interface) == 0) { | |
398 | if (osi_audit_interface(interface)) { | |
399 | printf("Invalid audit interface '%s'\n", interface); | |
400 | PT_EXIT(1); | |
401 | } | |
402 | free(interface); | |
403 | } | |
404 | ||
405 | cmd_OptionAsString(opts, OPT_database, &pr_dbaseName); | |
406 | ||
407 | if (cmd_OptionAsInt(opts, OPT_threads, &lwps) == 0) { | |
408 | if (lwps > 64) { /* maximum of 64 */ | |
409 | printf("Warning: '-p %d' is too big; using %d instead\n", | |
410 | lwps, 64); | |
411 | lwps = 64; | |
412 | } else if (lwps < 3) { /* minimum of 3 */ | |
413 | printf("Warning: '-p %d' is too small; using %d instead\n", | |
414 | lwps, 3); | |
415 | lwps = 3; | |
416 | } | |
417 | } | |
418 | ||
419 | #ifdef HAVE_SYSLOG | |
420 | if (cmd_OptionPresent(opts, OPT_syslog)) { | |
421 | if (cmd_OptionPresent(opts, OPT_logfile)) { | |
422 | fprintf(stderr, "Invalid options: -syslog and -logfile are exclusive."); | |
423 | PT_EXIT(1); | |
424 | } | |
425 | if (cmd_OptionPresent(opts, OPT_transarc_logs)) { | |
426 | fprintf(stderr, "Invalid options: -syslog and -transarc-logs are exclusive."); | |
427 | PT_EXIT(1); | |
428 | } | |
429 | logopts.lopt_dest = logDest_syslog; | |
430 | logopts.lopt_facility = LOG_DAEMON; | |
431 | logopts.lopt_tag = "ptserver"; | |
432 | cmd_OptionAsInt(opts, OPT_syslog, &logopts.lopt_facility); | |
433 | } else | |
434 | #endif | |
435 | { | |
436 | logopts.lopt_dest = logDest_file; | |
437 | if (cmd_OptionPresent(opts, OPT_transarc_logs)) { | |
438 | logopts.lopt_rotateOnOpen = 1; | |
439 | logopts.lopt_rotateStyle = logRotate_old; | |
440 | } | |
441 | if (cmd_OptionPresent(opts, OPT_logfile)) | |
442 | cmd_OptionAsString(opts, OPT_logfile, (char**)&logopts.lopt_filename); | |
443 | else | |
444 | logopts.lopt_filename = AFSDIR_SERVER_PTLOG_FILEPATH; | |
445 | } | |
446 | cmd_OptionAsInt(opts, OPT_debug, &logopts.lopt_logLevel); | |
447 | ||
448 | /* rx options */ | |
449 | if (cmd_OptionPresent(opts, OPT_peer)) | |
450 | rx_enablePeerRPCStats(); | |
451 | ||
452 | if (cmd_OptionPresent(opts, OPT_process)) | |
453 | rx_enableProcessRPCStats(); | |
454 | ||
455 | cmd_OptionAsFlag(opts, OPT_rxbind, &rxBind); | |
456 | ||
457 | cmd_OptionAsInt(opts, OPT_rxmaxmtu, &rxMaxMTU); | |
458 | ||
459 | /* rxkad options */ | |
460 | cmd_OptionAsFlag(opts, OPT_dotted, &rxkadDisableDotCheck); | |
461 | ||
462 | cmd_FreeOptions(&opts); | |
463 | ||
464 | if (auditFileName) { | |
465 | osi_audit_file(auditFileName); | |
466 | osi_audit(PTS_StartEvent, 0, AUD_END); | |
467 | } | |
468 | ||
469 | OpenLog(&logopts); | |
470 | #ifdef AFS_PTHREAD_ENV | |
471 | opr_softsig_Init(); | |
472 | SetupLogSoftSignals(); | |
473 | #else | |
474 | SetupLogSignals(); | |
475 | #endif | |
476 | ||
477 | prdir = afsconf_Open(configDir); | |
478 | if (!prdir) { | |
479 | fprintf(stderr, "ptserver: can't open configuration directory.\n"); | |
480 | PT_EXIT(1); | |
481 | } | |
482 | if (afsconf_GetNoAuthFlag(prdir)) | |
483 | printf("ptserver: running unauthenticated\n"); | |
484 | ||
485 | #ifdef AFS_NT40_ENV | |
486 | /* initialize winsock */ | |
487 | if (afs_winsockInit() < 0) { | |
488 | ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0, argv[0], 0); | |
489 | ||
490 | fprintf(stderr, "ptserver: couldn't initialize winsock. \n"); | |
491 | PT_EXIT(1); | |
492 | } | |
493 | #endif | |
494 | /* get this host */ | |
495 | gethostname(hostname, sizeof(hostname)); | |
496 | th = gethostbyname(hostname); | |
497 | if (!th) { | |
498 | fprintf(stderr, "ptserver: couldn't get address of this host.\n"); | |
499 | PT_EXIT(1); | |
500 | } | |
501 | memcpy(&myHost, th->h_addr, sizeof(afs_uint32)); | |
502 | ||
503 | /* get list of servers */ | |
504 | code = | |
505 | afsconf_GetExtendedCellInfo(prdir, NULL, "afsprot", &info, clones); | |
506 | if (code) { | |
507 | afs_com_err(whoami, code, "Couldn't get server list"); | |
508 | PT_EXIT(2); | |
509 | } | |
510 | ||
511 | /* initialize audit user check */ | |
512 | osi_audit_set_user_check(prdir, pr_IsLocalRealmMatch); | |
513 | ||
514 | /* initialize ubik */ | |
515 | ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate, prdir); | |
516 | ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects, | |
517 | afsconf_CheckAuth, prdir); | |
518 | ||
519 | /* The max needed is when deleting an entry. A full CoEntry deletion | |
520 | * required removal from 39 entries. Each of which may refers to the entry | |
521 | * being deleted in one of its CoEntries. If a CoEntry is freed its | |
522 | * predecessor CoEntry will be modified as well. Any freed blocks also | |
523 | * modifies the database header. Counting the entry being deleted and its | |
524 | * CoEntry this adds up to as much as 1+1+39*3 = 119. If all these entries | |
525 | * and the header are in separate Ubik buffers then 120 buffers may be | |
526 | * required. */ | |
527 | ubik_nBuffers = 120 + /*fudge */ 40; | |
528 | ||
529 | if (rxBind) { | |
530 | afs_int32 ccode; | |
531 | if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || | |
532 | AFSDIR_SERVER_NETINFO_FILEPATH) { | |
533 | char reason[1024]; | |
534 | ccode = afsconf_ParseNetFiles(SHostAddrs, NULL, NULL, | |
535 | ADDRSPERSITE, reason, | |
536 | AFSDIR_SERVER_NETINFO_FILEPATH, | |
537 | AFSDIR_SERVER_NETRESTRICT_FILEPATH); | |
538 | } else | |
539 | { | |
540 | ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE); | |
541 | } | |
542 | if (ccode == 1) { | |
543 | host = SHostAddrs[0]; | |
544 | /* the following call is idempotent so if/when it gets called | |
545 | * again by the ubik init stuff, it doesn't really matter | |
546 | * -- klm | |
547 | */ | |
548 | rx_InitHost(host, htons(AFSCONF_PROTPORT)); | |
549 | } | |
550 | } | |
551 | ||
552 | /* Disable jumbograms */ | |
553 | rx_SetNoJumbo(); | |
554 | ||
555 | if (rxMaxMTU != -1) { | |
556 | if (rx_SetMaxMTU(rxMaxMTU) != 0) { | |
557 | printf("rxMaxMTU %d is invalid\n", rxMaxMTU); | |
558 | PT_EXIT(1); | |
559 | } | |
560 | } | |
561 | ||
562 | code = | |
563 | ubik_ServerInitByInfo(myHost, htons(AFSCONF_PROTPORT), &info, clones, | |
564 | pr_dbaseName, &dbase); | |
565 | if (code) { | |
566 | afs_com_err(whoami, code, "Ubik init failed"); | |
567 | PT_EXIT(2); | |
568 | } | |
569 | ||
570 | #if defined(SUPERGROUPS) | |
571 | pt_hook_write(); | |
572 | #endif | |
573 | ||
574 | afsconf_BuildServerSecurityObjects(prdir, &securityClasses, &numClasses); | |
575 | ||
576 | tservice = | |
577 | rx_NewServiceHost(host, 0, PRSRV, "Protection Server", securityClasses, | |
578 | numClasses, PR_ExecuteRequest); | |
579 | if (tservice == (struct rx_service *)0) { | |
580 | fprintf(stderr, "ptserver: Could not create new rx service.\n"); | |
581 | PT_EXIT(3); | |
582 | } | |
583 | rx_SetMinProcs(tservice, 2); | |
584 | rx_SetMaxProcs(tservice, lwps); | |
585 | if (rxkadDisableDotCheck) { | |
586 | rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS, | |
587 | (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK); | |
588 | } | |
589 | ||
590 | tservice = | |
591 | rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", | |
592 | securityClasses, numClasses, RXSTATS_ExecuteRequest); | |
593 | if (tservice == (struct rx_service *)0) { | |
594 | fprintf(stderr, "ptserver: Could not create new rx service.\n"); | |
595 | PT_EXIT(3); | |
596 | } | |
597 | rx_SetMinProcs(tservice, 2); | |
598 | rx_SetMaxProcs(tservice, 4); | |
599 | ||
600 | /* allow super users to manage RX statistics */ | |
601 | rx_SetRxStatUserOk(pr_rxstat_userok); | |
602 | ||
603 | LogCommandLine(argc, argv, "ptserver", | |
604 | #if defined(SUPERGROUPS) | |
605 | "1.1", | |
606 | #else | |
607 | "1.0", | |
608 | #endif | |
609 | "Starting AFS", FSLog); | |
610 | if (afsconf_GetLatestKey(prdir, NULL, NULL) == 0) { | |
611 | LogDesWarning(); | |
612 | } | |
613 | ||
614 | rx_StartServer(1); | |
615 | osi_audit(PTS_FinishEvent, -1, AUD_END); | |
616 | exit(0); | |
617 | } |