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
43 #include "afscp_internal.h"
45 static int afscp_ncells = 0, afscp_cellsalloced = 0;
46 static struct afscp_cell *allcells = NULL;
47 static int afscp_nservers = 0, afscp_srvsalloced = 0;
48 static struct afscp_server **allservers = NULL;
49 static char *defcell = NULL;
50 static char *defrealm = NULL;
54 afscp_FreeAllCells(void)
61 for (i = 0; i < afscp_ncells; i++) {
62 if (allcells[i].realm != NULL)
63 free(allcells[i].realm);
64 if (allcells[i].fsservers != NULL)
65 free(allcells[i].fsservers);
71 afscp_cellsalloced = 0;
75 afscp_FreeAllServers(void)
77 if (allservers == NULL)
82 afscp_srvsalloced = 0;
86 afscp_CellById(int id)
88 if (id >= afscp_ncells || id < 0)
94 afscp_CellByName(const char *cellname, const char *realmname)
97 struct afscp_cell *newlist, *thecell;
99 if (cellname == NULL) {
102 for (i = 0; i < afscp_ncells; i++) {
103 if (strcmp(allcells[i].name, cellname) == 0) {
107 if (afscp_ncells >= afscp_cellsalloced) {
108 if (afscp_cellsalloced)
109 afscp_cellsalloced = afscp_cellsalloced * 2;
111 afscp_cellsalloced = 4;
113 realloc(allcells, afscp_cellsalloced * sizeof(struct afscp_cell));
114 if (newlist == NULL) {
119 thecell = &allcells[afscp_ncells];
120 memset(thecell, 0, sizeof(struct afscp_cell));
121 strlcpy(thecell->name, cellname, sizeof(thecell->name));
122 if (realmname != NULL) {
123 thecell->realm = malloc(strlen(realmname) + 1);
124 memset(thecell->realm, 0, strlen(realmname) + 1);
125 strlcpy(thecell->realm, realmname, strlen(realmname) + 1);
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)
168 /* krb5_error_code k5ec; */
173 if (realmname == NULL) {
174 if (defrealm != NULL)
180 code = krb5_init_context(&k5con); /* see aklog.c main() */
185 krb5_set_default_realm(k5con, realmname);
186 /* if (k5ec != KRB5KDC_ERR_NONE) {
187 * com_err("libafscp", k5ec, "k5ec = %d (compared to KRB5KDC_ERR_NONE = %d)", k5ec, KRB5KDC_ERR_NONE);
190 /* krb5_set_default_realm() is returning 0 on success, not KRB5KDC_ERR_NONE */
191 newdefrealm = strdup(realmname);
192 if (newdefrealm == NULL) {
195 if (defrealm != NULL)
197 defrealm = newdefrealm;
202 afscp_SetDefaultCell(const char *cellname)
204 struct afscp_cell *this;
206 if (cellname == NULL) {
213 this = afscp_CellByName(cellname, defrealm);
217 newdefcell = strdup(cellname);
218 if (newdefcell == NULL) {
223 defcell = newdefcell;
228 afscp_CellId(struct afscp_cell *cell)
236 _xdr_free(bool_t(*fn) (XDR * xdrs, void *obj), void *obj)
239 xdrs.x_op = XDR_FREE;
244 _xdr_bulkaddrs(XDR * xdrs, void *objp)
246 return xdr_bulkaddrs(xdrs, objp);
249 struct afscp_server *
250 afscp_ServerById(struct afscp_cell *thecell, afsUUID * u)
252 /* impliment uniquifiers? */
254 struct afscp_server **newlist;
255 struct afscp_server **newall;
256 struct afscp_server *ret = NULL;
259 struct ListAddrByAttributes attrs;
260 afs_int32 nentries, uniq;
262 afsUUID_to_string(u, s, 511);
263 afs_dprintf(("GetServerByID %s\n", s));
265 for (i = 0; i < thecell->nservers; i++) {
266 if (afs_uuid_equal(&thecell->fsservers[i]->id, u)) {
267 return thecell->fsservers[i];
271 if (thecell->nservers >= thecell->srvsalloced) {
272 if (thecell->srvsalloced)
273 thecell->srvsalloced = thecell->srvsalloced * 2;
275 thecell->srvsalloced = 4;
276 newlist = realloc(thecell->fsservers,
277 thecell->srvsalloced *
278 sizeof(struct afscp_server *));
279 if (newlist == NULL) {
282 thecell->fsservers = newlist;
284 ret = malloc(sizeof(struct afscp_server));
288 memset(ret, 0, sizeof(struct afscp_server));
289 thecell->fsservers[thecell->nservers] = ret;
290 memmove(&ret->id, u, sizeof(afsUUID));
291 ret->cell = thecell->id;
292 memset(&tmp, 0, sizeof(tmp));
293 memset(&addrs, 0, sizeof(addrs));
294 memset(&attrs, 0, sizeof(attrs));
295 attrs.Mask = VLADDR_UUID;
296 memmove(&attrs.uuid, u, sizeof(afsUUID));
298 code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &tmp,
299 &uniq, &nentries, &addrs);
303 if (nentries > AFS_MAXHOSTS) {
304 nentries = AFS_MAXHOSTS;
305 /* XXX I don't want to do *that* much dynamic allocation */
309 ret->naddrs = nentries;
310 for (i = 0; i < nentries; i++) {
311 ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]);
312 ret->conns[i] = rx_NewConnection(ret->addrs[i],
313 htons(AFSCONF_FILEPORT),
314 1, thecell->security,
317 _xdr_free(_xdr_bulkaddrs, &addrs);
320 if (afscp_nservers >= afscp_srvsalloced) {
321 if (afscp_srvsalloced)
322 afscp_srvsalloced = afscp_srvsalloced * 2;
324 afscp_srvsalloced = 4;
325 newall = realloc(allservers,
326 afscp_srvsalloced * sizeof(struct afscp_server *));
327 if (newall == NULL) {
332 ret->index = afscp_nservers;
333 allservers[afscp_nservers++] = ret;
337 /* takes server in host byte order */
338 struct afscp_server *
339 afscp_ServerByAddr(struct afscp_cell *thecell, afs_uint32 addr)
341 /* implement uniquifiers? */
343 struct afscp_server **newlist;
344 struct afscp_server **newall;
345 struct afscp_server *ret = NULL;
348 struct ListAddrByAttributes attrs;
349 afs_int32 nentries, code, uniq;
352 return ret; /* cannot continue without thecell */
354 for (i = 0; i < thecell->nservers; i++) {
355 ret = thecell->fsservers[i];
356 for (j = 0; j < ret->naddrs; j++)
357 if (ret->addrs[j] == htonl(addr)) {
362 if (thecell->nservers >= thecell->srvsalloced) {
363 if (thecell->srvsalloced)
364 thecell->srvsalloced = thecell->srvsalloced * 2;
366 thecell->srvsalloced = 4;
367 newlist = realloc(thecell->fsservers,
368 thecell->srvsalloced * sizeof(struct afscp_server));
369 if (newlist == NULL) {
372 thecell->fsservers = newlist;
374 ret = malloc(sizeof(struct afscp_server));
378 memset(ret, 0, sizeof(struct afscp_server));
379 thecell->fsservers[thecell->nservers] = ret;
380 ret->cell = thecell->id;
381 memset(&uuid, 0, sizeof(uuid));
382 memset(&addrs, 0, sizeof(addrs));
383 memset(&attrs, 0, sizeof(attrs));
384 attrs.Mask = VLADDR_IPADDR;
387 code = ubik_VL_GetAddrsU(thecell->vlservers, 0, &attrs, &uuid,
388 &uniq, &nentries, &addrs);
390 memset(&ret->id, 0, sizeof(uuid));
392 ret->addrs[0] = htonl(addr);
393 ret->conns[0] = rx_NewConnection(ret->addrs[0],
394 htons(AFSCONF_FILEPORT),
395 1, thecell->security,
400 afsUUID_to_string(&uuid, s, 511);
401 afs_dprintf(("GetServerByAddr 0x%x -> uuid %s\n", addr, s));
403 if (nentries > AFS_MAXHOSTS) {
404 nentries = AFS_MAXHOSTS;
405 /* XXX I don't want to do *that* much dynamic allocation */
408 memmove(&ret->id, &uuid, sizeof(afsUUID));
410 ret->naddrs = nentries;
411 for (i = 0; i < nentries; i++) {
412 ret->addrs[i] = htonl(addrs.bulkaddrs_val[i]);
413 ret->conns[i] = rx_NewConnection(ret->addrs[i],
414 htons(AFSCONF_FILEPORT),
415 1, thecell->security,
418 _xdr_free(_xdr_bulkaddrs, &addrs);
422 if (afscp_nservers >= afscp_srvsalloced) {
423 if (afscp_srvsalloced)
424 afscp_srvsalloced = afscp_srvsalloced * 2;
426 afscp_srvsalloced = 4;
427 newall = realloc(allservers,
428 afscp_srvsalloced * sizeof(struct afscp_server *));
429 if (newall == NULL) {
434 ret->index = afscp_nservers;
435 allservers[afscp_nservers++] = ret;
439 /* takes server in host byte order */
440 struct afscp_server *
441 afscp_AnyServerByAddr(afs_uint32 addr)
443 /* implement uniquifiers? */
445 struct afscp_server *ret = NULL;
447 if (allservers == NULL)
449 for (i = 0; i < afscp_nservers; i++) {
451 for (j = 0; j < ret->naddrs; j++)
452 if (ret->addrs[j] == htonl(addr)) {
459 struct afscp_server *
460 afscp_ServerByIndex(int i)
462 if (i >= afscp_nservers || i < 0)
464 return allservers[i];
467 struct rx_connection *
468 afscp_ServerConnection(const struct afscp_server *srv, int i)
470 if (srv == NULL || srv->conns == NULL)
472 if (i >= srv->naddrs || i < 0)
474 return srv->conns[i];