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