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
42 # define KERBEROS_APPLE_DEPRECATED(x)
46 #include "afscp_internal.h"
48 static int afscp_ncells
= 0, afscp_cellsalloced
= 0;
49 static struct afscp_cell
*allcells
= NULL
;
50 static int afscp_nservers
= 0, afscp_srvsalloced
= 0;
51 static struct afscp_server
**allservers
= NULL
;
52 static char *defcell
= NULL
;
53 static char *defrealm
= NULL
;
57 afscp_FreeAllCells(void)
64 for (i
= 0; i
< afscp_ncells
; i
++) {
65 if (allcells
[i
].realm
!= NULL
)
66 free(allcells
[i
].realm
);
67 if (allcells
[i
].fsservers
!= NULL
)
68 free(allcells
[i
].fsservers
);
74 afscp_cellsalloced
= 0;
78 afscp_FreeAllServers(void)
80 if (allservers
== NULL
)
85 afscp_srvsalloced
= 0;
89 afscp_CellById(int id
)
91 if (id
>= afscp_ncells
|| id
< 0)
97 afscp_CellByName(const char *cellname
, const char *realmname
)
100 struct afscp_cell
*newlist
, *thecell
;
102 if (cellname
== NULL
) {
105 for (i
= 0; i
< afscp_ncells
; i
++) {
106 if (strcmp(allcells
[i
].name
, cellname
) == 0) {
110 if (afscp_ncells
>= afscp_cellsalloced
) {
111 if (afscp_cellsalloced
)
112 afscp_cellsalloced
= afscp_cellsalloced
* 2;
114 afscp_cellsalloced
= 4;
116 realloc(allcells
, afscp_cellsalloced
* sizeof(struct afscp_cell
));
117 if (newlist
== NULL
) {
122 thecell
= &allcells
[afscp_ncells
];
123 memset(thecell
, 0, sizeof(struct afscp_cell
));
124 strlcpy(thecell
->name
, cellname
, sizeof(thecell
->name
));
125 if (realmname
!= NULL
) {
126 thecell
->realm
= strdup(realmname
);
128 thecell
->realm
= NULL
;
130 if (_GetSecurityObject(thecell
)) {
133 if (_GetVLservers(thecell
)) {
134 RXS_Close(thecell
->security
);
137 thecell
->id
= afscp_ncells
++;
142 afscp_DefaultCell(void)
144 struct afsconf_dir
*dir
;
145 char localcell
[MAXCELLCHARS
+ 1];
149 return afscp_CellByName(defcell
, defrealm
);
152 dir
= afsconf_Open(AFSCONF_CLIENTNAME
);
154 afscp_errno
= AFSCONF_NODB
;
157 code
= afsconf_GetLocalCell(dir
, localcell
, MAXCELLCHARS
);
163 return afscp_CellByName(localcell
, defrealm
);
167 afscp_SetDefaultRealm(const char *realmname
)
172 /* krb5_error_code k5ec; */
176 if (realmname
== NULL
) {
177 if (defrealm
!= NULL
)
183 code
= krb5_init_context(&k5con
); /* see aklog.c main() */
188 krb5_set_default_realm(k5con
, realmname
);
189 /* if (k5ec != KRB5KDC_ERR_NONE) {
190 * com_err("libafscp", k5ec, "k5ec = %d (compared to KRB5KDC_ERR_NONE = %d)", k5ec, KRB5KDC_ERR_NONE);
193 /* krb5_set_default_realm() is returning 0 on success, not KRB5KDC_ERR_NONE */
194 #endif /* HAVE_KERBEROS */
196 newdefrealm
= strdup(realmname
);
197 if (newdefrealm
== NULL
) {
200 if (defrealm
!= NULL
)
202 defrealm
= newdefrealm
;
207 afscp_SetDefaultCell(const char *cellname
)
209 struct afscp_cell
*this;
211 if (cellname
== NULL
) {
218 this = afscp_CellByName(cellname
, defrealm
);
222 newdefcell
= strdup(cellname
);
223 if (newdefcell
== NULL
) {
228 defcell
= newdefcell
;
233 afscp_CellId(struct afscp_cell
*cell
)
241 _xdr_free(bool_t(*fn
) (XDR
* xdrs
, void *obj
), void *obj
)
244 xdrs
.x_op
= XDR_FREE
;
249 _xdr_bulkaddrs(XDR
* xdrs
, void *objp
)
251 return xdr_bulkaddrs(xdrs
, objp
);
254 /* takes server in host byte order */
255 struct afscp_server
*
256 afscp_ServerById(struct afscp_cell
*thecell
, afsUUID
* u
)
258 /* impliment uniquifiers? */
260 struct afscp_server
**newlist
;
261 struct afscp_server
**newall
;
262 struct afscp_server
*ret
= NULL
;
265 struct ListAddrByAttributes attrs
;
266 afs_int32 nentries
, uniq
;
268 afsUUID_to_string(u
, s
, 511);
269 afs_dprintf(("GetServerByID %s\n", s
));
271 for (i
= 0; i
< thecell
->nservers
; i
++) {
272 if (afs_uuid_equal(&thecell
->fsservers
[i
]->id
, u
)) {
273 return thecell
->fsservers
[i
];
277 if (thecell
->nservers
>= thecell
->srvsalloced
) {
278 if (thecell
->srvsalloced
)
279 thecell
->srvsalloced
= thecell
->srvsalloced
* 2;
281 thecell
->srvsalloced
= 4;
282 newlist
= realloc(thecell
->fsservers
,
283 thecell
->srvsalloced
*
284 sizeof(struct afscp_server
*));
285 if (newlist
== NULL
) {
288 thecell
->fsservers
= newlist
;
290 ret
= calloc(1, 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
,
374 * sizeof(struct afscp_server
*));
375 if (newlist
== NULL
) {
378 thecell
->fsservers
= newlist
;
380 ret
= calloc(1, 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
)
478 if (i
>= srv
->naddrs
|| i
< 0)
480 return srv
->conns
[i
];