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