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
10 #include <afsconfig.h>
11 #include <afs/param.h>
17 #include "afs_clientAdmin.h"
18 #include "../adminutil/afs_AdminInternal.h"
21 #include <sys/types.h>
22 #include <afs/cellconfig.h>
24 #include <afs/afssyscalls.h>
26 #include <afs/fs_utils.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
32 #include <afs/venus.h>
38 #include <afs/kautils.h>
40 #include <rx/rx_null.h>
42 #include <afs/dirpath.h>
43 #include <afs/afs_AdminErrors.h>
44 #include <afs/afs_vosAdmin.h>
45 #include <afs/afs_utilAdmin.h>
46 #include <afs/ptserver.h>
47 #include <afs/vlserver.h>
48 #include <afs/pthread_glock.h>
51 * AFS client administration functions.
53 * Admin functions that are normally associated with the client.
55 * All of the functions related to authentication are here, plus
56 * some miscellaneous others.
60 static const unsigned long ADMIN_TICKET_LIFETIME = 24 * 3600;
63 * We need a way to track whether or not the client library has been
64 * initialized. We count on the fact that the other library initialization
65 * functions are protected by their own once mechanism. We only track
66 * our own internal status
69 static int client_init;
70 static pthread_once_t client_init_once = PTHREAD_ONCE_INIT;
79 * IsTokenValid - validate a token handle
83 * IN token - the token to be validated.
87 * No locks are obtained or released by this function
95 * Returns != 0 upon successful completion.
99 IsTokenValid(const afs_token_handle_p token, afs_status_p st)
102 afs_status_t tst = 0;
105 tst = ADMCLIENTTOKENHANDLENULL;
106 goto fail_IsTokenValid;
109 if (token->is_valid == 0) {
110 tst = ADMCLIENTTOKENHANDLEINVALID;
111 goto fail_IsTokenValid;
114 if ((token->begin_magic != BEGIN_MAGIC)
115 || (token->end_magic != END_MAGIC)) {
116 tst = ADMCLIENTTOKENHANDLEBADMAGIC;
117 goto fail_IsTokenValid;
130 * afsclient_TokenGetExisting - get tokens that already exist and
131 * are held by the cache manager.
135 * IN cellName - the name of the cell where the token originated.
137 * OUT tokenHandle - a handle to the tokens if they were obtained
142 * No locks are obtained or released by this function
146 * The tokenHandle returned by this function cannot be used for kas
147 * related operations, since kas tokens aren't stored in the kernel.
151 * Returns != 0 upon successful completion.
155 afsclient_TokenGetExisting(const char *cellName, void **tokenHandle,
159 afs_status_t tst = 0;
160 struct ktc_principal afs_server;
161 afs_token_handle_p t_handle =
162 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
164 if (client_init == 0) {
165 tst = ADMCLIENTNOINIT;
166 goto fail_afsclient_TokenGetExisting;
169 if (cellName == NULL) {
170 tst = ADMCLIENTCELLNAMENULL;
171 goto fail_afsclient_TokenGetExisting;
174 if (tokenHandle == NULL) {
175 tst = ADMCLIENTTOKENHANDLENULL;
176 goto fail_afsclient_TokenGetExisting;
179 if (t_handle == NULL) {
181 goto fail_afsclient_TokenGetExisting;
184 strcpy(afs_server.name, "afs");
185 afs_server.instance[0] = 0;
186 strcpy(afs_server.cell, cellName);
190 ktc_GetToken(&afs_server, &t_handle->afs_token,
191 sizeof(t_handle->afs_token), &t_handle->client))) {
193 * The token has been retrieved successfully, initialize
194 * the rest of the token handle structure
196 strcpy(t_handle->cell, cellName);
197 t_handle->afs_token_set = 1;
198 t_handle->from_kernel = 1;
199 t_handle->kas_token_set = 0;
200 t_handle->sc_index = 2;
201 t_handle->afs_sc[t_handle->sc_index] =
202 rxkad_NewClientSecurityObject(rxkad_clear,
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 t_handle->afs_encrypt_sc[t_handle->sc_index] =
208 rxkad_NewClientSecurityObject(rxkad_crypt,
209 &t_handle->afs_token.sessionKey,
210 t_handle->afs_token.kvno,
211 t_handle->afs_token.ticketLen,
212 t_handle->afs_token.ticket);
213 if ((t_handle->afs_sc[t_handle->sc_index] == NULL)
214 || (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
215 tst = ADMCLIENTTOKENHANDLENOSECURITY;
216 goto fail_afsclient_TokenGetExisting;
218 t_handle->begin_magic = BEGIN_MAGIC;
219 t_handle->is_valid = 1;
220 t_handle->end_magic = END_MAGIC;
221 *tokenHandle = (void *)t_handle;
224 goto fail_afsclient_TokenGetExisting;
228 fail_afsclient_TokenGetExisting:
230 if ((rc == 0) && (t_handle != NULL)) {
240 * afsclient_TokenSet - set the tokens represented by tokenHandle to be
241 * active in the kernel (aka ka_SetToken).
245 * IN cellName - the name of the cell where the token originated.
247 * OUT tokenHandle - a handle to the tokens if they were obtained
252 * No locks are obtained or released by this function
256 * The tokenHandle returned by this function cannot be used for kas
257 * related operations, since kas tokens aren't stored in the kernel.
261 * Returns != 0 upon successful completion.
265 afsclient_TokenSet(const void *tokenHandle, afs_status_p st)
268 afs_status_t tst = 0;
269 struct ktc_principal afs_server;
270 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
272 if (!IsTokenValid(t_handle, &tst)) {
273 goto fail_afsclient_TokenSet;
276 strcpy(afs_server.name, "afs");
277 afs_server.instance[0] = 0;
278 strcpy(afs_server.cell, t_handle->cell);
281 ktc_SetToken(&afs_server, &t_handle->afs_token, &t_handle->client, 0);
287 fail_afsclient_TokenSet:
296 * GetKASToken - get a KAS token and store it in the tokenHandle.
300 * IN cellName - the name of the cell where the token should be obtained.
302 * IN principal - the name of the user of the token.
304 * IN password - the password for the principal.
306 * OUT tokenHandle - a handle to the tokens if they were obtained
311 * No locks are obtained or released by this function
319 * Returns != 0 upon successful completion.
323 GetKASToken(const char *cellName, const char *principal, const char *password,
324 afs_token_handle_p tokenHandle, afs_status_p st)
327 afs_status_t tst = 0;
328 struct ubik_client *unauth_conn;
330 struct ktc_encryptionKey key;
331 struct ktc_token *token;
332 unsigned long now = time(0);
333 char name[MAXKTCNAMELEN];
334 char inst[MAXKTCNAMELEN];
335 int have_server_conn = 0;
337 token = &tokenHandle->kas_token;
339 ka_StringToKey((char *)password, (char *)cellName, &key);
342 * Get an unauthenticated connection in the right cell to use for
343 * retrieving the token.
347 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
350 goto fail_GetKASToken;
352 have_server_conn = 1;
354 tst = ka_ParseLoginName((char *)principal, name, inst, NULL);
356 goto fail_GetKASToken;
360 ka_Authenticate(name, inst, (char *)cellName, unauth_conn,
361 KA_MAINTENANCE_SERVICE, &key, now,
362 now + ADMIN_TICKET_LIFETIME, token, &expire);
364 goto fail_GetKASToken;
370 if (have_server_conn) {
371 ubik_ClientDestroy(unauth_conn);
381 * GetAFSToken - get a AFS token and store it in the tokenHandle.
385 * IN cellName - the name of the cell where the token should be obtained.
387 * IN principal - the name of the user of the token.
389 * IN password - the password for the principal.
391 * OUT tokenHandle - a handle to the tokens if they were obtained
396 * No locks are obtained or released by this function
404 * Returns != 0 upon successful completion.
408 GetAFSToken(const char *cellName, const char *principal, const char *password,
409 afs_token_handle_p tokenHandle, afs_status_p st)
412 afs_status_t tst = 0;
413 struct ubik_client *unauth_conn = NULL, *auth_conn = NULL;
415 struct ktc_encryptionKey key;
416 struct ktc_token auth_token;
417 struct ktc_token *token;
418 unsigned long now = time(0);
420 token = &tokenHandle->afs_token;
422 ka_StringToKey((char *)password, (char *)cellName, &key);
425 * Get an unauthenticated connection in the right cell to use for
426 * retrieving the token.
430 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
433 goto fail_GetAFSToken;
437 ka_ParseLoginName((char *)principal, tokenHandle->client.name,
438 tokenHandle->client.instance, NULL);
440 goto fail_GetAFSToken;
444 ka_Authenticate(tokenHandle->client.name,
445 tokenHandle->client.instance, (char *)cellName,
446 unauth_conn, KA_TICKET_GRANTING_SERVICE, &key, now,
447 now + ADMIN_TICKET_LIFETIME, &auth_token, &expire);
449 goto fail_GetAFSToken;
453 ka_AuthServerConn((char *)cellName, KA_TICKET_GRANTING_SERVICE, 0,
456 goto fail_GetAFSToken;
460 ka_CellToRealm((char *)cellName, tokenHandle->client.cell, (int *)0);
462 goto fail_GetAFSToken;
466 ka_GetToken("afs", "", (char *)cellName, tokenHandle->client.name,
467 tokenHandle->client.instance, auth_conn, now,
468 now + ADMIN_TICKET_LIFETIME, &auth_token,
469 tokenHandle->client.cell, token);
471 goto fail_GetAFSToken;
478 ubik_ClientDestroy(auth_conn);
482 ubik_ClientDestroy(unauth_conn);
493 * afsclient_TokenGetNew - get new tokens for a user and store them
494 * in the tokenHandle.
498 * IN cellName - the name of the cell where the tokens should be obtained.
500 * IN principal - the name of the user of the tokens.
502 * IN password - the password for the principal.
504 * OUT tokenHandle - a handle to the tokens if they were obtained
509 * No locks are obtained or released by this function
517 * Returns != 0 upon successful completion.
521 afsclient_TokenGetNew(const char *cellName, const char *principal,
522 const char *password, void **tokenHandle,
526 afs_status_t tst = 0;
527 afs_token_handle_p t_handle =
528 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
530 if (client_init == 0) {
531 tst = ADMCLIENTNOINIT;
532 goto fail_afsclient_TokenGetNew;
535 if (t_handle == NULL) {
537 goto fail_afsclient_TokenGetNew;
541 * Check to see if the principal or password is missing. If it is,
542 * get unauthenticated tokens for the cell
545 if ((principal == NULL) || (*principal == 0) || (password == NULL)
546 || (*password == 0)) {
547 t_handle->from_kernel = 0;
548 t_handle->afs_token_set = 1;
549 t_handle->kas_token_set = 1;
550 t_handle->sc_index = 0;
551 t_handle->afs_sc[t_handle->sc_index] =
552 rxnull_NewClientSecurityObject();
553 t_handle->afs_encrypt_sc[t_handle->sc_index] =
554 rxnull_NewClientSecurityObject();
555 t_handle->kas_sc[t_handle->sc_index] =
556 rxnull_NewClientSecurityObject();
557 t_handle->begin_magic = BEGIN_MAGIC;
558 t_handle->is_valid = 1;
559 t_handle->afs_token.endTime = 0;
560 t_handle->end_magic = END_MAGIC;
561 *tokenHandle = (void *)t_handle;
566 * create an authenticated token
569 if ((GetAFSToken(cellName, principal, password, t_handle, &tst))
570 && (GetKASToken(cellName, principal, password, t_handle, &tst))) {
571 strcpy(t_handle->cell, cellName);
572 t_handle->from_kernel = 0;
573 t_handle->afs_token_set = 1;
574 t_handle->kas_token_set = 1;
575 t_handle->sc_index = 2;
576 t_handle->afs_sc[t_handle->sc_index] =
577 rxkad_NewClientSecurityObject(rxkad_clear,
578 &t_handle->afs_token.sessionKey,
579 t_handle->afs_token.kvno,
580 t_handle->afs_token.ticketLen,
581 t_handle->afs_token.ticket);
582 t_handle->afs_encrypt_sc[t_handle->sc_index] =
583 rxkad_NewClientSecurityObject(rxkad_crypt,
584 &t_handle->afs_token.sessionKey,
585 t_handle->afs_token.kvno,
586 t_handle->afs_token.ticketLen,
587 t_handle->afs_token.ticket);
588 t_handle->kas_sc[t_handle->sc_index] =
589 rxkad_NewClientSecurityObject(rxkad_crypt,
590 &t_handle->kas_token.sessionKey,
591 t_handle->kas_token.kvno,
592 t_handle->kas_token.ticketLen,
593 t_handle->kas_token.ticket);
594 if ((t_handle->afs_sc[t_handle->sc_index] != NULL)
595 && (t_handle->afs_encrypt_sc[t_handle->sc_index] != NULL)
596 && (t_handle->kas_sc[t_handle->sc_index] != NULL)) {
597 t_handle->begin_magic = BEGIN_MAGIC;
598 t_handle->is_valid = 1;
599 t_handle->end_magic = END_MAGIC;
600 *tokenHandle = (void *)t_handle;
602 tst = ADMCLIENTTOKENHANDLENOSECURITY;
603 goto fail_afsclient_TokenGetNew;
606 goto fail_afsclient_TokenGetNew;
611 fail_afsclient_TokenGetNew:
613 if ((rc == 0) && (t_handle != NULL)) {
624 * afsclient_TokenQuery - get the expiration time of the tokens.
628 * IN tokenHandle - a previously obtained valid token.
630 * OUT expirationDateP - the time at which the tokens expire.
632 * OUT principal - the owning principal
634 * OUT instance - principal instance if it exists.
636 * OUT cell - the principal's cell
638 * OUT hasKasTokens - set to 1 if the token handle contains kas tokens.
642 * No locks are obtained or released by this function
646 * We only check the AFS tokens since we always get these. The
647 * KAS tokens may expirer later than the AFS tokens, but this
648 * difference is minor and reporting an earlier time won't cause
653 * Returns != 0 upon successful completion.
657 afsclient_TokenQuery(void *tokenHandle, unsigned long *expirationDateP,
658 char *principal, char *instance, char *cell,
659 int *hasKasTokens, afs_status_p st)
662 afs_status_t tst = 0;
663 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
665 if (client_init == 0) {
666 tst = ADMCLIENTNOINIT;
668 goto fail_afsclient_TokenQuery;
671 if (IsTokenValid(t_handle, &tst)) {
672 if (principal != NULL) {
673 strcpy(principal, t_handle->client.name);
675 if (instance != NULL) {
676 strcpy(instance, t_handle->client.instance);
679 strcpy(cell, t_handle->client.cell);
681 if (hasKasTokens != NULL) {
682 *hasKasTokens = t_handle->kas_token_set;
684 if (expirationDateP != NULL) {
685 *expirationDateP = t_handle->afs_token.endTime;
690 fail_afsclient_TokenQuery:
699 * afsclient_TokenClose - close an existing token.
703 * IN token - the token to be closed.
707 * No locks are obtained or released by this function
715 * Returns != 0 upon successful completion.
719 afsclient_TokenClose(const void *tokenHandle, afs_status_p st)
722 afs_status_t tst = 0;
723 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
725 if (client_init == 0) {
726 tst = ADMCLIENTNOINIT;
727 goto fail_afsclient_TokenClose;
730 if (IsTokenValid(t_handle, &tst)) {
731 t_handle->is_valid = 0;
736 fail_afsclient_TokenClose:
744 #define NUM_SERVER_TYPES 3
746 /* must match NUM_SERVER_TYPES */
747 typedef enum { KAS, PTS, VOS } afs_server_list_t;
749 typedef struct afs_server {
752 struct ubik_client **ubik;
753 struct rx_securityClass *sc;
755 } afs_server_t, *afs_server_p;
757 static afs_server_t servers[NUM_SERVER_TYPES]
758 = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
759 {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
760 {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}
764 * afsclient_CellOpen - Open a particular cell for work as a particular
769 * IN cellName - the cell where future admin calls will be made.
771 * IN tokenHandle - the tokens work will be done under.
773 * OUT cellHandleP - an opaque pointer that is the first parameter to
774 * almost all subsequent admin api calls.
778 * No locks are obtained or released by this function
786 * Returns != 0 upon successful completion.
790 afsclient_CellOpen(const char *cellName, const void *tokenHandle,
791 void **cellHandleP, afs_status_p st)
794 afs_status_t tst = 0;
795 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
796 afs_cell_handle_p c_handle = (afs_cell_handle_p)
797 calloc(1, sizeof(afs_cell_handle_t));
798 struct afsconf_dir *tdir = NULL;
799 struct afsconf_cell info;
800 struct rx_connection *serverconns[MAXSERVERS];
802 struct rx_securityClass *sc[3];
804 char copyCell[MAXCELLCHARS];
806 if (client_init == 0) {
807 tst = ADMCLIENTNOINIT;
808 goto fail_afsclient_CellOpen;
811 if (c_handle == NULL) {
813 goto fail_afsclient_CellOpen;
816 if (t_handle == NULL) {
817 tst = ADMCLIENTTOKENHANDLENULL;
818 goto fail_afsclient_CellOpen;
821 if ((cellName == NULL) || (*cellName == 0)) {
822 tst = ADMCLIENTCELLNAMENULL;
823 goto fail_afsclient_CellOpen;
826 if (cellHandleP == NULL) {
827 tst = ADMCLIENTCELLHANDLEPNULL;
828 goto fail_afsclient_CellOpen;
832 * Check that the token handle contains valid data and the calloc
835 if (!t_handle->afs_token_set) {
836 tst = ADMCLIENTCELLOPENBADTOKEN;
837 goto fail_afsclient_CellOpen;
841 * Use a table to initialize the cell handle structure, since
842 * most of the steps are the same for all the servers.
844 * Start by creating rx_securityClass objects for each of the
845 * servers. A potential optimization is to do this in
846 * afsclient_TokenGetNew and just keep the expiration time of
848 * Also, initialize the ubik client pointers in the table
850 servers[KAS].sc = t_handle->kas_sc[t_handle->sc_index];
851 servers[PTS].sc = t_handle->afs_sc[t_handle->sc_index];
852 servers[VOS].sc = servers[PTS].sc;
853 servers[KAS].ubik = &c_handle->kas;
854 servers[PTS].ubik = &c_handle->pts;
855 servers[VOS].ubik = &c_handle->vos;
856 servers[KAS].valid = &c_handle->kas_valid;
857 servers[PTS].valid = &c_handle->pts_valid;
858 servers[VOS].valid = &c_handle->vos_valid;
859 c_handle->vos_new = 1;
861 if ((servers[PTS].sc == NULL) || (servers[VOS].sc == NULL)) {
862 tst = ADMCLIENTBADTOKENHANDLE;
863 goto fail_afsclient_CellOpen;
867 * If the initialization has succeeded so far, get the address
868 * information for each server in the cell
871 strcpy(c_handle->working_cell, cellName);
872 if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
873 tst = ADMCLIENTBADCLIENTCONFIG;
874 goto fail_afsclient_CellOpen;
878 * We must copy the cellName here because afsconf_GetCellInfo
879 * actually writes over the cell name it is passed.
881 strncpy(copyCell, cellName, MAXCELLCHARS - 1);
882 for (i = 0; (i < NUM_SERVER_TYPES); i++) {
885 ka_AuthServerConn((char *)cellName, servers[i].serviceId,
886 ((t_handle->sc_index == 0)
888 kas_token_set)) ? 0 : &t_handle->
889 kas_token, servers[i].ubik);
891 goto fail_afsclient_CellOpen;
894 tst = afsconf_GetCellInfo(tdir, copyCell, servers[i].serv, &info);
896 /* create ubik client handles for each server */
897 scIndex = t_handle->sc_index;
898 sc[scIndex] = servers[i].sc;
899 for (j = 0; (j < info.numServers); j++) {
901 rx_GetCachedConnection(info.hostAddr[j].sin_addr.
903 info.hostAddr[j].sin_port,
904 servers[i].serviceId,
905 sc[scIndex], scIndex);
908 tst = ubik_ClientInit(serverconns, servers[i].ubik);
910 goto fail_afsclient_CellOpen;
913 goto fail_afsclient_CellOpen;
916 /* initialization complete, mark handle valid */
917 *servers[i].valid = 1;
919 c_handle->tokens = t_handle;
922 fail_afsclient_CellOpen:
929 * Upon error, free any obtained resources.
932 if (c_handle != NULL) {
933 if (c_handle->kas_valid)
934 ubik_ClientDestroy(c_handle->kas);
935 if (c_handle->pts_valid)
936 ubik_ClientDestroy(c_handle->pts);
937 if (c_handle->vos_valid)
938 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.
977 afsclient_NullCellOpen(void **cellHandleP, afs_status_p st)
980 afs_status_t tst = 0;
981 afs_cell_handle_p c_handle = (afs_cell_handle_p)
982 calloc(1, sizeof(afs_cell_handle_t));
986 * Validate parameters
989 if (cellHandleP == NULL) {
990 tst = ADMCLIENTCELLHANDLEPNULL;
991 goto fail_afsclient_NullCellOpen;
994 if (client_init == 0) {
995 tst = ADMCLIENTNOINIT;
996 goto fail_afsclient_NullCellOpen;
999 if (c_handle == NULL) {
1001 goto fail_afsclient_NullCellOpen;
1005 * Get unauthenticated tokens for any cell
1008 if (!afsclient_TokenGetNew(0, 0, 0, (void *)&c_handle->tokens, &tst)) {
1009 goto fail_afsclient_NullCellOpen;
1012 c_handle->begin_magic = BEGIN_MAGIC;
1013 c_handle->is_valid = 1;
1014 c_handle->is_null = 1;
1015 c_handle->end_magic = END_MAGIC;
1016 c_handle->kas_valid = 0;
1017 c_handle->pts_valid = 0;
1018 c_handle->vos_valid = 0;
1022 *cellHandleP = (void *)c_handle;
1025 fail_afsclient_NullCellOpen:
1034 * afsclient_CellClose - close a previously opened cellHandle.
1038 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
1042 * No locks are obtained or released by this function
1050 * Returns != 0 upon successful completion.
1054 afsclient_CellClose(const void *cellHandle, afs_status_p st)
1057 afs_status_t tst = 0;
1058 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1060 if (client_init == 0) {
1061 tst = ADMCLIENTNOINIT;
1062 goto fail_afsclient_CellClose;
1065 if (c_handle == NULL) {
1066 tst = ADMCLIENTCELLHANDLENULL;
1067 goto fail_afsclient_CellClose;
1070 if (c_handle->kas_valid)
1071 ubik_ClientDestroy(c_handle->kas);
1072 if (c_handle->pts_valid)
1073 ubik_ClientDestroy(c_handle->pts);
1074 if (c_handle->vos_valid)
1075 ubik_ClientDestroy(c_handle->vos);
1076 if (c_handle->is_null)
1077 afsclient_TokenClose(c_handle->tokens, 0);
1078 c_handle->kas_valid = 0;
1079 c_handle->pts_valid = 0;
1080 c_handle->vos_valid = 0;
1081 c_handle->is_valid = 0;
1085 fail_afsclient_CellClose:
1095 * afsclient_CellNameGet() -- get a pointer to the cell name in a cell handle
1099 * IN cellHandle - a valid cell handle
1100 * OUT cellNameP - a pointer to the cell name in the cell handle.
1104 * No locks are obtained or released by this function
1108 * If cellHandle is closed then the pointer returned by this function
1109 * is no longer valid.
1113 * Returns != 0 upon successful completion.
1116 afsclient_CellNameGet(const void *cellHandle, const char **cellNameP,
1120 afs_status_t tst = 0;
1121 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1123 if (!CellHandleIsValid(cellHandle, &tst)) {
1124 goto fail_afsclient_CellNameGet;
1127 *cellNameP = c_handle->working_cell;
1130 fail_afsclient_CellNameGet:
1140 * afsclient_LocalCellGet - get the name of the cell the machine
1141 * belongs to where this process is running.
1145 * OUT cellName - an array of characters that must be MAXCELLCHARS
1150 * No locks are obtained or released by this function
1154 * If cellName is smaller than MAXCELLCHARS chars, this function won't
1159 * Returns != 0 upon successful completion.
1163 afsclient_LocalCellGet(char *cellName, afs_status_p st)
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);
1208 client_ExtractDriveLetter(char *path)
1212 if (path[0] != 0 && path[1] == ':') {
1221 * Determine the parent directory of a give directory
1225 Parent(char *directory, char *parentDirectory)
1230 strcpy(parentDirectory, directory);
1231 tp = strrchr(parentDirectory, '\\');
1233 /* lv trailing slash so Parent("k:\foo") is "k:\" not "k :" */
1237 if (client_ExtractDriveLetter(parentDirectory)) {
1238 strcat(parentDirectory, ".");
1248 * Determine the parent directory of a give directory
1251 Parent(const char *directory, char *parentDirectory)
1256 strcpy(parentDirectory, directory);
1257 tp = strrchr(parentDirectory, '/');
1262 strcpy(parentDirectory, ".");
1271 * afsclient_MountPointCreate - create a mount point for a volume.
1275 * IN cellHandle - a handle to the cell where volumeName resides.
1277 * IN directory - the directory where the mountpoint should be created.
1279 * IN volumeName - the name of the volume to mount.
1281 * IN volType - the type of mount point to create.
1283 * IN volCheck - indicates whether or not to check the VLDB to see if
1284 * volumeName exists.
1288 * No locks are obtained or released by this function
1292 * Returns != 0 upon successful completion.
1295 #define TMP_DATA_SIZE 2048
1298 afsclient_MountPointCreate(const void *cellHandle, const char *directory,
1299 const char *volumeName, vol_type_t volType,
1300 vol_check_t volCheck, afs_status_p st)
1303 afs_status_t tst = 0;
1304 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1305 char parent_dir[TMP_DATA_SIZE];
1306 char space[TMP_DATA_SIZE];
1307 char directoryCell[MAXCELLCHARS];
1308 struct ViceIoctl idata;
1310 vos_vldbEntry_t vldbEntry;
1313 * Validate arguments
1316 if (client_init == 0) {
1317 tst = ADMCLIENTNOINIT;
1318 goto fail_afsclient_MountPointCreate;
1321 if ((directory == NULL) || (*directory == 0)) {
1322 tst = ADMCLIENTDIRECTORYNULL;
1323 goto fail_afsclient_MountPointCreate;
1326 if ((volumeName == NULL) || (*volumeName == 0)) {
1327 tst = ADMCLIENTVOLUMENAME;
1328 goto fail_afsclient_MountPointCreate;
1332 * Extract the parent directory and make sure it is in AFS.
1335 if (!Parent(directory, parent_dir)) {
1336 tst = ADMCLIENTBADDIRECTORY;
1337 goto fail_afsclient_MountPointCreate;
1341 idata.out_size = TMP_DATA_SIZE;
1343 i = pioctl(parent_dir, VIOC_FILE_CELL_NAME, &idata, 1);
1345 if ((errno == EINVAL) || (errno == ENOENT)) {
1346 tst = ADMCLIENTNOAFSDIRECTORY;
1347 goto fail_afsclient_MountPointCreate;
1350 strcpy(directoryCell, space);
1353 * If the user requested, check that the volume exists
1356 if (volCheck == CHECK_VOLUME) {
1357 if (!vos_VLDBGet(cellHandle, 0, 0, volumeName, &vldbEntry, &tst)) {
1358 goto fail_afsclient_MountPointCreate;
1363 * Begin constructing the pioctl buffer
1366 if (volType == READ_WRITE) {
1373 * Append the cell to the mount point if the volume is in a different
1374 * cell than the directory
1377 if (strcmp(c_handle->working_cell, directoryCell)) {
1378 strcat(space, c_handle->working_cell);
1381 strcat(space, volumeName);
1388 idata.in_size = 1 + strlen(space);
1390 if (tst = pioctl(directory, VIOC_AFS_CREATE_MT_PT, &idata, 0)) {
1391 goto fail_afsclient_MountPointCreate;
1394 if ((tst = symlink(space, directory))) {
1395 goto fail_afsclient_MountPointCreate;
1401 fail_afsclient_MountPointCreate:
1409 typedef struct Acl {
1417 afsclient_ACLEntryAdd(const char *directory, const char *user,
1418 const acl_p acl, afs_status_p st)
1421 afs_status_t tst = 0;
1422 struct ViceIoctl idata;
1423 char old_acl_string[2048];
1424 char new_acl_string[2048];
1429 int cur_user_acl = 0;
1434 if (client_init == 0) {
1435 tst = ADMCLIENTNOINIT;
1436 goto fail_afsclient_ACLEntryAdd;
1439 if ((directory == NULL) || (*directory == 0)) {
1440 tst = ADMMISCDIRECTORYNULL;
1441 goto fail_afsclient_ACLEntryAdd;
1444 if ((user == NULL) || (*user == 0)) {
1445 tst = ADMMISCUSERNULL;
1446 goto fail_afsclient_ACLEntryAdd;
1450 tst = ADMMISCACLNULL;
1451 goto fail_afsclient_ACLEntryAdd;
1454 if (acl->read == READ) {
1458 if (acl->write == WRITE) {
1462 if (acl->insert == INSERT) {
1466 if (acl->lookup == LOOKUP) {
1470 if (acl->del == DELETE) {
1474 if (acl->lock == LOCK) {
1478 if (acl->admin == ADMIN) {
1483 * Get the current acl for the directory
1486 idata.out_size = 2048;
1488 idata.in = idata.out = old_acl_string;
1489 tst = pioctl(directory, VIOCGETAL, &idata, 1);
1492 goto fail_afsclient_ACLEntryAdd;
1496 * The acl is presented to us in string format. The format of the
1499 * A header which contains the number of positive and negative entries
1500 * and a string indicating whether or not this is a dfs acl:
1502 * num_pos "\n" dfs_string "\n" num_neg
1504 * An entry for each acl that's of the form:
1508 * There are no blanks in the string between fields, but I use them here
1509 * to make the reading easier.
1511 * Since we are only going to add another entry to the acl, our approach
1512 * is simple. Get the num_pos dfs_string and num_neg from the current acl,
1513 * increment num_pos by one and create a new string. Concatenate the new
1514 * user and rights to the new string, and then concatenate the remaining
1515 * contents of the old acl to the new string.
1517 * Unfortunately, this approach doesn't work since the format the kernel
1518 * hands the acl back to us in, is NOT WHAT IT WANTS BACK!!!!
1519 * So instead we need to parse the entire freaking acl and put a space
1520 * between each user and their acl.
1522 * This is really ugly.
1526 * Parse the first few fields of the acl and see if this is a DFS
1531 sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs,
1533 ptr = strchr(old_acl_string, '\n');
1535 sscanf(ptr, "%d", &cur_acl.nminus);
1536 ptr = strchr(ptr, '\n');
1539 tst = ADMMISCNODFSACL;
1540 goto fail_afsclient_ACLEntryAdd;
1543 * It isn't a DFS file, so create the beginning of the string
1544 * we will hand back to the kernel
1546 sprintf(new_acl_string, "%d\n%d\n%s %d\n", (cur_acl.nplus + 1),
1547 cur_acl.nminus, user, newacl);
1551 * Finish scanning the old acl, parsing each user/acl pair and
1552 * adding a space in the new acl.
1555 for (i = 0; i < (cur_acl.nplus + cur_acl.nminus); i++) {
1556 sscanf(ptr, "%s%d\n", cur_user, &cur_user_acl);
1558 * Skip the entry for the user we are replacing/adding
1561 if (strcmp(cur_user, user)) {
1562 ptr = strchr(ptr, '\n');
1564 sprintf(tmp, "%s %d\n", cur_user, cur_user_acl);
1565 strcat(new_acl_string, tmp);
1569 strcat(new_acl_string, ptr);
1576 idata.in_size = strlen(new_acl_string) + 1;
1577 idata.in = idata.out = new_acl_string;
1578 tst = pioctl(directory, VIOCSETAL, &idata, 1);
1581 goto fail_afsclient_ACLEntryAdd;
1585 fail_afsclient_ACLEntryAdd:
1594 * afsclient_Init - initialize AFS components before use.
1600 * No locks are obtained or released by this function
1608 * Returns != 0 upon successful completion.
1612 afsclient_Init(afs_status_p st)
1615 afs_status_t tst = 0;
1618 pthread_once(&client_init_once, client_once);
1621 if (afs_winsockInit() < 0) {
1622 tst = ADMCLIENTCANTINITWINSOCK;
1623 goto fail_afsclient_Init;
1627 if (!(initAFSDirPath() & AFSDIR_CLIENT_PATHS_OK)) {
1628 tst = ADMCLIENTCANTINITAFSLOCATION;
1629 goto fail_afsclient_Init;
1632 if (rx_Init(0) < 0) {
1633 tst = ADMCLIENTCANTINITRX;
1634 goto fail_afsclient_Init;
1637 if ((tst = ka_CellConfig((char *)AFSDIR_CLIENT_ETC_DIRPATH))) {
1638 goto fail_afsclient_Init;
1643 fail_afsclient_Init:
1652 * afsclient_AFSServerGet - determine what kind of server serverName
1653 * is and fill in serverEntryP accordingly.
1657 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1659 * IN serverName - the hostname of the server of interest.
1661 * OUT serverEntryP - upon successful completion contains a description of
1666 * No locks are obtained or released by this function
1674 * Returns != 0 upon successful completion.
1678 afsclient_AFSServerGet(const void *cellHandle, const char *serverName,
1679 afs_serverEntry_p serverEntryP, afs_status_p st)
1682 afs_status_t tst = 0;
1684 int found_match = 0;
1686 if ((serverName == NULL) || (*serverName == 0)) {
1687 tst = ADMUTILSERVERNAMENULL;
1688 goto fail_afsclient_AFSServerGet;
1691 if (serverEntryP == NULL) {
1692 tst = ADMUTILSERVERENTRYPNULL;
1693 goto fail_afsclient_AFSServerGet;
1697 * Iterate over server entries and try to find a match for serverName
1700 if (!afsclient_AFSServerGetBegin(cellHandle, &iter, &tst)) {
1701 goto fail_afsclient_AFSServerGet;
1704 while (afsclient_AFSServerGetNext(iter, serverEntryP, &tst)) {
1705 if (!strcmp(serverName, serverEntryP->serverName)) {
1712 * If we didn't find a match, the iterator should have terminated
1713 * normally. If it didn't, return the error
1717 if (tst != ADMITERATORDONE) {
1718 afsclient_AFSServerGetDone(iter, 0);
1720 afsclient_AFSServerGetDone(iter, &tst);
1722 tst = ADMCLIENTNOMATCHINGSERVER;
1723 goto fail_afsclient_AFSServerGet;
1725 if (!afsclient_AFSServerGetDone(iter, &tst)) {
1726 goto fail_afsclient_AFSServerGet;
1731 fail_afsclient_AFSServerGet:
1740 * The iterator functions and data for the server retrieval functions
1743 typedef struct server_get {
1746 afs_serverEntry_t server[MAXHOSTSPERCELL + BADSERVERID];
1747 afs_serverEntry_t cache[CACHED_ITEMS];
1748 } server_get_t, *server_get_p;
1751 GetServerRPC(void *rpc_specific, int slot, int *last_item,
1752 int *last_item_contains_data, afs_status_p st)
1755 afs_status_t tst = 0;
1756 server_get_p serv = (server_get_p) rpc_specific;
1758 memcpy(&serv->cache[slot], &serv->server[serv->index],
1759 sizeof(afs_serverEntry_t));
1762 if (serv->index == serv->total) {
1764 *last_item_contains_data = 1;
1775 GetServerFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
1778 afs_status_t tst = 0;
1779 server_get_p serv = (server_get_p) rpc_specific;
1781 memcpy(dest, (const void *)&serv->cache[slot], sizeof(afs_serverEntry_t));
1791 * afsclient_AFSServerGetBegin - start the process of iterating over
1792 * every server in the cell.
1796 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1798 * OUT iterationIdP - - upon successful completion contains an iterator
1799 * that can be passed to afsclient_AFSServerGetNext.
1803 * No locks are obtained or released by this function
1811 * Returns != 0 upon successful completion.
1815 afsclient_AFSServerGetBegin(const void *cellHandle, void **iterationIdP,
1819 afs_status_t tst = 0;
1820 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1821 afs_admin_iterator_p iter =
1822 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1823 server_get_p serv = (server_get_p) calloc(1, sizeof(server_get_t));
1824 const char *cellName;
1825 void *database_iter;
1826 util_databaseServerEntry_t database_entry;
1827 void *fileserver_iter;
1828 vos_fileServerEntry_t fileserver_entry;
1829 int iserv, iservaddr, ientryaddr, is_dup;
1830 struct hostent *host;
1832 if (!CellHandleIsValid(c_handle, &tst)) {
1833 goto fail_afsclient_AFSServerGetBegin;
1836 if (iterationIdP == NULL) {
1837 tst = ADMITERATIONIDPNULL;
1838 goto fail_afsclient_AFSServerGetBegin;
1841 if ((serv == NULL) || (iter == NULL)) {
1843 goto fail_afsclient_AFSServerGetBegin;
1847 * Retrieve the list of database servers for this cell.
1850 if (!afsclient_CellNameGet(cellHandle, &cellName, &tst)) {
1851 goto fail_afsclient_AFSServerGetBegin;
1854 if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
1855 goto fail_afsclient_AFSServerGetBegin;
1858 while (util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
1859 serv->server[serv->total].serverAddress[0] =
1860 database_entry.serverAddress;
1861 serv->server[serv->total].serverType = DATABASE_SERVER;
1865 if (tst != ADMITERATORDONE) {
1866 util_DatabaseServerGetDone(database_iter, 0);
1867 goto fail_afsclient_AFSServerGetBegin;
1870 if (!util_DatabaseServerGetDone(database_iter, &tst)) {
1871 goto fail_afsclient_AFSServerGetBegin;
1875 * Retrieve the list of file servers for this cell.
1878 if (!vos_FileServerGetBegin(cellHandle, 0, &fileserver_iter, &tst)) {
1879 goto fail_afsclient_AFSServerGetBegin;
1882 while (vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
1884 * See if any of the addresses returned in this fileserver_entry
1885 * structure already exist in the list of servers we're building.
1886 * If not, create a new record for this server.
1889 for (iserv = 0; iserv < serv->total; iserv++) {
1890 for (ientryaddr = 0; ientryaddr < fileserver_entry.count;
1892 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1894 if (serv->server[iserv].serverAddress[iservaddr] ==
1895 fileserver_entry.serverAddress[ientryaddr]) {
1910 serv->server[iserv].serverType |= FILE_SERVER;
1912 iserv = serv->total++;
1913 serv->server[iserv].serverType = FILE_SERVER;
1917 * Add the addresses from the vldb list to the serv->server[iserv]
1918 * record. Remember that VLDB's list-of-addrs is not guaranteed
1919 * to be unique in a particular entry, or to return only one entry
1920 * per machine--so when we add addresses, always check for
1921 * duplicate entries.
1924 for (ientryaddr = 0; ientryaddr < fileserver_entry.count;
1926 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1928 if (serv->server[iserv].serverAddress[iservaddr] ==
1929 fileserver_entry.serverAddress[ientryaddr]) {
1933 if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
1934 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1936 if (!serv->server[iserv].serverAddress[iservaddr]) {
1937 serv->server[iserv].serverAddress[iservaddr] =
1938 fileserver_entry.serverAddress[ientryaddr];
1946 if (tst != ADMITERATORDONE) {
1947 vos_FileServerGetDone(fileserver_iter, 0);
1948 goto fail_afsclient_AFSServerGetBegin;
1951 if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
1952 goto fail_afsclient_AFSServerGetBegin;
1956 * Iterate over the list and fill in the hostname of each of the servers
1959 LOCK_GLOBAL_MUTEX for (iserv = 0; iserv < serv->total; iserv++) {
1960 int addr = htonl(serv->server[iserv].serverAddress[0]);
1961 host = gethostbyaddr((const char *)&addr, sizeof(int), AF_INET);
1963 strncpy(serv->server[iserv].serverName, host->h_name,
1964 AFS_MAX_SERVER_NAME_LEN);
1969 (iter, (void *)serv, GetServerRPC, GetServerFromCache, NULL, NULL,
1971 *iterationIdP = (void *)iter;
1975 fail_afsclient_AFSServerGetBegin:
1993 * afsclient_AFSServerGetNext - retrieve the next server in the cell.
1997 * IN iterationId - an iterator previously returned by
1998 * afsclient_AFSServerGetBegin.
2000 * OUT serverEntryP - upon successful completion contains the next server.
2004 * No locks are obtained or released by this function
2012 * Returns != 0 upon successful completion.
2016 afsclient_AFSServerGetNext(void *iterationId, afs_serverEntry_p serverEntryP,
2020 afs_status_t tst = 0;
2021 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2023 if (iterationId == NULL) {
2024 tst = ADMITERATORNULL;
2025 goto fail_afsclient_AFSServerGetNext;
2028 if (serverEntryP == NULL) {
2029 tst = ADMUTILSERVERENTRYPNULL;
2030 goto fail_afsclient_AFSServerGetNext;
2033 rc = IteratorNext(iter, (void *)serverEntryP, &tst);
2035 fail_afsclient_AFSServerGetNext:
2044 * afsclient_AFSServerGetDone - finish using a server iterator.
2048 * IN iterationId - an iterator previously returned by
2049 * afsclient_AFSServerGetBegin.
2053 * No locks are obtained or released by this function
2061 * Returns != 0 upon successful completion.
2065 afsclient_AFSServerGetDone(void *iterationId, afs_status_p st)
2068 afs_status_t tst = 0;
2069 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2071 if (iterationId == NULL) {
2072 tst = ADMITERATORNULL;
2073 goto fail_afsclient_AFSServerGetDone;
2076 rc = IteratorDone(iter, &tst);
2078 fail_afsclient_AFSServerGetDone:
2087 * afsclient_RPCStatOpen - open an rx connection to a server to retrieve
2092 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2094 * IN serverName - the host name where the server resides.
2096 * IN type - what type of process to query
2098 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2102 * No locks are obtained or released by this function
2110 * Returns != 0 upon successful completion.
2114 afsclient_RPCStatOpen(const void *cellHandle, const char *serverName,
2115 afs_stat_source_t type,
2116 struct rx_connection **rpcStatHandleP, afs_status_p st)
2119 afs_status_t tst = 0;
2120 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2123 struct rx_securityClass *sc;
2125 if (!CellHandleIsValid(cellHandle, &tst)) {
2126 goto fail_afsclient_RPCStatOpen;
2129 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2130 goto fail_afsclient_RPCStatOpen;
2133 if (rpcStatHandleP == NULL) {
2134 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2135 goto fail_afsclient_RPCStatOpen;
2141 servPort = AFSCONF_NANNYPORT;
2144 case AFS_FILESERVER:
2145 servPort = AFSCONF_FILEPORT;
2149 servPort = AFSCONF_KAUTHPORT;
2153 servPort = AFSCONF_PROTPORT;
2157 servPort = AFSCONF_VOLUMEPORT;
2161 servPort = AFSCONF_VLDBPORT;
2165 servPort = AFSCONF_CALLBACKPORT;
2169 tst = ADMTYPEINVALID;
2170 goto fail_afsclient_RPCStatOpen;
2174 * special processing of tokens by server type
2177 if (type == AFS_KASERVER) {
2178 if (!c_handle->tokens->kas_token_set) {
2179 tst = ADMCLIENTNOKASTOKENS;
2180 goto fail_afsclient_RPCStatOpen;
2182 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2184 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2188 rx_GetCachedConnection(htonl(servAddr), htons(servPort),
2189 RX_STATS_SERVICE_ID, sc,
2190 c_handle->tokens->sc_index);
2192 if (*rpcStatHandleP == NULL) {
2193 tst = ADMCLIENTRPCSTATNOCONNECTION;
2194 goto fail_afsclient_RPCStatOpen;
2198 fail_afsclient_RPCStatOpen:
2207 * afsclient_RPCStatOpenPort - open an rx connection to a server to retrieve
2212 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2214 * IN serverName - the host name where the server resides.
2216 * IN port - the UDP port number where the server resides.
2218 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2222 * No locks are obtained or released by this function
2230 * Returns != 0 upon successful completion.
2234 afsclient_RPCStatOpenPort(const void *cellHandle, const char *serverName,
2235 const int serverPort,
2236 struct rx_connection **rpcStatHandleP,
2240 afs_status_t tst = 0;
2241 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2243 struct rx_securityClass *sc;
2245 if (!CellHandleIsValid(cellHandle, &tst)) {
2246 goto fail_afsclient_RPCStatOpenPort;
2249 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2250 goto fail_afsclient_RPCStatOpenPort;
2253 if (rpcStatHandleP == NULL) {
2254 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2255 goto fail_afsclient_RPCStatOpenPort;
2259 * special processing of tokens by server type
2262 if (serverPort == AFSCONF_KAUTHPORT) {
2263 if (!c_handle->tokens->kas_token_set) {
2264 tst = ADMCLIENTNOKASTOKENS;
2265 goto fail_afsclient_RPCStatOpenPort;
2267 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2269 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2273 rx_GetCachedConnection(htonl(servAddr), htons(serverPort),
2274 RX_STATS_SERVICE_ID, sc,
2275 c_handle->tokens->sc_index);
2277 if (*rpcStatHandleP == NULL) {
2278 tst = ADMCLIENTRPCSTATNOCONNECTION;
2279 goto fail_afsclient_RPCStatOpenPort;
2283 fail_afsclient_RPCStatOpenPort:
2292 * afsclient_RPCStatClose - close a previously opened rx connection.
2296 * IN rpcStatHandle - an rx connection returned by afsclient_RPCStatOpen
2300 * No locks are obtained or released by this function
2308 * Returns != 0 upon successful completion.
2312 afsclient_RPCStatClose(struct rx_connection *rpcStatHandle, afs_status_p st)
2315 afs_status_t tst = 0;
2317 if (rpcStatHandle == NULL) {
2318 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2319 goto fail_afsclient_RPCStatClose;
2322 rx_ReleaseCachedConnection(rpcStatHandle);
2324 fail_afsclient_RPCStatClose:
2333 * afsclient_CMStatOpen - open an rx connection to a server to retrieve
2338 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2340 * IN serverName - the host name where the server resides.
2342 * OUT cmStatHandleP - contains an rx connection to the server of interest
2346 * No locks are obtained or released by this function
2354 * Returns != 0 upon successful completion.
2358 afsclient_CMStatOpen(const void *cellHandle, const char *serverName,
2359 struct rx_connection **cmStatHandleP, afs_status_p st)
2362 afs_status_t tst = 0;
2363 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2365 struct rx_securityClass *sc;
2367 if (!CellHandleIsValid(cellHandle, &tst)) {
2368 goto fail_afsclient_CMStatOpen;
2371 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2372 goto fail_afsclient_CMStatOpen;
2375 if (cmStatHandleP == NULL) {
2376 tst = ADMCLIENTCMSTATHANDLEPNULL;
2377 goto fail_afsclient_CMStatOpen;
2380 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2383 rx_GetCachedConnection(htonl(servAddr), htons(AFSCONF_CALLBACKPORT),
2384 1, sc, c_handle->tokens->sc_index);
2386 if (*cmStatHandleP == NULL) {
2387 tst = ADMCLIENTCMSTATNOCONNECTION;
2388 goto fail_afsclient_CMStatOpen;
2392 fail_afsclient_CMStatOpen:
2401 * afsclient_CMStatOpenPort - open an rx connection to a server to retrieve
2406 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2408 * IN serverName - the host name where the server resides.
2410 * IN port - the UDP port number where the server resides.
2412 * OUT cmStatHandleP - contains an rx connection to the server of interest
2416 * No locks are obtained or released by this function
2424 * Returns != 0 upon successful completion.
2428 afsclient_CMStatOpenPort(const void *cellHandle, const char *serverName,
2429 const int serverPort,
2430 struct rx_connection **cmStatHandleP,
2434 afs_status_t tst = 0;
2435 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2437 struct rx_securityClass *sc;
2439 if (!CellHandleIsValid(cellHandle, &tst)) {
2440 goto fail_afsclient_CMStatOpenPort;
2443 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2444 goto fail_afsclient_CMStatOpenPort;
2447 if (cmStatHandleP == NULL) {
2448 tst = ADMCLIENTCMSTATHANDLEPNULL;
2449 goto fail_afsclient_CMStatOpenPort;
2452 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2455 rx_GetCachedConnection(htonl(servAddr), htons(serverPort), 1, sc,
2456 c_handle->tokens->sc_index);
2458 if (*cmStatHandleP == NULL) {
2459 tst = ADMCLIENTCMSTATNOCONNECTION;
2460 goto fail_afsclient_CMStatOpenPort;
2464 fail_afsclient_CMStatOpenPort:
2473 * afsclient_CMStatClose - close a previously opened rx connection.
2477 * IN cmStatHandle - an rx connection returned by afsclient_CMStatOpen
2481 * No locks are obtained or released by this function
2489 * Returns != 0 upon successful completion.
2493 afsclient_CMStatClose(struct rx_connection *cmStatHandle, afs_status_p st)
2496 afs_status_t tst = 0;
2498 if (cmStatHandle == NULL) {
2499 tst = ADMCLIENTCMSTATHANDLEPNULL;
2500 goto fail_afsclient_CMStatClose;
2503 rx_ReleaseCachedConnection(cmStatHandle);
2505 fail_afsclient_CMStatClose:
2514 * afsclient_RXDebugOpen - open an rxdebug handle to a server.
2518 * IN serverName - the host name where the server resides.
2520 * IN type - what type of process to query
2522 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2526 * No locks are obtained or released by this function
2534 * Returns != 0 upon successful completion.
2538 afsclient_RXDebugOpen(const char *serverName, afs_stat_source_t type,
2539 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2542 afs_status_t tst = 0;
2544 rxdebugHandle_p handle;
2545 rxdebugSocket_t sock;
2546 struct sockaddr_in taddr;
2550 if (rxdebugHandleP == NULL) {
2551 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2552 goto fail_afsclient_RXDebugOpen;
2558 serverPort = AFSCONF_NANNYPORT;
2561 case AFS_FILESERVER:
2562 serverPort = AFSCONF_FILEPORT;
2566 serverPort = AFSCONF_KAUTHPORT;
2570 serverPort = AFSCONF_PROTPORT;
2574 serverPort = AFSCONF_VOLUMEPORT;
2578 serverPort = AFSCONF_VLDBPORT;
2582 serverPort = AFSCONF_CALLBACKPORT;
2586 tst = ADMTYPEINVALID;
2587 goto fail_afsclient_RXDebugOpen;
2590 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2591 goto fail_afsclient_RXDebugOpen;
2594 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2595 if (sock == INVALID_RXDEBUG_SOCKET) {
2597 goto fail_afsclient_RXDebugOpen;
2600 memset(&taddr, 0, sizeof(taddr));
2601 taddr.sin_family = AF_INET;
2603 taddr.sin_addr.s_addr = INADDR_ANY;
2604 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2608 goto fail_afsclient_RXDebugOpen;
2611 handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
2615 goto fail_afsclient_RXDebugOpen;
2618 handle->sock = sock;
2619 handle->ipAddr = serverAddr;
2620 handle->udpPort = serverPort;
2621 handle->firstFlag = 1;
2622 handle->supportedStats = 0;
2623 *rxdebugHandleP = handle;
2626 fail_afsclient_RXDebugOpen:
2635 * afsclient_RXDebugOpenPort - open an rxdebug handle to a server.
2639 * IN serverName - the host name where the server resides.
2641 * IN port - the UDP port number where the server resides.
2643 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2647 * No locks are obtained or released by this function
2655 * Returns != 0 upon successful completion.
2659 afsclient_RXDebugOpenPort(const char *serverName, int serverPort,
2660 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2663 afs_status_t tst = 0;
2665 rxdebugHandle_p handle;
2666 rxdebugSocket_t sock;
2667 struct sockaddr_in taddr;
2670 if (rxdebugHandleP == NULL) {
2671 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2672 goto fail_afsclient_RXDebugOpenPort;
2675 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2676 goto fail_afsclient_RXDebugOpenPort;
2679 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2680 if (sock == INVALID_RXDEBUG_SOCKET) {
2682 goto fail_afsclient_RXDebugOpenPort;
2685 memset(&taddr, 0, sizeof(taddr));
2686 taddr.sin_family = AF_INET;
2688 taddr.sin_addr.s_addr = INADDR_ANY;
2689 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2693 goto fail_afsclient_RXDebugOpenPort;
2696 handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
2700 goto fail_afsclient_RXDebugOpenPort;
2703 handle->sock = sock;
2704 handle->ipAddr = serverAddr;
2705 handle->udpPort = serverPort;
2706 handle->firstFlag = 1;
2707 handle->supportedStats = 0;
2708 *rxdebugHandleP = handle;
2711 fail_afsclient_RXDebugOpenPort:
2720 * afsclient_RXDebugClose - close a previously opened rxdebug handle.
2724 * IN rxdebugHandle - an rxdebug handle returned by afsclient_RXDebugOpen
2728 * No locks are obtained or released by this function
2736 * Returns != 0 upon successful completion.
2740 afsclient_RXDebugClose(rxdebugHandle_p rxdebugHandle, afs_status_p st)
2743 afs_status_t tst = 0;
2745 if (rxdebugHandle == NULL) {
2746 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2747 goto fail_afsclient_RXDebugClose;
2750 close(rxdebugHandle->sock);
2751 free(rxdebugHandle);
2753 fail_afsclient_RXDebugClose: