ptserver-remove-redundant-prototypes-20010629
[openafs.git] / src / ptserver / ptserver.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 <afs/param.h>
11 #include <afs/stds.h>
12 #ifdef  AFS_AIX32_ENV
13 #include <signal.h>
14 #endif
15 #include <sys/types.h>
16 #include <stdio.h>
17 #ifdef AFS_NT40_ENV 
18 #include <winsock2.h>
19 #include <WINNT/afsevent.h>
20 #else
21 #include <netdb.h>
22 #include <netinet/in.h>
23 #endif
24 #include <rx/xdr.h>
25 #include <rx/rx.h>
26 #include <rx/rx_globals.h>
27 #include <lock.h>
28 #include <ubik.h>
29 #include <afs/cellconfig.h>
30 #include <afs/auth.h>
31 #include <afs/keys.h>
32 #include "ptserver.h"
33 #include "error_macros.h"
34 #include "afs/audit.h"
35 #include <afs/afsutil.h>
36
37
38 /* make all of these into a structure if you want */
39 struct prheader cheader;
40 struct ubik_dbase *dbase;
41 struct afsconf_dir *prdir;
42
43 extern afs_int32 ubik_lastYesTime;
44 extern afs_int32 ubik_nBuffers;
45
46 extern int afsconf_ServerAuth();
47 extern int afsconf_CheckAuth();
48
49 int   pr_realmNameLen;
50 char *pr_realmName;
51
52 #include "AFS_component_version_number.c"
53
54 /* check whether caller is authorized to manage RX statistics */
55 int pr_rxstat_userok(call)
56     struct rx_call *call;
57 {
58     return afsconf_SuperUser(prdir, call, (char *)0);
59 }
60
61 void main (argc, argv)
62   int argc;
63   char **argv;
64 {
65     register afs_int32 code;
66     afs_int32 myHost;
67     register struct hostent *th;
68     char hostname[64];
69     struct rx_service *tservice;
70     struct rx_securityClass *sc[3];
71     extern struct rx_securityClass *rxnull_NewServerSecurityObject();
72     extern struct rx_securityClass *rxkad_NewServerSecurityObject();
73     extern int RXSTATS_ExecuteRequest();
74     extern int PR_ExecuteRequest();
75 #if 0
76     struct ktc_encryptionKey tkey;
77 #endif
78     struct afsconf_cell info;
79     int kerberosKeys;                   /* set if found some keys */
80     afs_int32 i,j;
81     int lwps = 3;
82     char clones[MAXHOSTSPERCELL];
83
84     const char *pr_dbaseName;
85     char *whoami = "ptserver";
86
87     int   a;
88     char  arg[100];
89     
90 #ifdef  AFS_AIX32_ENV
91     /*
92      * The following signal action for AIX is necessary so that in case of a 
93      * crash (i.e. core is generated) we can include the user's data section 
94      * in the core dump. Unfortunately, by default, only a partial core is
95      * generated which, in many cases, isn't too useful.
96      */
97     struct sigaction nsa;
98     
99     sigemptyset(&nsa.sa_mask);
100     nsa.sa_handler = SIG_DFL;
101     nsa.sa_flags = SA_FULLDUMP;
102     sigaction(SIGABRT, &nsa, NULL);
103     sigaction(SIGSEGV, &nsa, NULL);
104 #endif
105     osi_audit (PTS_StartEvent, 0, AUD_END);
106
107     /* Initialize dirpaths */
108     if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
109 #ifdef AFS_NT40_ENV
110         ReportErrorEventAlt(AFSEVT_SVR_NO_INSTALL_DIR, 0, argv[0],0);
111 #endif
112         fprintf(stderr,"%s: Unable to obtain AFS server directory.\n", argv[0]);
113         exit(2);
114     }
115
116     pr_dbaseName = AFSDIR_SERVER_PRDB_FILEPATH;
117
118     for (a=1; a<argc; a++) {
119         int alen;
120         lcstring (arg, argv[a], sizeof(arg));
121         alen = strlen (arg);
122         if ((strncmp (arg, "-database", alen) == 0) ||
123             (strncmp (arg, "-db", alen) == 0)) {
124             pr_dbaseName = argv[++a];   /* specify a database */
125         }
126         else if (strncmp(arg, "-p", alen) == 0) {
127            lwps = atoi(argv[++a]);
128            if (lwps > 16) {       /* maximum of 16 */
129               printf("Warning: '-p %d' is too big; using %d instead\n",
130                      lwps, 16);
131               lwps = 16;
132            } else if (lwps < 3) { /* minimum of 3 */
133               printf("Warning: '-p %d' is too small; using %d instead\n",
134                      lwps, 3);
135               lwps = 3;
136            }
137         }
138         else if (strncmp (arg, "-rebuild", alen) == 0) /* rebuildDB++ */ ;
139         else if (strncmp (arg, "-enable_peer_stats", alen) == 0) {
140             rx_enablePeerRPCStats();
141         }
142         else if (strncmp (arg, "-enable_process_stats", alen) == 0) {
143             rx_enableProcessRPCStats();
144         }
145 #ifndef AFS_NT40_ENV
146         else if (strncmp(arg, "-syslog", alen)==0) {
147             /* set syslog logging flag */
148             serverLogSyslog = 1;
149         } 
150         else if (strncmp(arg, "-syslog=", MIN(8,alen))==0) {
151             serverLogSyslog = 1;
152             serverLogSyslogFacility = atoi(arg+8);
153         }
154 #endif
155         else if (*arg == '-') {
156           usage:
157
158                 /* hack in help flag support */
159
160 #ifndef AFS_NT40_ENV
161                 printf ("Usage: ptserver [-database <db path>] "
162                         "[-syslog[=FACILITY]] "
163                         "[-p <number of processes>] [-rebuild] "
164                         "[-enable_peer_stats] [-enable_process_stats] "
165                         "[-help]\n");
166 #else
167                 printf ("Usage: ptserver [-database <db path>] "
168                         "[-p <number of processes>] [-rebuild] "
169                         "[-help]\n");
170 #endif
171                 fflush(stdout);
172
173             PT_EXIT(1);
174         }
175     }
176
177     OpenLog(AFSDIR_SERVER_PTLOG_FILEPATH);     /* set up logging */
178     SetupLogSignals();
179  
180     prdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
181     if (!prdir) {
182         fprintf (stderr, "ptserver: can't open configuration directory.\n");
183         PT_EXIT(1);
184     }
185     if (afsconf_GetNoAuthFlag(prdir))
186         printf ("ptserver: running unauthenticated\n");
187
188 #ifdef AFS_NT40_ENV 
189     /* initialize winsock */
190     if (afs_winsockInit()<0) {
191       ReportErrorEventAlt(AFSEVT_SVR_WINSOCK_INIT_FAILED, 0,
192                           argv[0],0);
193       
194       fprintf(stderr, "ptserver: couldn't initialize winsock. \n");
195       PT_EXIT(1);
196     }
197 #endif
198     /* get this host */
199     gethostname(hostname,sizeof(hostname));
200     th = gethostbyname(hostname);
201     if (!th) {
202         fprintf (stderr, "ptserver: couldn't get address of this host.\n");
203         PT_EXIT(1);
204     }
205     bcopy(th->h_addr,&myHost,sizeof(afs_int32));
206         
207     /* get list of servers */
208     code = afsconf_GetExtendedCellInfo(prdir,(char *)0,"afsprot",
209                        &info, &clones);
210     if (code) {
211         com_err (whoami, code, "Couldn't get server list");
212         PT_EXIT(2);
213     }
214     pr_realmName = info.name;
215     pr_realmNameLen = strlen (pr_realmName);
216
217 #if 0
218     /* get keys */
219     code = afsconf_GetKey(prdir,999,&tkey);
220     if (code) {
221         com_err (whoami, code, "couldn't get bcrypt keys from key file, ignoring.");
222     }
223 #endif
224     {   afs_int32 kvno;                 /* see if there is a KeyFile here */
225         struct ktc_encryptionKey key;
226         code = afsconf_GetLatestKey (prdir, &kvno, &key);
227         kerberosKeys = (code == 0);
228         if (!kerberosKeys)
229             printf ("ptserver: can't find any Kerberos keys, code = %d, ignoring\n", code);
230     }
231     if (kerberosKeys) {
232         /* initialize ubik */
233         ubik_CRXSecurityProc = afsconf_ClientAuth;
234         ubik_CRXSecurityRock = (char *)prdir;
235         ubik_SRXSecurityProc = afsconf_ServerAuth;
236         ubik_SRXSecurityRock = (char *)prdir;
237         ubik_CheckRXSecurityProc = afsconf_CheckAuth;
238         ubik_CheckRXSecurityRock = (char *)prdir;
239     }
240     /* The max needed is when deleting an entry.  A full CoEntry deletion
241      * required removal from 39 entries.  Each of which may refers to the entry
242      * being deleted in one of its CoEntries.  If a CoEntry is freed its
243      * predecessor CoEntry will be modified as well.  Any freed blocks also
244      * modifies the database header.  Counting the entry being deleted and its
245      * CoEntry this adds up to as much as 1+1+39*3 = 119.  If all these entries
246      * and the header are in separate Ubik buffers then 120 buffers may be
247      * required. */
248     ubik_nBuffers = 120 + /*fudge*/40;
249     code = ubik_ServerInitByInfo(myHost, htons(AFSCONF_PROTPORT), &info,
250                            &clones, pr_dbaseName, &dbase);
251     if (code) {
252         com_err (whoami, code, "Ubik init failed");
253         PT_EXIT(2);
254     }
255     sc[0] = rxnull_NewServerSecurityObject();
256     sc[1] = 0;
257     if (kerberosKeys) {
258         sc[2] = rxkad_NewServerSecurityObject
259             (0, prdir, afsconf_GetKey, (char *)0);
260     }
261     else sc[2] = sc[0];
262
263     /* These two lines disallow jumbograms */
264     rx_maxReceiveSize = OLD_MAX_PACKET_SIZE;
265     rxi_nSendFrags = rxi_nRecvFrags = 1;
266
267     tservice = rx_NewService(0,PRSRV,"Protection Server",sc,3,PR_ExecuteRequest);
268     if (tservice == (struct rx_service *)0) {
269         fprintf (stderr, "ptserver: Could not create new rx service.\n");
270         PT_EXIT(3);
271     }
272     rx_SetMinProcs(tservice,2);
273     rx_SetMaxProcs(tservice,lwps);
274
275     tservice = rx_NewService(0,RX_STATS_SERVICE_ID,"rpcstats",sc,3,RXSTATS_ExecuteRequest);
276     if (tservice == (struct rx_service *)0) {
277         fprintf (stderr, "ptserver: Could not create new rx service.\n");
278         PT_EXIT(3);
279     }
280     rx_SetMinProcs(tservice,2);
281     rx_SetMaxProcs(tservice,4);
282
283     /* allow super users to manage RX statistics */
284     rx_SetRxStatUserOk(pr_rxstat_userok);
285
286     rx_StartServer(1);
287     osi_audit (PTS_FinishEvent, -1, AUD_END);
288 }