2 Copyright (C) 2003 - 2010 Chaskiel Grundman
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include <afsconfig.h>
28 #include <afs/param.h>
32 #include <afs/vlserver.h>
33 #include <afs/vldbint.h>
34 #include <afs/volint.h>
35 #include <afs/cellconfig.h>
36 #ifndef AFSCONF_CLIENTNAME
37 #include <afs/dirpath.h>
38 #define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
45 #include "afscp_internal.h"
47 static int afscp_ncells = 0, afscp_cellsalloced = 0;
48 static struct afscp_cell *allcells = NULL;
49 static int afscp_nservers = 0, afscp_srvsalloced = 0;
50 static struct afscp_server **allservers = NULL;
51 static char *defcell = NULL;
52 static char *defrealm = NULL;
56 afscp_FreeAllCells(void)
63 for (i = 0; i < afscp_ncells; i++) {
64 if (allcells[i].realm != NULL)
65 free(allcells[i].realm);
66 if (allcells[i].fsservers != NULL)
67 free(allcells[i].fsservers);
73 afscp_cellsalloced = 0;
77 afscp_FreeAllServers(void)
79 if (allservers == NULL)
84 afscp_srvsalloced = 0;
88 afscp_CellById(int id)
90 if (id >= afscp_ncells || id < 0)
96 afscp_CellByName(const char *cellname, const char *realmname)
99 struct afscp_cell *newlist, *thecell;
101 if (cellname == NULL) {
104 for (i = 0; i < afscp_ncells; i++) {
105 if (strcmp(allcells[i].name, cellname) == 0) {
109 if (afscp_ncells >= afscp_cellsalloced) {
110 if (afscp_cellsalloced)
111 afscp_cellsalloced = afscp_cellsalloced * 2;
113 afscp_cellsalloced = 4;
115 realloc(allcells, afscp_cellsalloced * sizeof(struct afscp_cell));
116 if (newlist == NULL) {
121 thecell = &allcells[afscp_ncells];
122 memset(thecell, 0, sizeof(struct afscp_cell));
123 strlcpy(thecell->name, cellname, sizeof(thecell->name));
124 if (realmname != NULL) {
125 thecell->realm = strdup(realmname);
127 thecell->realm = NULL;
129 if (_GetSecurityObject(thecell)) {
132 if (_GetVLservers(thecell)) {
133 RXS_Close(thecell->security);
136 thecell->id = afscp_ncells++;
141 afscp_DefaultCell(void)
143 struct afsconf_dir *dir;
144 char localcell[MAXCELLCHARS + 1];
148 return afscp_CellByName(defcell, defrealm);
151 dir = afsconf_Open(AFSCONF_CLIENTNAME);
153 afscp_errno = AFSCONF_NODB;
156 code = afsconf_GetLocalCell(dir, localcell, MAXCELLCHARS);
162 return afscp_CellByName(localcell, defrealm);
166 afscp_SetDefaultRealm(const char *realmname)
171 /* krb5_error_code k5ec; */
175 if (realmname == NULL) {
176 if (defrealm != NULL)
182 code = krb5_init_context(&k5con); /* see aklog.c main() */
187 krb5_set_default_realm(k5con, realmname);
188 /* if (k5ec != KRB5KDC_ERR_NONE) {
189 * com_err("libafscp", k5ec, "k5ec = %d (compared to KRB5KDC_ERR_NONE = %d)", k5ec, KRB5KDC_ERR_NONE);
192 /* krb5_set_default_realm() is returning 0 on success, not KRB5KDC_ERR_NONE */
193 #endif /* HAVE_KERBEROS */
195 newdefrealm = strdup(realmname);
196 if (newdefrealm == NULL) {
199 if (defrealm != NULL)
201 defrealm = newdefrealm;
206 afscp_SetDefaultCell(const char *cellname)
208 struct afscp_cell *this;
210 if (cellname == NULL) {
217 this = afscp_CellByName(cellname, defrealm);
221 newdefcell = strdup(cellname);
222 if (newdefcell == NULL) {
227 defcell = newdefcell;
232 afscp_CellId(struct afscp_cell *cell)
240 _xdr_free(bool_t(*fn) (XDR * xdrs, void *obj), void *obj)
243 xdrs.x_op = XDR_FREE;
248 _xdr_bulkaddrs(XDR * xdrs, void *objp)
250 return xdr_bulkaddrs(xdrs, objp);
253 /* takes server in host byte order */
254 struct afscp_server *
255 afscp_ServerById(struct afscp_cell *thecell, afsUUID * u)
257 /* impliment uniquifiers? */
259 struct afscp_server **newlist;
260 struct afscp_server **newall;
261 struct afscp_server *ret = NULL;
264 struct ListAddrByAttributes attrs;
265 afs_int32 nentries, uniq;
267 afsUUID_to_string(u, s, 511);
268 afs_dprintf(("GetServerByID %s\n", s));
270 for (i = 0; i < thecell->nservers; i++) {
271 if (afs_uuid_equal(&thecell->fsservers[i]->id, u)) {
272 return thecell->fsservers[i];
276 if (thecell->nservers >= thecell->srvsalloced) {
277 if (thecell->srvsalloced)
278 thecell->srvsalloced = thecell->srvsalloced * 2;
280 thecell->srvsalloced = 4;
281 newlist = realloc(thecell->fsservers,
282 thecell->srvsalloced *
283 sizeof(struct afscp_server *));
284 if (newlist == NULL) {
287 thecell->fsservers = newlist;
289 ret = malloc(sizeof(struct afscp_server));
293 memset(ret, 0, sizeof(struct afscp_server));
294 thecell->fsservers[thecell->nservers] = ret;
295 memmove(&ret->id, u, sizeof(afsUUID));
296 ret->cell = thecell->id;
297 memset(&tmp, 0, sizeof(tmp));
298 memset(&addrs, 0, sizeof(addrs));
299 memset(&attrs, 0, sizeof(attrs));
300 attrs.Mask = VLADDR_UUID;
301 memmove(&attrs.uuid, u, sizeof(afsUUID));
303 code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &tmp,
304 &uniq, &nentries, &addrs);
308 if (nentries > AFS_MAXHOSTS) {
309 nentries = AFS_MAXHOSTS;
310 /* XXX I don't want to do *that* much dynamic allocation */
314 ret->naddrs = nentries;
315 for (i = 0; i < nentries; i++) {
316 ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]);
317 ret->conns[i] = rx_NewConnection(ret->addrs[i],
318 htons(AFSCONF_FILEPORT),
319 1, thecell->security,
322 _xdr_free(_xdr_bulkaddrs, &addrs);
325 if (afscp_nservers >= afscp_srvsalloced) {
326 if (afscp_srvsalloced)
327 afscp_srvsalloced = afscp_srvsalloced * 2;
329 afscp_srvsalloced = 4;
330 newall = realloc(allservers,
331 afscp_srvsalloced * sizeof(struct afscp_server *));
332 if (newall == NULL) {
337 ret->index = afscp_nservers;
338 allservers[afscp_nservers++] = ret;
342 /* takes server in host byte order */
343 struct afscp_server *
344 afscp_ServerByAddr(struct afscp_cell *thecell, afs_uint32 addr)
346 /* implement uniquifiers? */
348 struct afscp_server **newlist;
349 struct afscp_server **newall;
350 struct afscp_server *ret = NULL;
353 struct ListAddrByAttributes attrs;
354 afs_int32 nentries, code, uniq;
357 return ret; /* cannot continue without thecell */
359 for (i = 0; i < thecell->nservers; i++) {
360 ret = thecell->fsservers[i];
361 for (j = 0; j < ret->naddrs; j++)
362 if (ret->addrs[j] == htonl(addr)) {
367 if (thecell->nservers >= thecell->srvsalloced) {
368 if (thecell->srvsalloced)
369 thecell->srvsalloced = thecell->srvsalloced * 2;
371 thecell->srvsalloced = 4;
372 newlist = realloc(thecell->fsservers,
373 thecell->srvsalloced * sizeof(struct afscp_server));
374 if (newlist == NULL) {
377 thecell->fsservers = newlist;
379 ret = malloc(sizeof(struct afscp_server));
383 memset(ret, 0, sizeof(struct afscp_server));
384 thecell->fsservers[thecell->nservers] = ret;
385 ret->cell = thecell->id;
386 memset(&uuid, 0, sizeof(uuid));
387 memset(&addrs, 0, sizeof(addrs));
388 memset(&attrs, 0, sizeof(attrs));
389 attrs.Mask = VLADDR_IPADDR;
392 code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &uuid,
393 &uniq, &nentries, &addrs);
395 memset(&ret->id, 0, sizeof(uuid));
397 ret->addrs[0] = htonl(addr);
398 ret->conns[0] = rx_NewConnection(ret->addrs[0],
399 htons(AFSCONF_FILEPORT),
400 1, thecell->security,
405 afsUUID_to_string(&uuid, s, 511);
406 afs_dprintf(("GetServerByAddr 0x%x -> uuid %s\n", addr, s));
408 if (nentries > AFS_MAXHOSTS) {
409 nentries = AFS_MAXHOSTS;
410 /* XXX I don't want to do *that* much dynamic allocation */
413 memmove(&ret->id, &uuid, sizeof(afsUUID));
415 ret->naddrs = nentries;
416 for (i = 0; i < nentries; i++) {
417 ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]);
418 ret->conns[i] = rx_NewConnection(ret->addrs[i],
419 htons(AFSCONF_FILEPORT),
420 1, thecell->security,
423 _xdr_free(_xdr_bulkaddrs, &addrs);
427 if (afscp_nservers >= afscp_srvsalloced) {
428 if (afscp_srvsalloced)
429 afscp_srvsalloced = afscp_srvsalloced * 2;
431 afscp_srvsalloced = 4;
432 newall = realloc(allservers,
433 afscp_srvsalloced * sizeof(struct afscp_server *));
434 if (newall == NULL) {
439 ret->index = afscp_nservers;
440 allservers[afscp_nservers++] = ret;
444 /* takes server in host byte order */
445 struct afscp_server *
446 afscp_AnyServerByAddr(afs_uint32 addr)
448 /* implement uniquifiers? */
450 struct afscp_server *ret = NULL;
452 if (allservers == NULL)
454 for (i = 0; i < afscp_nservers; i++) {
456 for (j = 0; j < ret->naddrs; j++)
457 if (ret->addrs[j] == htonl(addr)) {
464 /* takes server in host byte order */
465 struct afscp_server *
466 afscp_ServerByIndex(int i)
468 if (i >= afscp_nservers || i < 0)
470 return allservers[i];
473 struct rx_connection *
474 afscp_ServerConnection(const struct afscp_server *srv, int i)
476 if (srv == NULL || srv->conns == NULL)
478 if (i >= srv->naddrs || i < 0)
480 return srv->conns[i];