afs: prevent double release of global lock afs_xvcb
[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 #include <afs/stds.h>
13
14 #include <roken.h>
15
16 #ifdef AFS_AIX_ENV
17 # include <sys/statfs.h>
18 #endif
19
20 #include <afs/dirpath.h>
21 #include <lock.h>
22 #include <rx/xdr.h>
23 #include <rx/rx.h>
24 #include <rx/rx_globals.h>
25 #include <afs/auth.h>
26 #include <afs/cellconfig.h>
27 #include <afs/keys.h>
28 #include "ubik.h"
29 #include <afs/afsint.h>
30 #include <afs/cmd.h>
31
32 static int
33 internal_client_init(struct afsconf_dir *dir, struct afsconf_cell *info,
34                      int secFlags, struct ubik_client **uclientp,
35                      ugen_secproc_func secproc,
36                      int maxservers, const char *serviceid, int deadtime,
37                      afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
38 {
39     int code, i;
40     afs_int32 scIndex;
41     struct rx_securityClass *sc;
42     /* This must change if VLDB_MAXSERVERS becomes larger than MAXSERVERS */
43     static struct rx_connection *serverconns[MAXSERVERS];
44     const char *progname;
45
46     progname = getprogname();
47     if (progname == NULL)
48         progname = "<unknown>";
49
50     code = rx_Init(0);
51     if (code) {
52         fprintf(stderr, "%s: could not initialize rx.\n", progname);
53         return code;
54     }
55     rx_SetRxDeadTime(deadtime);
56
57     code = afsconf_PickClientSecObj(dir, secFlags, info, NULL, &sc,
58                                     &scIndex, NULL);
59     if (code) {
60         fprintf(stderr, "%s: can't create client security object", progname);
61         return code;
62     }
63
64     if (scIndex == RX_SECIDX_NULL && !(secFlags & AFSCONF_SECOPTS_NOAUTH)) {
65         fprintf(stderr,
66                 "%s: Could not get afs tokens, running unauthenticated.\n",
67                 progname);
68     }
69
70     if (secproc)        /* tell UV module about default authentication */
71         (*secproc) (sc, scIndex);
72
73     if (server) {
74         serverconns[0] = rx_NewConnection(server, port,
75                                           usrvid, sc, scIndex);
76     } else {
77         if (info->numServers > maxservers) {
78             fprintf(stderr,
79                     "%s: info.numServers=%d (> maxservers=%d)\n",
80                     progname, info->numServers, maxservers);
81             return -1;
82         }
83         for (i = 0; i < info->numServers; i++) {
84             if (!info->hostAddr[i].sin_port && port)
85                 info->hostAddr[i].sin_port = port;
86             serverconns[i] =
87                 rx_NewConnection(info->hostAddr[i].sin_addr.s_addr,
88                                  info->hostAddr[i].sin_port, usrvid,
89                                  sc, scIndex);
90         }
91     }
92     /* Are we just setting up connections, or is this really ubik stuff? */
93     if (uclientp) {
94         *uclientp = 0;
95         code = ubik_ClientInit(serverconns, uclientp);
96         if (code) {
97             fprintf(stderr, "%s: ubik client init failed.\n", progname);
98             return code;
99         }
100     }
101
102     return 0;
103 }
104
105 int
106 ugen_ClientInitCell(struct afsconf_dir *dir, struct afsconf_cell *info,
107                     int secFlags, struct ubik_client **uclientp,
108                     int maxservers, const char *serviceid, int deadtime)
109 {
110     return internal_client_init(dir, info, secFlags, uclientp, NULL,
111                                 maxservers, serviceid, deadtime, 0, 0,
112                                 USER_SERVICE_ID);
113 }
114
115 static int
116 internal_client_init_dir(const char *confDir, char *cellName, int secFlags,
117                       struct ubik_client **uclientp,
118                       ugen_secproc_func secproc,
119                       afs_int32 maxservers, char *serviceid, afs_int32 deadtime,
120                       afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
121 {
122     int code;
123     const char *progname;
124     struct afsconf_dir *dir;
125     struct afsconf_cell info;
126
127     progname = getprogname();
128     if (progname == NULL)
129         progname = "<unknown>";
130
131     if (confDir == NULL)
132         confDir = AFSDIR_CLIENT_ETC_DIRPATH;
133
134     dir = afsconf_Open(confDir);
135     if (!dir) {
136         fprintf(stderr,
137                 "%s: Could not process files in configuration directory (%s).\n",
138                 progname, confDir);
139         return EIO;
140     }
141
142     if (cellName == NULL)
143         cellName = dir->cellName;
144
145     code = afsconf_GetCellInfo(dir, cellName, serviceid, &info);
146     if (code) {
147         fprintf(stderr, "%s: can't find cell %s's hosts in %s\n",
148                 progname?progname:"<unknown>", cellName, dir->cellservDB);
149         afsconf_Close(dir);
150         return code;
151     }
152
153     code = internal_client_init(dir, &info, secFlags, uclientp, secproc,
154                                 maxservers, serviceid, deadtime, server,
155                                 port, usrvid);
156
157     afsconf_Close(dir);
158
159     return code;
160 }
161
162 int
163 ugen_ClientInitServer(const char *confDir, char *cellName, int secFlags,
164                       struct ubik_client **uclientp, int maxservers,
165                       char *serviceid, int deadtime, afs_uint32 server,
166                       afs_uint32 port)
167 {
168
169     return internal_client_init_dir(confDir, cellName, secFlags, uclientp,
170                                     NULL, maxservers, serviceid, deadtime,
171                                     server, port, USER_SERVICE_ID);
172 }
173
174 int
175 ugen_ClientInitFlags(const char *confDir, char *cellName, int secFlags,
176                      struct ubik_client **uclientp,
177                      ugen_secproc_func secproc,
178                      int maxservers, char *serviceid, int deadtime)
179 {
180     return internal_client_init_dir(confDir, cellName, secFlags, uclientp,
181                                     secproc, maxservers, serviceid, deadtime,
182                                     0, 0, USER_SERVICE_ID);
183 }
184
185 /*!
186  * \brief Get the appropriate type of ubik client structure out from the system.
187  */
188 afs_int32
189 ugen_ClientInit(int noAuthFlag, const char *confDir, char *cellName, afs_int32 sauth,
190                struct ubik_client **uclientp,
191                ugen_secproc_func secproc,
192                char *funcName, afs_int32 gen_rxkad_level,
193                afs_int32 maxservers, char *serviceid, afs_int32 deadtime,
194                afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
195 {
196     int secFlags;
197
198     secFlags = AFSCONF_SECOPTS_FALLBACK_NULL;
199     if (sauth) {
200         secFlags |= AFSCONF_SECOPTS_LOCALAUTH;
201         confDir = AFSDIR_SERVER_ETC_DIRPATH;
202     }
203
204     secFlags |= AFSCONF_SECOPTS_ALWAYSENCRYPT;
205
206     if (noAuthFlag)
207         secFlags |= AFSCONF_SECOPTS_NOAUTH;
208
209     return internal_client_init_dir(confDir, cellName, secFlags, uclientp,
210                                     secproc, maxservers, serviceid, deadtime,
211                                     server, port, usrvid);
212 }
213