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>
30 #include <afs/vlserver.h>
31 #include <afs/vldbint.h>
32 #include <afs/volint.h>
33 #include <afs/cellconfig.h>
34 #ifndef AFSCONF_CLIENTNAME
35 #include <afs/dirpath.h>
36 #define AFSCONF_CLIENTNAME AFSDIR_CLIENT_ETC_DIRPATH
40 # define KERBEROS_APPLE_DEPRECATED(x)
44 #include "afscp_internal.h"
46 static int afscp_ncells
= 0, afscp_cellsalloced
= 0;
47 static struct afscp_cell
*allcells
= NULL
;
48 static int afscp_nservers
= 0, afscp_srvsalloced
= 0;
49 static struct afscp_server
**allservers
= NULL
;
50 static char *defcell
= NULL
;
51 static char *defrealm
= NULL
;
55 afscp_FreeAllCells(void)
62 for (i
= 0; i
< afscp_ncells
; i
++) {
63 if (allcells
[i
].realm
!= NULL
)
64 free(allcells
[i
].realm
);
65 if (allcells
[i
].fsservers
!= NULL
)
66 free(allcells
[i
].fsservers
);
72 afscp_cellsalloced
= 0;
76 afscp_FreeAllServers(void)
78 if (allservers
== NULL
)
83 afscp_srvsalloced
= 0;
87 afscp_CellById(int id
)
89 if (id
>= afscp_ncells
|| id
< 0)
95 afscp_CellByName(const char *cellname
, const char *realmname
)
98 struct afscp_cell
*newlist
, *thecell
;
100 if (cellname
== NULL
) {
103 for (i
= 0; i
< afscp_ncells
; i
++) {
104 if (strcmp(allcells
[i
].name
, cellname
) == 0) {
108 if (afscp_ncells
>= afscp_cellsalloced
) {
109 if (afscp_cellsalloced
)
110 afscp_cellsalloced
= afscp_cellsalloced
* 2;
112 afscp_cellsalloced
= 4;
114 realloc(allcells
, afscp_cellsalloced
* sizeof(struct afscp_cell
));
115 if (newlist
== NULL
) {
120 thecell
= &allcells
[afscp_ncells
];
121 memset(thecell
, 0, sizeof(struct afscp_cell
));
122 strlcpy(thecell
->name
, cellname
, sizeof(thecell
->name
));
123 if (realmname
!= NULL
) {
124 thecell
->realm
= strdup(realmname
);
126 thecell
->realm
= NULL
;
128 if (_GetSecurityObject(thecell
)) {
131 if (_GetVLservers(thecell
)) {
132 RXS_Close(thecell
->security
);
135 thecell
->id
= afscp_ncells
++;
140 afscp_DefaultCell(void)
142 struct afsconf_dir
*dir
;
143 char localcell
[MAXCELLCHARS
+ 1];
147 return afscp_CellByName(defcell
, defrealm
);
150 dir
= afsconf_Open(AFSCONF_CLIENTNAME
);
152 afscp_errno
= AFSCONF_NODB
;
155 code
= afsconf_GetLocalCell(dir
, localcell
, MAXCELLCHARS
);
161 return afscp_CellByName(localcell
, defrealm
);
165 afscp_SetDefaultRealm(const char *realmname
)
170 /* krb5_error_code k5ec; */
174 if (realmname
== NULL
) {
175 if (defrealm
!= NULL
)
181 code
= krb5_init_context(&k5con
); /* see aklog.c main() */
186 krb5_set_default_realm(k5con
, realmname
);
187 /* if (k5ec != KRB5KDC_ERR_NONE) {
188 * com_err("libafscp", k5ec, "k5ec = %d (compared to KRB5KDC_ERR_NONE = %d)", k5ec, KRB5KDC_ERR_NONE);
191 /* krb5_set_default_realm() is returning 0 on success, not KRB5KDC_ERR_NONE */
192 #endif /* HAVE_KERBEROS */
194 newdefrealm
= strdup(realmname
);
195 if (newdefrealm
== NULL
) {
198 if (defrealm
!= NULL
)
200 defrealm
= newdefrealm
;
205 afscp_SetDefaultCell(const char *cellname
)
207 struct afscp_cell
*this;
209 if (cellname
== NULL
) {
216 this = afscp_CellByName(cellname
, defrealm
);
220 newdefcell
= strdup(cellname
);
221 if (newdefcell
== NULL
) {
226 defcell
= newdefcell
;
231 afscp_CellId(struct afscp_cell
*cell
)
239 _xdr_free(bool_t(*fn
) (XDR
* xdrs
, void *obj
), void *obj
)
242 xdrs
.x_op
= XDR_FREE
;
247 _xdr_bulkaddrs(XDR
* xdrs
, void *objp
)
249 return xdr_bulkaddrs(xdrs
, objp
);
252 /* takes server in host byte order */
253 struct afscp_server
*
254 afscp_ServerById(struct afscp_cell
*thecell
, afsUUID
* u
)
256 /* impliment uniquifiers? */
258 struct afscp_server
**newlist
;
259 struct afscp_server
**newall
;
260 struct afscp_server
*ret
= NULL
;
263 struct ListAddrByAttributes attrs
;
264 afs_int32 nentries
, uniq
;
266 afsUUID_to_string(u
, s
, 511);
267 afs_dprintf(("GetServerByID %s\n", s
));
269 for (i
= 0; i
< thecell
->nservers
; i
++) {
270 if (afs_uuid_equal(&thecell
->fsservers
[i
]->id
, u
)) {
271 return thecell
->fsservers
[i
];
275 if (thecell
->nservers
>= thecell
->srvsalloced
) {
276 if (thecell
->srvsalloced
)
277 thecell
->srvsalloced
= thecell
->srvsalloced
* 2;
279 thecell
->srvsalloced
= 4;
280 newlist
= realloc(thecell
->fsservers
,
281 thecell
->srvsalloced
*
282 sizeof(struct afscp_server
*));
283 if (newlist
== NULL
) {
286 thecell
->fsservers
= newlist
;
288 ret
= malloc(sizeof(struct afscp_server
));
292 memset(ret
, 0, sizeof(struct afscp_server
));
293 thecell
->fsservers
[thecell
->nservers
] = ret
;
294 memmove(&ret
->id
, u
, sizeof(afsUUID
));
295 ret
->cell
= thecell
->id
;
296 memset(&tmp
, 0, sizeof(tmp
));
297 memset(&addrs
, 0, sizeof(addrs
));
298 memset(&attrs
, 0, sizeof(attrs
));
299 attrs
.Mask
= VLADDR_UUID
;
300 memmove(&attrs
.uuid
, u
, sizeof(afsUUID
));
302 code
= ubik_VL_GetAddrsU(thecell
->vlservers
, 0, &attrs
, &tmp
,
303 &uniq
, &nentries
, &addrs
);
307 if (nentries
> AFS_MAXHOSTS
) {
308 nentries
= AFS_MAXHOSTS
;
309 /* XXX I don't want to do *that* much dynamic allocation */
313 ret
->naddrs
= nentries
;
314 for (i
= 0; i
< nentries
; i
++) {
315 ret
->addrs
[i
] = htonl(addrs
.bulkaddrs_val
[i
]);
316 ret
->conns
[i
] = rx_NewConnection(ret
->addrs
[i
],
317 htons(AFSCONF_FILEPORT
),
318 1, thecell
->security
,
321 _xdr_free(_xdr_bulkaddrs
, &addrs
);
324 if (afscp_nservers
>= afscp_srvsalloced
) {
325 if (afscp_srvsalloced
)
326 afscp_srvsalloced
= afscp_srvsalloced
* 2;
328 afscp_srvsalloced
= 4;
329 newall
= realloc(allservers
,
330 afscp_srvsalloced
* sizeof(struct afscp_server
*));
331 if (newall
== NULL
) {
336 ret
->index
= afscp_nservers
;
337 allservers
[afscp_nservers
++] = ret
;
341 /* takes server in host byte order */
342 struct afscp_server
*
343 afscp_ServerByAddr(struct afscp_cell
*thecell
, afs_uint32 addr
)
345 /* implement uniquifiers? */
347 struct afscp_server
**newlist
;
348 struct afscp_server
**newall
;
349 struct afscp_server
*ret
= NULL
;
352 struct ListAddrByAttributes attrs
;
353 afs_int32 nentries
, code
, uniq
;
356 return ret
; /* cannot continue without thecell */
358 for (i
= 0; i
< thecell
->nservers
; i
++) {
359 ret
= thecell
->fsservers
[i
];
360 for (j
= 0; j
< ret
->naddrs
; j
++)
361 if (ret
->addrs
[j
] == htonl(addr
)) {
366 if (thecell
->nservers
>= thecell
->srvsalloced
) {
367 if (thecell
->srvsalloced
)
368 thecell
->srvsalloced
= thecell
->srvsalloced
* 2;
370 thecell
->srvsalloced
= 4;
371 newlist
= realloc(thecell
->fsservers
,
372 thecell
->srvsalloced
* sizeof(struct afscp_server
));
373 if (newlist
== NULL
) {
376 thecell
->fsservers
= newlist
;
378 ret
= malloc(sizeof(struct afscp_server
));
382 memset(ret
, 0, sizeof(struct afscp_server
));
383 thecell
->fsservers
[thecell
->nservers
] = ret
;
384 ret
->cell
= thecell
->id
;
385 memset(&uuid
, 0, sizeof(uuid
));
386 memset(&addrs
, 0, sizeof(addrs
));
387 memset(&attrs
, 0, sizeof(attrs
));
388 attrs
.Mask
= VLADDR_IPADDR
;
391 code
= ubik_VL_GetAddrsU(thecell
->vlservers
, 0, &attrs
, &uuid
,
392 &uniq
, &nentries
, &addrs
);
394 memset(&ret
->id
, 0, sizeof(uuid
));
396 ret
->addrs
[0] = htonl(addr
);
397 ret
->conns
[0] = rx_NewConnection(ret
->addrs
[0],
398 htons(AFSCONF_FILEPORT
),
399 1, thecell
->security
,
404 afsUUID_to_string(&uuid
, s
, 511);
405 afs_dprintf(("GetServerByAddr 0x%x -> uuid %s\n", addr
, s
));
407 if (nentries
> AFS_MAXHOSTS
) {
408 nentries
= AFS_MAXHOSTS
;
409 /* XXX I don't want to do *that* much dynamic allocation */
412 memmove(&ret
->id
, &uuid
, sizeof(afsUUID
));
414 ret
->naddrs
= nentries
;
415 for (i
= 0; i
< nentries
; i
++) {
416 ret
->addrs
[i
] = htonl(addrs
.bulkaddrs_val
[i
]);
417 ret
->conns
[i
] = rx_NewConnection(ret
->addrs
[i
],
418 htons(AFSCONF_FILEPORT
),
419 1, thecell
->security
,
422 _xdr_free(_xdr_bulkaddrs
, &addrs
);
426 if (afscp_nservers
>= afscp_srvsalloced
) {
427 if (afscp_srvsalloced
)
428 afscp_srvsalloced
= afscp_srvsalloced
* 2;
430 afscp_srvsalloced
= 4;
431 newall
= realloc(allservers
,
432 afscp_srvsalloced
* sizeof(struct afscp_server
*));
433 if (newall
== NULL
) {
438 ret
->index
= afscp_nservers
;
439 allservers
[afscp_nservers
++] = ret
;
443 /* takes server in host byte order */
444 struct afscp_server
*
445 afscp_AnyServerByAddr(afs_uint32 addr
)
447 /* implement uniquifiers? */
449 struct afscp_server
*ret
= NULL
;
451 if (allservers
== NULL
)
453 for (i
= 0; i
< afscp_nservers
; i
++) {
455 for (j
= 0; j
< ret
->naddrs
; j
++)
456 if (ret
->addrs
[j
] == htonl(addr
)) {
463 /* takes server in host byte order */
464 struct afscp_server
*
465 afscp_ServerByIndex(int i
)
467 if (i
>= afscp_nservers
|| i
< 0)
469 return allservers
[i
];
472 struct rx_connection
*
473 afscp_ServerConnection(const struct afscp_server
*srv
, int i
)
477 if (i
>= srv
->naddrs
|| i
< 0)
479 return srv
->conns
[i
];