2 * Copyright 2000, International Business Machines Corporation and others.
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
11 #include "afs_clientAdmin.h"
12 #include "../adminutil/afs_AdminInternal.h"
15 #include <sys/types.h>
16 #include <afs/cellconfig.h>
18 #include <afs/afssyscalls.h>
20 #include <afs/fs_utils.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
26 #include <afs/venus.h>
31 #include <afs/kautils.h>
33 #include <rx/rx_null.h>
35 #include <afs/dirpath.h>
36 #include <afs/afs_AdminErrors.h>
37 #include <afs/afs_vosAdmin.h>
38 #include <afs/afs_utilAdmin.h>
39 #include <afs/ptserver.h>
40 #include <afs/vlserver.h>
41 #include <afs/pthread_glock.h>
44 #include "../../permit_xprt.h"
47 * AFS client administration functions.
49 * Admin functions that are normally associated with the client.
51 * All of the functions related to authentication are here, plus
52 * some miscellaneous others.
56 static const unsigned long ADMIN_TICKET_LIFETIME = 24*3600;
59 * We need a way to track whether or not the client library has been
60 * initialized. We count on the fact that the other library initialization
61 * functions are protected by their own once mechanism. We only track
62 * our own internal status
65 static int client_init;
66 static pthread_once_t client_init_once = PTHREAD_ONCE_INIT;
68 static void client_once(void) {
73 * IsTokenValid - validate a token handle
77 * IN token - the token to be validated.
81 * No locks are obtained or released by this function
89 * Returns != 0 upon successful completion.
92 static int IsTokenValid(
93 const afs_token_handle_p token,
100 tst = ADMCLIENTTOKENHANDLENULL;
101 goto fail_IsTokenValid;
104 if (token->is_valid == 0) {
105 tst = ADMCLIENTTOKENHANDLEINVALID;
106 goto fail_IsTokenValid;
109 if ((token->begin_magic != BEGIN_MAGIC) ||
110 (token->end_magic != END_MAGIC)) {
111 tst = ADMCLIENTTOKENHANDLEBADMAGIC;
112 goto fail_IsTokenValid;
125 * afsclient_TokenGetExisting - get tokens that already exist and
126 * are held by the cache manager.
130 * IN cellName - the name of the cell where the token originated.
132 * OUT tokenHandle - a handle to the tokens if they were obtained
137 * No locks are obtained or released by this function
141 * The tokenHandle returned by this function cannot be used for kas
142 * related operations, since kas tokens aren't stored in the kernel.
146 * Returns != 0 upon successful completion.
149 int ADMINAPI afsclient_TokenGetExisting(
150 const char *cellName,
155 afs_status_t tst = 0;
156 struct ktc_principal afs_server;
157 afs_token_handle_p t_handle = (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
159 if (client_init == 0) {
160 tst = ADMCLIENTNOINIT;
161 goto fail_afsclient_TokenGetExisting;
164 if (cellName == NULL) {
165 tst = ADMCLIENTCELLNAMENULL;
166 goto fail_afsclient_TokenGetExisting;
169 if (tokenHandle == NULL) {
170 tst = ADMCLIENTTOKENHANDLENULL;
171 goto fail_afsclient_TokenGetExisting;
174 if (t_handle == NULL) {
176 goto fail_afsclient_TokenGetExisting;
179 strcpy(afs_server.name, "afs");
180 afs_server.instance[0] = 0;
181 strcpy(afs_server.cell, cellName);
183 if (!(tst = ktc_GetToken(&afs_server, &t_handle->afs_token,
184 sizeof(t_handle->afs_token),
185 &t_handle->client))) {
187 * The token has been retrieved successfully, initialize
188 * the rest of the token handle structure
190 strcpy(t_handle->cell, cellName);
191 t_handle->afs_token_set = 1;
192 t_handle->from_kernel = 1;
193 t_handle->kas_token_set = 0;
194 t_handle->sc_index = 2;
195 t_handle->afs_sc[t_handle->sc_index] =
196 rxkad_NewClientSecurityObject(rxkad_clear,
197 &t_handle->afs_token.sessionKey,
198 t_handle->afs_token.kvno,
199 t_handle->afs_token.ticketLen,
200 t_handle->afs_token.ticket);
201 t_handle->afs_encrypt_sc[t_handle->sc_index] =
202 rxkad_NewClientSecurityObject(rxkad_crypt,
203 &t_handle->afs_token.sessionKey,
204 t_handle->afs_token.kvno,
205 t_handle->afs_token.ticketLen,
206 t_handle->afs_token.ticket);
207 if ((t_handle->afs_sc[t_handle->sc_index] == NULL) ||
208 (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
209 tst = ADMCLIENTTOKENHANDLENOSECURITY;
210 goto fail_afsclient_TokenGetExisting;
212 t_handle->begin_magic = BEGIN_MAGIC;
213 t_handle->is_valid = 1;
214 t_handle->end_magic = END_MAGIC;
215 *tokenHandle = (void *) t_handle;
218 goto fail_afsclient_TokenGetExisting;
222 fail_afsclient_TokenGetExisting:
224 if ((rc == 0) && (t_handle != NULL)) {
234 * afsclient_TokenSet - set the tokens represented by tokenHandle to be
235 * active in the kernel (aka ka_SetToken).
239 * IN cellName - the name of the cell where the token originated.
241 * OUT tokenHandle - a handle to the tokens if they were obtained
246 * No locks are obtained or released by this function
250 * The tokenHandle returned by this function cannot be used for kas
251 * related operations, since kas tokens aren't stored in the kernel.
255 * Returns != 0 upon successful completion.
258 int ADMINAPI afsclient_TokenSet(
259 const void *tokenHandle,
263 afs_status_t tst = 0;
264 struct ktc_principal afs_server;
265 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
267 if (!IsTokenValid(t_handle, &tst)) {
268 goto fail_afsclient_TokenSet;
271 strcpy(afs_server.name, "afs");
272 afs_server.instance[0] = 0;
273 strcpy(afs_server.cell, t_handle->cell);
275 tst = ktc_SetToken(&afs_server, &t_handle->afs_token, &t_handle->client, 0);
281 fail_afsclient_TokenSet:
290 * GetKASToken - get a KAS token and store it in the tokenHandle.
294 * IN cellName - the name of the cell where the token should be obtained.
296 * IN principal - the name of the user of the token.
298 * IN password - the password for the principal.
300 * OUT tokenHandle - a handle to the tokens if they were obtained
305 * No locks are obtained or released by this function
313 * Returns != 0 upon successful completion.
316 static int GetKASToken(
317 const char *cellName,
318 const char *principal,
319 const char *password,
320 afs_token_handle_p tokenHandle,
324 afs_status_t tst = 0;
325 struct ubik_client *unauth_conn;
327 struct ktc_encryptionKey key;
328 struct ktc_token *token;
329 unsigned long now = time(0);
330 char name[MAXKTCNAMELEN];
331 char inst[MAXKTCNAMELEN];
332 int have_server_conn = 0;
334 token = &tokenHandle->kas_token;
336 ka_StringToKey((char *)password, (char *)cellName, &key);
339 * Get an unauthenticated connection in the right cell to use for
340 * retrieving the token.
343 tst = ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
346 goto fail_GetKASToken;
348 have_server_conn = 1;
350 tst = ka_ParseLoginName((char *)principal, name, inst, (char *) 0);
352 goto fail_GetKASToken;
355 tst = ka_Authenticate(name, inst, (char *)cellName, unauth_conn,
356 KA_MAINTENANCE_SERVICE, &key, now,
357 now+ADMIN_TICKET_LIFETIME, token, &expire);
359 goto fail_GetKASToken;
365 if (have_server_conn) {
366 ubik_ClientDestroy(unauth_conn);
376 * GetAFSToken - get a AFS token and store it in the tokenHandle.
380 * IN cellName - the name of the cell where the token should be obtained.
382 * IN principal - the name of the user of the token.
384 * IN password - the password for the principal.
386 * OUT tokenHandle - a handle to the tokens if they were obtained
391 * No locks are obtained or released by this function
399 * Returns != 0 upon successful completion.
402 static int GetAFSToken(
403 const char *cellName,
404 const char *principal,
405 const char *password,
406 afs_token_handle_p tokenHandle,
410 afs_status_t tst = 0;
411 struct ubik_client *unauth_conn = NULL, *auth_conn = NULL;
413 struct ktc_encryptionKey key;
414 struct ktc_token auth_token;
415 struct ktc_token *token;
416 unsigned long now = time(0);
418 token = &tokenHandle->afs_token;
420 ka_StringToKey((char *)password, (char *)cellName, &key);
423 * Get an unauthenticated connection in the right cell to use for
424 * retrieving the token.
427 tst = ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
430 goto fail_GetAFSToken;
433 tst = ka_ParseLoginName((char *)principal, tokenHandle->client.name,
434 tokenHandle->client.instance, (char *) 0);
436 goto fail_GetAFSToken;
439 tst = ka_Authenticate(tokenHandle->client.name,
440 tokenHandle->client.instance, (char *)cellName,
441 unauth_conn, KA_TICKET_GRANTING_SERVICE,
442 &key, now, now+ADMIN_TICKET_LIFETIME,
443 &auth_token, &expire);
445 goto fail_GetAFSToken;
448 tst = ka_AuthServerConn((char *)cellName, KA_TICKET_GRANTING_SERVICE,
451 goto fail_GetAFSToken;
454 tst = ka_CellToRealm((char *)cellName, tokenHandle->client.cell, (int *) 0);
456 goto fail_GetAFSToken;
459 tst = ka_GetToken("afs", "", (char *)cellName,
460 tokenHandle->client.name,
461 tokenHandle->client.instance,
463 now+ADMIN_TICKET_LIFETIME,
464 &auth_token, tokenHandle->client.cell,
467 goto fail_GetAFSToken;
474 ubik_ClientDestroy(auth_conn);
478 ubik_ClientDestroy(unauth_conn);
489 * afsclient_TokenGetNew - get new tokens for a user and store them
490 * in the tokenHandle.
494 * IN cellName - the name of the cell where the tokens should be obtained.
496 * IN principal - the name of the user of the tokens.
498 * IN password - the password for the principal.
500 * OUT tokenHandle - a handle to the tokens if they were obtained
505 * No locks are obtained or released by this function
513 * Returns != 0 upon successful completion.
516 int ADMINAPI afsclient_TokenGetNew(
517 const char *cellName,
518 const char *principal,
519 const char *password,
524 afs_status_t tst = 0;
525 afs_token_handle_p t_handle = (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
527 if (client_init == 0) {
528 tst = ADMCLIENTNOINIT;
529 goto fail_afsclient_TokenGetNew;
532 if (t_handle == NULL) {
534 goto fail_afsclient_TokenGetNew;
538 * Check to see if the principal or password is missing. If it is,
539 * get unauthenticated tokens for the cell
542 if ((principal == NULL) || (*principal == 0) ||
543 (password == NULL) || (*password == 0)) {
544 t_handle->from_kernel = 0;
545 t_handle->afs_token_set = 1;
546 t_handle->kas_token_set = 1;
547 t_handle->sc_index = 0;
548 t_handle->afs_sc[t_handle->sc_index] =
549 rxnull_NewClientSecurityObject();
550 t_handle->afs_encrypt_sc[t_handle->sc_index] =
551 rxnull_NewClientSecurityObject();
552 t_handle->kas_sc[t_handle->sc_index] =
553 rxnull_NewClientSecurityObject();
554 t_handle->begin_magic = BEGIN_MAGIC;
555 t_handle->is_valid = 1;
556 t_handle->afs_token.endTime = 0;
557 t_handle->end_magic = END_MAGIC;
558 *tokenHandle = (void *) t_handle;
563 * create an authenticated token
566 if ((GetAFSToken(cellName, principal, password, t_handle, &tst)) &&
567 (GetKASToken(cellName, principal, password, t_handle, &tst))) {
568 strcpy(t_handle->cell, cellName);
569 t_handle->from_kernel = 0;
570 t_handle->afs_token_set = 1;
571 t_handle->kas_token_set = 1;
572 t_handle->sc_index = 2;
573 t_handle->afs_sc[t_handle->sc_index] =
574 rxkad_NewClientSecurityObject(rxkad_clear,
575 &t_handle->afs_token.sessionKey,
576 t_handle->afs_token.kvno,
577 t_handle->afs_token.ticketLen,
578 t_handle->afs_token.ticket);
579 t_handle->afs_encrypt_sc[t_handle->sc_index] =
580 rxkad_NewClientSecurityObject(rxkad_crypt,
581 &t_handle->afs_token.sessionKey,
582 t_handle->afs_token.kvno,
583 t_handle->afs_token.ticketLen,
584 t_handle->afs_token.ticket);
585 t_handle->kas_sc[t_handle->sc_index] =
586 rxkad_NewClientSecurityObject(rxkad_crypt,
587 &t_handle->kas_token.sessionKey,
588 t_handle->kas_token.kvno,
589 t_handle->kas_token.ticketLen,
590 t_handle->kas_token.ticket);
591 if ((t_handle->afs_sc[t_handle->sc_index] != NULL) &&
592 (t_handle->afs_encrypt_sc[t_handle->sc_index] != NULL) &&
593 (t_handle->kas_sc[t_handle->sc_index] != NULL)) {
594 t_handle->begin_magic = BEGIN_MAGIC;
595 t_handle->is_valid = 1;
596 t_handle->end_magic = END_MAGIC;
597 *tokenHandle = (void *) t_handle;
599 tst = ADMCLIENTTOKENHANDLENOSECURITY;
600 goto fail_afsclient_TokenGetNew;
603 goto fail_afsclient_TokenGetNew;
608 fail_afsclient_TokenGetNew:
610 if ((rc == 0) && (t_handle != NULL)) {
621 * afsclient_TokenQuery - get the expiration time of the tokens.
625 * IN tokenHandle - a previously obtained valid token.
627 * OUT expirationDateP - the time at which the tokens expire.
629 * OUT principal - the owning principal
631 * OUT instance - principal instance if it exists.
633 * OUT cell - the principal's cell
635 * OUT hasKasTokens - set to 1 if the token handle contains kas tokens.
639 * No locks are obtained or released by this function
643 * We only check the AFS tokens since we always get these. The
644 * KAS tokens may expirer later than the AFS tokens, but this
645 * difference is minor and reporting an earlier time won't cause
650 * Returns != 0 upon successful completion.
653 int ADMINAPI afsclient_TokenQuery(
655 unsigned long *expirationDateP,
663 afs_status_t tst = 0;
664 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
666 if (client_init == 0) {
667 tst = ADMCLIENTNOINIT;
669 goto fail_afsclient_TokenQuery;
672 if (IsTokenValid(t_handle, &tst)) {
673 if (principal != NULL) {
674 strcpy(principal, t_handle->client.name);
676 if (instance != NULL) {
677 strcpy(instance, t_handle->client.instance);
680 strcpy(cell, t_handle->client.cell);
682 if (hasKasTokens != NULL) {
683 *hasKasTokens = t_handle->kas_token_set;
685 if (expirationDateP != NULL) {
686 *expirationDateP = t_handle->afs_token.endTime;
691 fail_afsclient_TokenQuery:
700 * afsclient_TokenClose - close an existing token.
704 * IN token - the token to be closed.
708 * No locks are obtained or released by this function
716 * Returns != 0 upon successful completion.
719 int ADMINAPI afsclient_TokenClose(
720 const void *tokenHandle,
724 afs_status_t tst = 0;
725 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
727 if (client_init == 0) {
728 tst = ADMCLIENTNOINIT;
729 goto fail_afsclient_TokenClose;
732 if (IsTokenValid(t_handle, &tst)) {
733 t_handle->is_valid = 0;
738 fail_afsclient_TokenClose:
746 #define NUM_SERVER_TYPES 3
748 /* must match NUM_SERVER_TYPES */
749 typedef enum {KAS, PTS, VOS} afs_server_list_t;
751 typedef struct afs_server {
754 struct ubik_client **ubik;
755 struct rx_securityClass *sc;
757 } afs_server_t, *afs_server_p;
759 static afs_server_t servers[NUM_SERVER_TYPES]
760 = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
761 {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
762 {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}};
765 * afsclient_CellOpen - Open a particular cell for work as a particular
770 * IN cellName - the cell where future admin calls will be made.
772 * IN tokenHandle - the tokens work will be done under.
774 * OUT cellHandleP - an opaque pointer that is the first parameter to
775 * almost all subsequent admin api calls.
779 * No locks are obtained or released by this function
787 * Returns != 0 upon successful completion.
790 int ADMINAPI afsclient_CellOpen(
791 const char *cellName,
792 const void *tokenHandle,
797 afs_status_t tst = 0;
798 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
799 afs_cell_handle_p c_handle = (afs_cell_handle_p)
800 calloc(1, sizeof(afs_cell_handle_t));
801 struct afsconf_dir *tdir = NULL;
802 struct afsconf_cell info;
803 struct rx_connection *serverconns[MAXSERVERS];
805 struct rx_securityClass *sc[3];
807 char copyCell[MAXCELLCHARS];
809 if (client_init == 0) {
810 tst = ADMCLIENTNOINIT;
811 goto fail_afsclient_CellOpen;
814 if (c_handle == NULL) {
816 goto fail_afsclient_CellOpen;
819 if (t_handle == NULL) {
820 tst = ADMCLIENTTOKENHANDLENULL;
821 goto fail_afsclient_CellOpen;
824 if ((cellName == NULL) || (*cellName == 0)) {
825 tst = ADMCLIENTCELLNAMENULL;
826 goto fail_afsclient_CellOpen;
829 if (cellHandleP == NULL) {
830 tst = ADMCLIENTCELLHANDLEPNULL;
831 goto fail_afsclient_CellOpen;
835 * Check that the token handle contains valid data and the calloc
838 if (!t_handle->afs_token_set) {
839 tst = ADMCLIENTCELLOPENBADTOKEN;
840 goto fail_afsclient_CellOpen;
844 * Use a table to initialize the cell handle structure, since
845 * most of the steps are the same for all the servers.
847 * Start by creating rx_securityClass objects for each of the
848 * servers. A potential optimization is to do this in
849 * afsclient_TokenGetNew and just keep the expiration time of
851 * Also, initialize the ubik client pointers in the table
853 servers[KAS].sc = t_handle->kas_sc[t_handle->sc_index];
854 servers[PTS].sc = t_handle->afs_sc[t_handle->sc_index];
855 servers[VOS].sc = servers[PTS].sc;
856 servers[KAS].ubik = &c_handle->kas;
857 servers[PTS].ubik = &c_handle->pts;
858 servers[VOS].ubik = &c_handle->vos;
859 servers[KAS].valid = &c_handle->kas_valid;
860 servers[PTS].valid = &c_handle->pts_valid;
861 servers[VOS].valid = &c_handle->vos_valid;
862 c_handle->vos_new = 1;
864 if ((servers[PTS].sc == NULL) || (servers[VOS].sc == NULL)) {
865 tst = ADMCLIENTBADTOKENHANDLE;
866 goto fail_afsclient_CellOpen;
870 * If the initialization has succeeded so far, get the address
871 * information for each server in the cell
874 strcpy(c_handle->working_cell, cellName);
875 if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
876 tst = ADMCLIENTBADCLIENTCONFIG;
877 goto fail_afsclient_CellOpen;
881 * We must copy the cellName here because afsconf_GetCellInfo
882 * actually writes over the cell name it is passed.
884 strncpy(copyCell, cellName, MAXCELLCHARS - 1);
885 for(i=0;(i<NUM_SERVER_TYPES);i++) {
887 tst = ka_AuthServerConn((char *)cellName,servers[i].serviceId,
888 ((t_handle->sc_index == 0) ||
889 (!t_handle->kas_token_set)) ?
890 0 : &t_handle->kas_token,
893 goto fail_afsclient_CellOpen;
896 tst = afsconf_GetCellInfo(tdir, copyCell,
897 servers[i].serv, &info);
899 /* create ubik client handles for each server */
900 scIndex = t_handle->sc_index;
901 sc[scIndex] = servers[i].sc;
902 for(j=0;(j<info.numServers);j++) {
904 rx_GetCachedConnection(
905 info.hostAddr[j].sin_addr.s_addr,
906 info.hostAddr[j].sin_port,
907 servers[i].serviceId,
908 sc[scIndex], scIndex);
911 tst = ubik_ClientInit(serverconns,servers[i].ubik);
913 goto fail_afsclient_CellOpen;
916 goto fail_afsclient_CellOpen;
919 /* initialization complete, mark handle valid */
920 *servers[i].valid = 1;
922 c_handle->tokens = t_handle;
925 fail_afsclient_CellOpen:
932 * Upon error, free any obtained resources.
935 if (c_handle != NULL) {
936 if (c_handle->kas_valid) ubik_ClientDestroy(c_handle->kas);
937 if (c_handle->pts_valid) ubik_ClientDestroy(c_handle->pts);
938 if (c_handle->vos_valid) ubik_ClientDestroy(c_handle->vos);
942 c_handle->begin_magic = BEGIN_MAGIC;
943 c_handle->is_valid = 1;
944 c_handle->is_null = 0;
945 c_handle->end_magic = END_MAGIC;
946 *cellHandleP = (void *) c_handle;
956 * afsclient_NullCellOpen - open a null cell handle for access.
960 * OUT cellHandleP - an opaque pointer that is the first parameter to
961 * almost all subsequent admin api calls.
965 * No locks are obtained or released by this function
973 * Returns != 0 upon successful completion.
976 int ADMINAPI afsclient_NullCellOpen(
981 afs_status_t tst = 0;
982 afs_cell_handle_p c_handle = (afs_cell_handle_p)
983 calloc(1, sizeof(afs_cell_handle_t));
987 * Validate parameters
990 if (cellHandleP == NULL) {
991 tst = ADMCLIENTCELLHANDLEPNULL;
992 goto fail_afsclient_NullCellOpen;
995 if (client_init == 0) {
996 tst = ADMCLIENTNOINIT;
997 goto fail_afsclient_NullCellOpen;
1000 if (c_handle == NULL) {
1002 goto fail_afsclient_NullCellOpen;
1006 * Get unauthenticated tokens for any cell
1009 if (!afsclient_TokenGetNew(0, 0, 0, (void *) &c_handle->tokens, &tst)) {
1010 goto fail_afsclient_NullCellOpen;
1013 c_handle->begin_magic = BEGIN_MAGIC;
1014 c_handle->is_valid = 1;
1015 c_handle->is_null = 1;
1016 c_handle->end_magic = END_MAGIC;
1017 c_handle->kas_valid = 0;
1018 c_handle->pts_valid = 0;
1019 c_handle->vos_valid = 0;
1023 *cellHandleP = (void *) c_handle;
1026 fail_afsclient_NullCellOpen:
1035 * afsclient_CellClose - close a previously opened cellHandle.
1039 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
1043 * No locks are obtained or released by this function
1051 * Returns != 0 upon successful completion.
1054 int ADMINAPI afsclient_CellClose(
1055 const void *cellHandle,
1059 afs_status_t tst = 0;
1060 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1062 if (client_init == 0) {
1063 tst = ADMCLIENTNOINIT;
1064 goto fail_afsclient_CellClose;
1067 if (c_handle == NULL) {
1068 tst = ADMCLIENTCELLHANDLENULL;
1069 goto fail_afsclient_CellClose;
1072 if (c_handle->kas_valid) ubik_ClientDestroy(c_handle->kas);
1073 if (c_handle->pts_valid) ubik_ClientDestroy(c_handle->pts);
1074 if (c_handle->vos_valid) ubik_ClientDestroy(c_handle->vos);
1075 if (c_handle->is_null) afsclient_TokenClose(c_handle->tokens, 0);
1076 c_handle->kas_valid = 0;
1077 c_handle->pts_valid = 0;
1078 c_handle->vos_valid = 0;
1079 c_handle->is_valid = 0;
1083 fail_afsclient_CellClose:
1093 * afsclient_CellNameGet() -- get a pointer to the cell name in a cell handle
1097 * IN cellHandle - a valid cell handle
1098 * OUT cellNameP - a pointer to the cell name in the cell handle.
1102 * No locks are obtained or released by this function
1106 * If cellHandle is closed then the pointer returned by this function
1107 * is no longer valid.
1111 * Returns != 0 upon successful completion.
1113 int ADMINAPI afsclient_CellNameGet(
1114 const void *cellHandle,
1115 const char **cellNameP,
1119 afs_status_t tst = 0;
1120 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1122 if (!CellHandleIsValid(cellHandle, &tst)) {
1123 goto fail_afsclient_CellNameGet;
1126 *cellNameP = c_handle->working_cell;
1129 fail_afsclient_CellNameGet:
1139 * afsclient_LocalCellGet - get the name of the cell the machine
1140 * belongs to where this process is running.
1144 * OUT cellName - an array of characters that must be MAXCELLCHARS
1149 * No locks are obtained or released by this function
1153 * If cellName is smaller than MAXCELLCHARS chars, this function won't
1158 * Returns != 0 upon successful completion.
1161 int ADMINAPI afsclient_LocalCellGet(
1166 afs_status_t tst = 0;
1167 struct afsconf_dir *tdir = NULL;
1169 if (client_init == 0) {
1170 tst = ADMCLIENTNOINIT;
1171 goto fail_afsclient_LocalCellGet;
1174 if (cellName == NULL) {
1175 tst = ADMCLIENTCELLNAMENULL;
1176 goto fail_afsclient_LocalCellGet;
1179 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1182 tst = ADMCLIENTBADCLIENTCONFIG;
1183 goto fail_afsclient_LocalCellGet;
1186 if (tst = afsconf_GetLocalCell(tdir, cellName, MAXCELLCHARS)) {
1187 goto fail_afsclient_LocalCellGet;
1192 fail_afsclient_LocalCellGet:
1195 afsconf_Close(tdir);
1207 static int client_ExtractDriveLetter(
1212 if (path[0] != 0 && path[1] == ':') {
1221 * Determine the parent directory of a give directory
1226 char *parentDirectory)
1231 strcpy(parentDirectory, directory);
1232 tp = strrchr(parentDirectory, '\\');
1234 /* lv trailing slash so Parent("k:\foo") is "k:\" not "k :" */
1239 if (client_ExtractDriveLetter(parentDirectory)) {
1240 strcat(parentDirectory, ".");
1250 * Determine the parent directory of a give directory
1253 const char *directory,
1254 char *parentDirectory)
1259 strcpy(parentDirectory, directory);
1260 tp = rindex(parentDirectory, '/');
1266 strcpy(parentDirectory, ".");
1275 * afsclient_MountPointCreate - create a mount point for a volume.
1279 * IN cellHandle - a handle to the cell where volumeName resides.
1281 * IN directory - the directory where the mountpoint should be created.
1283 * IN volumeName - the name of the volume to mount.
1285 * IN volType - the type of mount point to create.
1287 * IN volCheck - indicates whether or not to check the VLDB to see if
1288 * volumeName exists.
1292 * No locks are obtained or released by this function
1296 * Returns != 0 upon successful completion.
1299 #define TMP_DATA_SIZE 2048
1301 int ADMINAPI afsclient_MountPointCreate(
1302 const void *cellHandle,
1303 const char *directory,
1304 const char *volumeName,
1306 vol_check_t volCheck,
1310 afs_status_t tst = 0;
1311 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1312 char parent_dir[TMP_DATA_SIZE];
1313 char space[TMP_DATA_SIZE];
1314 char directoryCell[MAXCELLCHARS];
1315 struct ViceIoctl idata;
1317 vos_vldbEntry_t vldbEntry;
1320 * Validate arguments
1323 if (client_init == 0) {
1324 tst = ADMCLIENTNOINIT;
1325 goto fail_afsclient_MountPointCreate;
1328 if ((directory == NULL) || (*directory == 0)) {
1329 tst = ADMCLIENTDIRECTORYNULL;
1330 goto fail_afsclient_MountPointCreate;
1333 if ((volumeName == NULL) || (*volumeName == 0)) {
1334 tst = ADMCLIENTVOLUMENAME;
1335 goto fail_afsclient_MountPointCreate;
1339 * Extract the parent directory and make sure it is in AFS.
1342 if (!Parent(directory, parent_dir)) {
1343 tst = ADMCLIENTBADDIRECTORY;
1344 goto fail_afsclient_MountPointCreate;
1348 idata.out_size = TMP_DATA_SIZE;
1350 i = pioctl(parent_dir, VIOC_FILE_CELL_NAME, &idata, 1);
1352 if ((errno == EINVAL) || (errno == ENOENT)) {
1353 tst = ADMCLIENTNOAFSDIRECTORY;
1354 goto fail_afsclient_MountPointCreate;
1357 strcpy(directoryCell, space);
1360 * If the user requested, check that the volume exists
1363 if (volCheck == CHECK_VOLUME) {
1364 if (!vos_VLDBGet(cellHandle, 0, 0, volumeName, &vldbEntry, &tst)) {
1365 goto fail_afsclient_MountPointCreate;
1370 * Begin constructing the pioctl buffer
1373 if (volType == READ_WRITE) {
1380 * Append the cell to the mount point if the volume is in a different
1381 * cell than the directory
1384 if (strcmp(c_handle->working_cell, directoryCell)) {
1385 strcat(space, c_handle->working_cell);
1388 strcat(space, volumeName);
1395 idata.in_size = 1 + strlen(space);
1397 if (tst = pioctl(directory, VIOC_AFS_CREATE_MT_PT, &idata, 0)) {
1398 goto fail_afsclient_MountPointCreate;
1401 if (tst = symlink(space, directory)) {
1402 goto fail_afsclient_MountPointCreate;
1408 fail_afsclient_MountPointCreate:
1416 typedef struct Acl {
1423 int ADMINAPI afsclient_ACLEntryAdd(
1424 const char *directory,
1430 afs_status_t tst = 0;
1431 struct ViceIoctl idata;
1432 char old_acl_string[2048];
1433 char new_acl_string[2048];
1443 if (client_init == 0) {
1444 tst = ADMCLIENTNOINIT;
1445 goto fail_afsclient_ACLEntryAdd;
1448 if ((directory == NULL) || (*directory == 0)) {
1449 tst = ADMMISCDIRECTORYNULL;
1450 goto fail_afsclient_ACLEntryAdd;
1453 if ((user == NULL) || (*user == 0)) {
1454 tst = ADMMISCUSERNULL;
1455 goto fail_afsclient_ACLEntryAdd;
1459 tst = ADMMISCACLNULL;
1460 goto fail_afsclient_ACLEntryAdd;
1463 if (acl->read == READ) {
1467 if (acl->write == WRITE) {
1471 if (acl->insert == INSERT) {
1475 if (acl->lookup == LOOKUP) {
1479 if (acl->del == DELETE) {
1483 if (acl->lock == LOCK) {
1487 if (acl->admin == ADMIN) {
1492 * Get the current acl for the directory
1495 idata.out_size = 2048;
1497 idata.in = idata.out = old_acl_string;
1498 tst = pioctl(directory, VIOCGETAL, &idata, 1);
1501 goto fail_afsclient_ACLEntryAdd;
1505 * The acl is presented to us in string format. The format of the
1508 * A header which contains the number of positive and negative entries
1509 * and a string indicating whether or not this is a dfs acl:
1511 * num_pos "\n" dfs_string "\n" num_neg
1513 * An entry for each acl that's of the form:
1517 * There are no blanks in the string between fields, but I use them here
1518 * to make the reading easier.
1520 * Since we are only going to add another entry to the acl, our approach
1521 * is simple. Get the num_pos dfs_string and num_neg from the current acl,
1522 * increment num_pos by one and create a new string. Concatenate the new
1523 * user and rights to the new string, and then concatenate the remaining
1524 * contents of the old acl to the new string.
1526 * Unfortunately, this approach doesn't work since the format the kernel
1527 * hands the acl back to us in, is NOT WHAT IT WANTS BACK!!!!
1528 * So instead we need to parse the entire freaking acl and put a space
1529 * between each user and their acl.
1531 * This is really ugly.
1535 * Parse the first few fields of the acl and see if this is a DFS
1539 is_dfs = sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs, &cur_acl.cell);
1540 ptr = strchr(old_acl_string, '\n');
1542 sscanf(ptr, "%d", &cur_acl.nminus);
1543 ptr = strchr(ptr, '\n');
1546 tst = ADMMISCNODFSACL;
1547 goto fail_afsclient_ACLEntryAdd;
1550 * It isn't a DFS file, so create the beginning of the string
1551 * we will hand back to the kernel
1553 sprintf(new_acl_string, "%d\n%d\n%s %d\n", (cur_acl.nplus + 1),
1554 cur_acl.nminus, user, newacl);
1558 * Finish scanning the old acl, parsing each user/acl pair and
1559 * adding a space in the new acl.
1562 for(i=0;i<(cur_acl.nplus + cur_acl.nminus);i++) {
1563 sscanf(ptr, "%s%d\n", &cur_user, &cur_user_acl);
1565 * Skip the entry for the user we are replacing/adding
1568 if (strcmp(cur_user, user)) {
1569 ptr = strchr(ptr, '\n');
1571 sprintf(tmp, "%s %d\n", cur_user, cur_user_acl);
1572 strcat(new_acl_string, tmp);
1576 strcat(new_acl_string, ptr);
1583 idata.in_size = strlen(new_acl_string) + 1;
1584 idata.in = idata.out = new_acl_string;
1585 tst = pioctl(directory, VIOCSETAL, &idata, 1);
1588 goto fail_afsclient_ACLEntryAdd;
1592 fail_afsclient_ACLEntryAdd:
1601 * afsclient_Init - initialize AFS components before use.
1607 * No locks are obtained or released by this function
1615 * Returns != 0 upon successful completion.
1618 int ADMINAPI afsclient_Init(
1622 afs_status_t tst = 0;
1624 (client_init || pthread_once(&client_init_once, client_once));
1627 if (afs_winsockInit() < 0) {
1628 tst = ADMCLIENTCANTINITWINSOCK;
1629 goto fail_afsclient_Init;
1633 if (!(initAFSDirPath() & AFSDIR_CLIENT_PATHS_OK)) {
1634 tst = ADMCLIENTCANTINITAFSLOCATION;
1635 goto fail_afsclient_Init;
1638 if (rx_Init(0) < 0) {
1639 tst = ADMCLIENTCANTINITRX;
1640 goto fail_afsclient_Init;
1643 if (tst = ka_CellConfig((char *)AFSDIR_CLIENT_ETC_DIRPATH)) {
1644 goto fail_afsclient_Init;
1649 fail_afsclient_Init:
1658 * afsclient_AFSServerGet - determine what kind of server serverName
1659 * is and fill in serverEntryP accordingly.
1663 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1665 * IN serverName - the hostname of the server of interest.
1667 * OUT serverEntryP - upon successful completion contains a description of
1672 * No locks are obtained or released by this function
1680 * Returns != 0 upon successful completion.
1683 int ADMINAPI afsclient_AFSServerGet(
1684 const void *cellHandle,
1685 const char *serverName,
1686 afs_serverEntry_p serverEntryP,
1690 afs_status_t tst = 0;
1692 int found_match = 0;
1694 if ((serverName == NULL) || (*serverName == 0)) {
1695 tst = ADMUTILSERVERNAMENULL;
1696 goto fail_afsclient_AFSServerGet;
1699 if (serverEntryP == NULL) {
1700 tst = ADMUTILSERVERENTRYPNULL;
1701 goto fail_afsclient_AFSServerGet;
1705 * Iterate over server entries and try to find a match for serverName
1708 if (!afsclient_AFSServerGetBegin(cellHandle, &iter, &tst)) {
1709 goto fail_afsclient_AFSServerGet;
1712 while(afsclient_AFSServerGetNext(iter, serverEntryP, &tst)) {
1713 if (!strcmp(serverName, serverEntryP->serverName)) {
1720 * If we didn't find a match, the iterator should have terminated
1721 * normally. If it didn't, return the error
1725 if (tst != ADMITERATORDONE) {
1726 afsclient_AFSServerGetDone(iter, 0);
1728 afsclient_AFSServerGetDone(iter, &tst);
1730 tst = ADMCLIENTNOMATCHINGSERVER;
1731 goto fail_afsclient_AFSServerGet;
1733 if (!afsclient_AFSServerGetDone(iter, &tst)) {
1734 goto fail_afsclient_AFSServerGet;
1739 fail_afsclient_AFSServerGet:
1748 * The iterator functions and data for the server retrieval functions
1751 typedef struct server_get {
1754 afs_serverEntry_t server[MAXHOSTSPERCELL + BADSERVERID];
1755 afs_serverEntry_t cache[CACHED_ITEMS];
1756 } server_get_t, *server_get_p;
1758 static int GetServerRPC(
1762 int *last_item_contains_data,
1766 afs_status_t tst = 0;
1767 server_get_p serv = (server_get_p) rpc_specific;
1769 memcpy(&serv->cache[slot], &serv->server[serv->index],
1770 sizeof(afs_serverEntry_t));
1773 if (serv->index == serv->total) {
1775 *last_item_contains_data = 1;
1787 static int GetServerFromCache(
1794 afs_status_t tst = 0;
1795 server_get_p serv = (server_get_p) rpc_specific;
1797 memcpy(dest, (const void *) &serv->cache[slot], sizeof(afs_serverEntry_t));
1807 * afsclient_AFSServerGetBegin - start the process of iterating over
1808 * every server in the cell.
1812 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1814 * OUT iterationIdP - - upon successful completion contains an iterator
1815 * that can be passed to afsclient_AFSServerGetNext.
1819 * No locks are obtained or released by this function
1827 * Returns != 0 upon successful completion.
1830 int ADMINAPI afsclient_AFSServerGetBegin(
1831 const void *cellHandle,
1832 void **iterationIdP,
1836 afs_status_t tst = 0;
1837 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1838 afs_admin_iterator_p iter = (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1839 server_get_p serv = (server_get_p) calloc(1, sizeof(server_get_t));
1840 const char *cellName;
1841 void *database_iter;
1842 util_databaseServerEntry_t database_entry;
1843 void *fileserver_iter;
1844 vos_fileServerEntry_t fileserver_entry;
1845 int iserv,iservaddr,ientryaddr, is_dup;
1846 struct hostent *host;
1848 if (!CellHandleIsValid(c_handle, &tst)) {
1849 goto fail_afsclient_AFSServerGetBegin;
1852 if (iterationIdP == NULL) {
1853 tst = ADMITERATIONIDPNULL;
1854 goto fail_afsclient_AFSServerGetBegin;
1857 if ((serv == NULL) || (iter == NULL)) {
1859 goto fail_afsclient_AFSServerGetBegin;
1863 * Retrieve the list of database servers for this cell.
1866 if (!afsclient_CellNameGet(cellHandle, &cellName, &tst)) {
1867 goto fail_afsclient_AFSServerGetBegin;
1870 if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
1871 goto fail_afsclient_AFSServerGetBegin;
1874 while(util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
1875 serv->server[serv->total].serverAddress[0] = database_entry.serverAddress;
1876 serv->server[serv->total].serverType = DATABASE_SERVER;
1880 if (tst != ADMITERATORDONE) {
1881 util_DatabaseServerGetDone(database_iter, 0);
1882 goto fail_afsclient_AFSServerGetBegin;
1885 if (!util_DatabaseServerGetDone(database_iter, &tst)) {
1886 goto fail_afsclient_AFSServerGetBegin;
1890 * Retrieve the list of file servers for this cell.
1893 if (!vos_FileServerGetBegin(cellHandle, 0, &fileserver_iter, &tst)) {
1894 goto fail_afsclient_AFSServerGetBegin;
1897 while(vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
1899 * See if any of the addresses returned in this fileserver_entry
1900 * structure already exist in the list of servers we're building.
1901 * If not, create a new record for this server.
1904 for(iserv=0;iserv<serv->total;iserv++) {
1905 for(ientryaddr=0; ientryaddr<fileserver_entry.count; ientryaddr++) {
1906 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1907 if (serv->server[iserv].serverAddress[iservaddr] ==
1908 fileserver_entry.serverAddress[ientryaddr]) {
1923 serv->server[iserv].serverType |= FILE_SERVER;
1925 iserv = serv->total++;
1926 serv->server[iserv].serverType = FILE_SERVER;
1930 * Add the addresses from the vldb list to the serv->server[iserv]
1931 * record. Remember that VLDB's list-of-addrs is not guaranteed
1932 * to be unique in a particular entry, or to return only one entry
1933 * per machine--so when we add addresses, always check for
1934 * duplicate entries.
1937 for(ientryaddr=0;ientryaddr<fileserver_entry.count;ientryaddr++) {
1938 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1939 if (serv->server[iserv].serverAddress[iservaddr] ==
1940 fileserver_entry.serverAddress[ientryaddr]) {
1944 if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
1945 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1946 if (!serv->server[iserv].serverAddress[iservaddr]) {
1947 serv->server[iserv].serverAddress[iservaddr] =
1948 fileserver_entry.serverAddress[ientryaddr];
1956 if (tst != ADMITERATORDONE) {
1957 vos_FileServerGetDone(fileserver_iter, 0);
1958 goto fail_afsclient_AFSServerGetBegin;
1961 if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
1962 goto fail_afsclient_AFSServerGetBegin;
1966 * Iterate over the list and fill in the hostname of each of the servers
1970 for(iserv=0;iserv<serv->total;iserv++) {
1971 int addr = htonl(serv->server[iserv].serverAddress[0]);
1972 host = gethostbyaddr((const char *) &addr, sizeof(int), AF_INET);
1974 strncpy(serv->server[iserv].serverName, host->h_name,
1975 AFS_MAX_SERVER_NAME_LEN);
1980 if (IteratorInit(iter, (void *) serv, GetServerRPC, GetServerFromCache,
1981 NULL, NULL, &tst)) {
1982 *iterationIdP = (void *) iter;
1986 fail_afsclient_AFSServerGetBegin:
2004 * afsclient_AFSServerGetNext - retrieve the next server in the cell.
2008 * IN iterationId - an iterator previously returned by
2009 * afsclient_AFSServerGetBegin.
2011 * OUT serverEntryP - upon successful completion contains the next server.
2015 * No locks are obtained or released by this function
2023 * Returns != 0 upon successful completion.
2026 int ADMINAPI afsclient_AFSServerGetNext(
2028 afs_serverEntry_p serverEntryP,
2032 afs_status_t tst = 0;
2033 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2035 if (iterationId == NULL) {
2036 tst = ADMITERATORNULL;
2037 goto fail_afsclient_AFSServerGetNext;
2040 if (serverEntryP == NULL) {
2041 tst = ADMUTILSERVERENTRYPNULL;
2042 goto fail_afsclient_AFSServerGetNext;
2045 rc = IteratorNext(iter, (void *) serverEntryP, &tst);
2047 fail_afsclient_AFSServerGetNext:
2056 * afsclient_AFSServerGetDone - finish using a server iterator.
2060 * IN iterationId - an iterator previously returned by
2061 * afsclient_AFSServerGetBegin.
2065 * No locks are obtained or released by this function
2073 * Returns != 0 upon successful completion.
2076 int ADMINAPI afsclient_AFSServerGetDone(
2081 afs_status_t tst = 0;
2082 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2084 if (iterationId == NULL) {
2085 tst = ADMITERATORNULL;
2086 goto fail_afsclient_AFSServerGetDone;
2089 rc = IteratorDone(iter, &tst);
2091 fail_afsclient_AFSServerGetDone:
2100 * afsclient_RPCStatOpen - open an rx connection to a server to retrieve
2105 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2107 * IN serverName - the host name where the server resides.
2109 * IN type - what type of process to query
2111 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2115 * No locks are obtained or released by this function
2123 * Returns != 0 upon successful completion.
2126 int ADMINAPI afsclient_RPCStatOpen(
2127 const void *cellHandle,
2128 const char *serverName,
2129 afs_stat_source_t type,
2130 struct rx_connection **rpcStatHandleP,
2134 afs_status_t tst = 0;
2135 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2138 struct rx_securityClass *sc;
2140 if (!CellHandleIsValid(cellHandle, &tst)) {
2141 goto fail_afsclient_RPCStatOpen;
2144 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2145 goto fail_afsclient_RPCStatOpen;
2148 if (rpcStatHandleP == NULL) {
2149 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2150 goto fail_afsclient_RPCStatOpen;
2156 servPort = AFSCONF_NANNYPORT;
2159 case AFS_FILESERVER:
2160 servPort = AFSCONF_FILEPORT;
2164 servPort = AFSCONF_KAUTHPORT;
2168 servPort = AFSCONF_PROTPORT;
2172 servPort = AFSCONF_VOLUMEPORT;
2176 servPort = AFSCONF_VLDBPORT;
2180 servPort = AFSCONF_CALLBACKPORT;
2184 tst = ADMTYPEINVALID;
2185 goto fail_afsclient_RPCStatOpen;
2189 * special processing of tokens by server type
2192 if (type == AFS_KASERVER) {
2193 if (!c_handle->tokens->kas_token_set) {
2194 tst = ADMCLIENTNOKASTOKENS;
2195 goto fail_afsclient_RPCStatOpen;
2197 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2199 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2202 *rpcStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2204 RX_STATS_SERVICE_ID,
2206 c_handle->tokens->sc_index);
2208 if (*rpcStatHandleP == NULL) {
2209 tst = ADMCLIENTRPCSTATNOCONNECTION;
2210 goto fail_afsclient_RPCStatOpen;
2214 fail_afsclient_RPCStatOpen:
2223 * afsclient_RPCStatOpenPort - open an rx connection to a server to retrieve
2228 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2230 * IN serverName - the host name where the server resides.
2232 * IN port - the UDP port number where the server resides.
2234 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2238 * No locks are obtained or released by this function
2246 * Returns != 0 upon successful completion.
2249 int ADMINAPI afsclient_RPCStatOpenPort(
2250 const void *cellHandle,
2251 const char *serverName,
2252 const int serverPort,
2253 struct rx_connection **rpcStatHandleP,
2257 afs_status_t tst = 0;
2258 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2260 struct rx_securityClass *sc;
2262 if (!CellHandleIsValid(cellHandle, &tst)) {
2263 goto fail_afsclient_RPCStatOpenPort;
2266 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2267 goto fail_afsclient_RPCStatOpenPort;
2270 if (rpcStatHandleP == NULL) {
2271 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2272 goto fail_afsclient_RPCStatOpenPort;
2276 * special processing of tokens by server type
2279 if (serverPort == AFSCONF_KAUTHPORT) {
2280 if (!c_handle->tokens->kas_token_set) {
2281 tst = ADMCLIENTNOKASTOKENS;
2282 goto fail_afsclient_RPCStatOpenPort;
2284 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2286 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2289 *rpcStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2291 RX_STATS_SERVICE_ID,
2293 c_handle->tokens->sc_index);
2295 if (*rpcStatHandleP == NULL) {
2296 tst = ADMCLIENTRPCSTATNOCONNECTION;
2297 goto fail_afsclient_RPCStatOpenPort;
2301 fail_afsclient_RPCStatOpenPort:
2310 * afsclient_RPCStatClose - close a previously opened rx connection.
2314 * IN rpcStatHandle - an rx connection returned by afsclient_RPCStatOpen
2318 * No locks are obtained or released by this function
2326 * Returns != 0 upon successful completion.
2329 int ADMINAPI afsclient_RPCStatClose(
2330 struct rx_connection *rpcStatHandle,
2334 afs_status_t tst = 0;
2336 if (rpcStatHandle == NULL) {
2337 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2338 goto fail_afsclient_RPCStatClose;
2341 rx_ReleaseCachedConnection(rpcStatHandle);
2343 fail_afsclient_RPCStatClose:
2352 * afsclient_CMStatOpen - open an rx connection to a server to retrieve
2357 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2359 * IN serverName - the host name where the server resides.
2361 * OUT cmStatHandleP - contains an rx connection to the server of interest
2365 * No locks are obtained or released by this function
2373 * Returns != 0 upon successful completion.
2376 int ADMINAPI afsclient_CMStatOpen(
2377 const void *cellHandle,
2378 const char *serverName,
2379 struct rx_connection **cmStatHandleP,
2383 afs_status_t tst = 0;
2384 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2386 struct rx_securityClass *sc;
2388 if (!CellHandleIsValid(cellHandle, &tst)) {
2389 goto fail_afsclient_CMStatOpen;
2392 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2393 goto fail_afsclient_CMStatOpen;
2396 if (cmStatHandleP == NULL) {
2397 tst = ADMCLIENTCMSTATHANDLEPNULL;
2398 goto fail_afsclient_CMStatOpen;
2401 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2403 *cmStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2404 htons(AFSCONF_CALLBACKPORT),
2407 c_handle->tokens->sc_index);
2409 if (*cmStatHandleP == NULL) {
2410 tst = ADMCLIENTCMSTATNOCONNECTION;
2411 goto fail_afsclient_CMStatOpen;
2415 fail_afsclient_CMStatOpen:
2424 * afsclient_CMStatOpenPort - open an rx connection to a server to retrieve
2429 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2431 * IN serverName - the host name where the server resides.
2433 * IN port - the UDP port number where the server resides.
2435 * OUT cmStatHandleP - contains an rx connection to the server of interest
2439 * No locks are obtained or released by this function
2447 * Returns != 0 upon successful completion.
2450 int ADMINAPI afsclient_CMStatOpenPort(
2451 const void *cellHandle,
2452 const char *serverName,
2453 const int serverPort,
2454 struct rx_connection **cmStatHandleP,
2458 afs_status_t tst = 0;
2459 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2461 struct rx_securityClass *sc;
2463 if (!CellHandleIsValid(cellHandle, &tst)) {
2464 goto fail_afsclient_CMStatOpenPort;
2467 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2468 goto fail_afsclient_CMStatOpenPort;
2471 if (cmStatHandleP == NULL) {
2472 tst = ADMCLIENTCMSTATHANDLEPNULL;
2473 goto fail_afsclient_CMStatOpenPort;
2476 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2478 *cmStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2482 c_handle->tokens->sc_index);
2484 if (*cmStatHandleP == NULL) {
2485 tst = ADMCLIENTCMSTATNOCONNECTION;
2486 goto fail_afsclient_CMStatOpenPort;
2490 fail_afsclient_CMStatOpenPort:
2499 * afsclient_CMStatClose - close a previously opened rx connection.
2503 * IN cmStatHandle - an rx connection returned by afsclient_CMStatOpen
2507 * No locks are obtained or released by this function
2515 * Returns != 0 upon successful completion.
2518 int ADMINAPI afsclient_CMStatClose(
2519 struct rx_connection *cmStatHandle,
2523 afs_status_t tst = 0;
2525 if (cmStatHandle == NULL) {
2526 tst = ADMCLIENTCMSTATHANDLEPNULL;
2527 goto fail_afsclient_CMStatClose;
2530 rx_ReleaseCachedConnection(cmStatHandle);
2532 fail_afsclient_CMStatClose:
2541 * afsclient_RXDebugOpen - open an rxdebug handle to a server.
2545 * IN serverName - the host name where the server resides.
2547 * IN type - what type of process to query
2549 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2553 * No locks are obtained or released by this function
2561 * Returns != 0 upon successful completion.
2564 int ADMINAPI afsclient_RXDebugOpen(
2565 const char *serverName,
2566 afs_stat_source_t type,
2567 rxdebugHandle_p *rxdebugHandleP,
2571 afs_status_t tst = 0;
2573 rxdebugHandle_p handle;
2574 rxdebugSocket_t sock;
2575 struct sockaddr_in taddr;
2579 if (rxdebugHandleP == NULL) {
2580 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2581 goto fail_afsclient_RXDebugOpen;
2587 serverPort = AFSCONF_NANNYPORT;
2590 case AFS_FILESERVER:
2591 serverPort = AFSCONF_FILEPORT;
2595 serverPort = AFSCONF_KAUTHPORT;
2599 serverPort = AFSCONF_PROTPORT;
2603 serverPort = AFSCONF_VOLUMEPORT;
2607 serverPort = AFSCONF_VLDBPORT;
2611 serverPort = AFSCONF_CALLBACKPORT;
2615 tst = ADMTYPEINVALID;
2616 goto fail_afsclient_RXDebugOpen;
2619 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2620 goto fail_afsclient_RXDebugOpen;
2623 sock = (rxdebugSocket_t)socket(AF_INET, SOCK_DGRAM, 0);
2624 if (sock == INVALID_RXDEBUG_SOCKET) {
2626 goto fail_afsclient_RXDebugOpen;
2629 memset(&taddr, 0, sizeof(taddr));
2630 taddr.sin_family = AF_INET;
2632 taddr.sin_addr.s_addr = INADDR_ANY;
2633 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2637 goto fail_afsclient_RXDebugOpen;
2640 handle = (rxdebugHandle_p)malloc(sizeof(rxdebugHandle_t));
2644 goto fail_afsclient_RXDebugOpen;
2647 handle->sock = sock;
2648 handle->ipAddr = serverAddr;
2649 handle->udpPort = serverPort;
2650 handle->firstFlag = 1;
2651 handle->supportedStats = 0;
2652 *rxdebugHandleP = handle;
2655 fail_afsclient_RXDebugOpen:
2664 * afsclient_RXDebugOpenPort - open an rxdebug handle to a server.
2668 * IN serverName - the host name where the server resides.
2670 * IN port - the UDP port number where the server resides.
2672 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2676 * No locks are obtained or released by this function
2684 * Returns != 0 upon successful completion.
2687 int ADMINAPI afsclient_RXDebugOpenPort(
2688 const char *serverName,
2690 rxdebugHandle_p *rxdebugHandleP,
2694 afs_status_t tst = 0;
2696 rxdebugHandle_p handle;
2697 rxdebugSocket_t sock;
2698 struct sockaddr_in taddr;
2701 if (rxdebugHandleP == NULL) {
2702 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2703 goto fail_afsclient_RXDebugOpenPort;
2706 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2707 goto fail_afsclient_RXDebugOpenPort;
2710 sock = (rxdebugSocket_t)socket(AF_INET, SOCK_DGRAM, 0);
2711 if (sock == INVALID_RXDEBUG_SOCKET) {
2713 goto fail_afsclient_RXDebugOpenPort;
2716 memset(&taddr, 0, sizeof(taddr));
2717 taddr.sin_family = AF_INET;
2719 taddr.sin_addr.s_addr = INADDR_ANY;
2720 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2724 goto fail_afsclient_RXDebugOpenPort;
2727 handle = (rxdebugHandle_p)malloc(sizeof(rxdebugHandle_t));
2731 goto fail_afsclient_RXDebugOpenPort;
2734 handle->sock = sock;
2735 handle->ipAddr = serverAddr;
2736 handle->udpPort = serverPort;
2737 handle->firstFlag = 1;
2738 handle->supportedStats = 0;
2739 *rxdebugHandleP = handle;
2742 fail_afsclient_RXDebugOpenPort:
2751 * afsclient_RXDebugClose - close a previously opened rxdebug handle.
2755 * IN rxdebugHandle - an rxdebug handle returned by afsclient_RXDebugOpen
2759 * No locks are obtained or released by this function
2767 * Returns != 0 upon successful completion.
2770 int ADMINAPI afsclient_RXDebugClose(
2771 rxdebugHandle_p rxdebugHandle,
2775 afs_status_t tst = 0;
2777 if (rxdebugHandle == NULL) {
2778 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2779 goto fail_afsclient_RXDebugClose;
2782 close(rxdebugHandle->sock);
2783 free(rxdebugHandle);
2785 fail_afsclient_RXDebugClose: