da61e60af3fa4bb6436d04116ae1261c37f0f98e
[openafs.git] / src / ubik / uinit.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 RCSID
14     ("$Header$");
15
16 #include <afs/stds.h>
17 #ifdef AFS_NT40_ENV
18 #include <fcntl.h>
19 #include <winsock2.h>
20 #else
21 #include <sys/types.h>
22 #include <sys/file.h>
23 #include <netdb.h>
24 #include <netinet/in.h>
25 #endif /* AFS_NT40_ENV */
26 #include <sys/stat.h>
27 #ifdef AFS_AIX_ENV
28 #include <sys/statfs.h>
29 #endif
30
31 #include <string.h>
32
33 #include <afs/dirpath.h>
34 #include <errno.h>
35 #include <lock.h>
36 #include <rx/xdr.h>
37 #include <rx/rx.h>
38 #include <rx/rx_globals.h>
39 #include <afs/auth.h>
40 #include <afs/cellconfig.h>
41 #include <afs/keys.h>
42 #include <ubik.h>
43 #include <afs/afsint.h>
44 #include <afs/cmd.h>
45
46 /*
47   Get the appropriate type of ubik client structure out from the system.
48 */
49 afs_int32
50 ugen_ClientInit(int noAuthFlag, char *confDir, char *cellName, afs_int32 sauth,
51                struct ubik_client **uclientp, int (*secproc) (),
52                char *funcName, afs_int32 gen_rxkad_level, 
53                afs_int32 maxservers, char *serviceid, afs_int32 deadtime,
54                afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
55 {
56     afs_int32 code, scIndex, i;
57     struct afsconf_cell info;
58     struct afsconf_dir *tdir;
59     struct ktc_principal sname;
60     struct ktc_token ttoken;
61     struct rx_securityClass *sc;
62     /* This must change if VLDB_MAXSERVERS becomes larger than MAXSERVERS */
63     static struct rx_connection *serverconns[MAXSERVERS];
64     char cellstr[64];
65
66     code = rx_Init(0);
67     if (code) {
68         fprintf(stderr, "%s: could not initialize rx.\n", funcName);
69         return code;
70     }
71     rx_SetRxDeadTime(deadtime);
72
73     if (sauth) {                /* -localauth */
74         tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
75         if (!tdir) {
76             fprintf(stderr,
77                     "%s: Could not process files in configuration directory (%s).\n",
78                     funcName, AFSDIR_SERVER_ETC_DIRPATH);
79             return -1;
80         }
81         code = afsconf_ClientAuth(tdir, &sc, &scIndex); /* sets sc,scIndex */
82         if (code) {
83             afsconf_Close(tdir);
84             fprintf(stderr,
85                     "%s: Could not get security object for -localAuth\n",
86                     funcName);
87             return -1;
88         }
89         code =
90             afsconf_GetCellInfo(tdir, tdir->cellName, serviceid,
91                                 &info);
92         if (code) {
93             afsconf_Close(tdir);
94             fprintf(stderr,
95                     "%s: can't find cell %s's hosts in %s/%s\n",
96                     funcName, cellName, AFSDIR_SERVER_ETC_DIRPATH,
97                     AFSDIR_CELLSERVDB_FILE);
98             exit(1);
99         }
100     } else {                    /* not -localauth */
101         tdir = afsconf_Open(confDir);
102         if (!tdir) {
103             fprintf(stderr,
104                     "%s: Could not process files in configuration directory (%s).\n",
105                     funcName, confDir);
106             return -1;
107         }
108
109         if (!cellName) {
110             code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
111             if (code) {
112                 fprintf(stderr,
113                         "%s: can't get local cellname, check %s/%s\n",
114                         funcName, confDir, AFSDIR_THISCELL_FILE);
115                 exit(1);
116             }
117             cellName = cellstr;
118         }
119
120         code =
121             afsconf_GetCellInfo(tdir, cellName, serviceid, &info);
122         if (code) {
123             fprintf(stderr,
124                     "%s: can't find cell %s's hosts in %s/%s\n",
125                     funcName, cellName, confDir, AFSDIR_CELLSERVDB_FILE);
126             exit(1);
127         }
128         if (noAuthFlag)         /* -noauth */
129             scIndex = 0;
130         else {                  /* not -noauth */
131             strcpy(sname.cell, info.name);
132             sname.instance[0] = 0;
133             strcpy(sname.name, "afs");
134             code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
135             if (code) {         /* did not get ticket */
136                 fprintf(stderr,
137                         "%s: Could not get afs tokens, running unauthenticated.\n",
138                         funcName);
139                 scIndex = 0;
140             } else {            /* got a ticket */
141                 scIndex = 2;
142                 if ((ttoken.kvno < 0) || (ttoken.kvno > 256)) {
143                     fprintf(stderr,
144                             "%s: funny kvno (%d) in ticket, proceeding\n",
145                             funcName, ttoken.kvno);
146                 }
147             }
148         }
149
150         switch (scIndex) {
151         case 0:
152             sc = rxnull_NewClientSecurityObject();
153             break;
154         case 2:
155             sc = rxkad_NewClientSecurityObject(gen_rxkad_level,
156                                                &ttoken.sessionKey,
157                                                ttoken.kvno, ttoken.ticketLen,
158                                                ttoken.ticket);
159             break;
160         default:
161             fprintf(stderr, "%s: unsupported security index %d\n",
162                     funcName, scIndex);
163             exit(1);
164             break;
165         }
166     }
167
168     afsconf_Close(tdir);
169
170     if (secproc)        /* tell UV module about default authentication */
171         (*secproc) (sc, scIndex);
172     if (server) {
173         serverconns[0] = rx_NewConnection(server, port,
174                                           usrvid, sc, scIndex);
175     } else {
176         if (info.numServers > maxservers) {
177             fprintf(stderr,
178                     "%s: info.numServers=%d (> maxservers=%d)\n",
179                     funcName, info.numServers, maxservers);
180             exit(1);
181         }
182         for (i = 0; i < info.numServers; i++) {
183             serverconns[i] =
184                 rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
185                                  info.hostAddr[i].sin_port, usrvid,
186                                  sc, scIndex);
187         }
188     }
189     /* Are we just setting up connections, or is this really ubik stuff? */
190     if (uclientp) {
191         *uclientp = 0;
192         code = ubik_ClientInit(serverconns, uclientp);
193         if (code) {
194             fprintf(stderr, "%s: ubik client init failed.\n", funcName);
195             return code;
196         }
197     }
198     return 0;
199 }
200
201