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;
62 static const unsigned long SERVER_TTL = 10 * 60;
65 * We need a way to track whether or not the client library has been
66 * initialized. We count on the fact that the other library initialization
67 * functions are protected by their own once mechanism. We only track
68 * our own internal status
71 static int client_init;
72 static pthread_once_t client_init_once = PTHREAD_ONCE_INIT;
81 * IsTokenValid - validate a token handle
85 * IN token - the token to be validated.
89 * No locks are obtained or released by this function
97 * Returns != 0 upon successful completion.
101 IsTokenValid(const afs_token_handle_p token, afs_status_p st)
104 afs_status_t tst = 0;
107 tst = ADMCLIENTTOKENHANDLENULL;
108 goto fail_IsTokenValid;
111 if (token->is_valid == 0) {
112 tst = ADMCLIENTTOKENHANDLEINVALID;
113 goto fail_IsTokenValid;
116 if ((token->begin_magic != BEGIN_MAGIC)
117 || (token->end_magic != END_MAGIC)) {
118 tst = ADMCLIENTTOKENHANDLEBADMAGIC;
119 goto fail_IsTokenValid;
132 * afsclient_TokenGetExisting - get tokens that already exist and
133 * are held by the cache manager.
137 * IN cellName - the name of the cell where the token originated.
139 * OUT tokenHandle - a handle to the tokens if they were obtained
144 * No locks are obtained or released by this function
148 * The tokenHandle returned by this function cannot be used for kas
149 * related operations, since kas tokens aren't stored in the kernel.
153 * Returns != 0 upon successful completion.
157 afsclient_TokenGetExisting(const char *cellName, void **tokenHandle,
161 afs_status_t tst = 0;
162 struct ktc_principal afs_server;
163 afs_token_handle_p t_handle =
164 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
166 if (client_init == 0) {
167 tst = ADMCLIENTNOINIT;
168 goto fail_afsclient_TokenGetExisting;
171 if (cellName == NULL) {
172 tst = ADMCLIENTCELLNAMENULL;
173 goto fail_afsclient_TokenGetExisting;
176 if (tokenHandle == NULL) {
177 tst = ADMCLIENTTOKENHANDLENULL;
178 goto fail_afsclient_TokenGetExisting;
181 if (t_handle == NULL) {
183 goto fail_afsclient_TokenGetExisting;
186 strcpy(afs_server.name, "afs");
187 afs_server.instance[0] = 0;
188 strcpy(afs_server.cell, cellName);
192 ktc_GetToken(&afs_server, &t_handle->afs_token,
193 sizeof(t_handle->afs_token), &t_handle->client))) {
195 * The token has been retrieved successfully, initialize
196 * the rest of the token handle structure
198 strncpy(t_handle->cell, cellName, MAXCELLCHARS);
199 t_handle->cell[MAXCELLCHARS - 1] = '\0';
200 t_handle->afs_token_set = 1;
201 t_handle->from_kernel = 1;
202 t_handle->kas_token_set = 0;
203 t_handle->sc_index = 2;
204 t_handle->afs_sc[t_handle->sc_index] =
205 rxkad_NewClientSecurityObject(rxkad_clear,
206 &t_handle->afs_token.sessionKey,
207 t_handle->afs_token.kvno,
208 t_handle->afs_token.ticketLen,
209 t_handle->afs_token.ticket);
210 t_handle->afs_encrypt_sc[t_handle->sc_index] =
211 rxkad_NewClientSecurityObject(rxkad_crypt,
212 &t_handle->afs_token.sessionKey,
213 t_handle->afs_token.kvno,
214 t_handle->afs_token.ticketLen,
215 t_handle->afs_token.ticket);
216 if ((t_handle->afs_sc[t_handle->sc_index] == NULL)
217 || (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
218 tst = ADMCLIENTTOKENHANDLENOSECURITY;
219 goto fail_afsclient_TokenGetExisting;
221 t_handle->begin_magic = BEGIN_MAGIC;
222 t_handle->is_valid = 1;
223 t_handle->end_magic = END_MAGIC;
224 *tokenHandle = (void *)t_handle;
227 goto fail_afsclient_TokenGetExisting;
231 fail_afsclient_TokenGetExisting:
233 if ((rc == 0) && (t_handle != NULL)) {
243 * afsclient_TokenSet - set the tokens represented by tokenHandle to be
244 * active in the kernel (aka ka_SetToken).
248 * IN cellName - the name of the cell where the token originated.
250 * OUT tokenHandle - a handle to the tokens if they were obtained
255 * No locks are obtained or released by this function
259 * The tokenHandle returned by this function cannot be used for kas
260 * related operations, since kas tokens aren't stored in the kernel.
264 * Returns != 0 upon successful completion.
268 afsclient_TokenSet(const void *tokenHandle, afs_status_p st)
271 afs_status_t tst = 0;
272 struct ktc_principal afs_server;
273 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
275 if (!IsTokenValid(t_handle, &tst)) {
276 goto fail_afsclient_TokenSet;
279 strcpy(afs_server.name, "afs");
280 afs_server.instance[0] = 0;
281 strcpy(afs_server.cell, t_handle->cell);
284 ktc_SetToken(&afs_server, &t_handle->afs_token, &t_handle->client, 0);
290 fail_afsclient_TokenSet:
299 * GetKASToken - get a KAS token and store it in the tokenHandle.
303 * IN cellName - the name of the cell where the token should be obtained.
305 * IN principal - the name of the user of the token.
307 * IN password - the password for the principal.
309 * OUT tokenHandle - a handle to the tokens if they were obtained
314 * No locks are obtained or released by this function
322 * Returns != 0 upon successful completion.
326 GetKASToken(const char *cellName, const char *principal, const char *password,
327 afs_token_handle_p tokenHandle, afs_status_p st)
330 afs_status_t tst = 0;
331 struct ubik_client *unauth_conn;
333 struct ktc_encryptionKey key;
334 struct ktc_token *token;
335 unsigned long now = time(0);
336 char name[MAXKTCNAMELEN];
337 char inst[MAXKTCNAMELEN];
338 int have_server_conn = 0;
340 token = &tokenHandle->kas_token;
342 ka_StringToKey((char *)password, (char *)cellName, &key);
345 * Get an unauthenticated connection in the right cell to use for
346 * retrieving the token.
350 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
353 goto fail_GetKASToken;
355 have_server_conn = 1;
357 tst = ka_ParseLoginName((char *)principal, name, inst, NULL);
359 goto fail_GetKASToken;
363 ka_Authenticate(name, inst, (char *)cellName, unauth_conn,
364 KA_MAINTENANCE_SERVICE, &key, now,
365 now + ADMIN_TICKET_LIFETIME, token, &expire);
367 goto fail_GetKASToken;
373 if (have_server_conn) {
374 ubik_ClientDestroy(unauth_conn);
384 * GetAFSToken - get a AFS token and store it in the tokenHandle.
388 * IN cellName - the name of the cell where the token should be obtained.
390 * IN principal - the name of the user of the token.
392 * IN password - the password for the principal.
394 * OUT tokenHandle - a handle to the tokens if they were obtained
399 * No locks are obtained or released by this function
407 * Returns != 0 upon successful completion.
411 GetAFSToken(const char *cellName, const char *principal, const char *password,
412 afs_token_handle_p tokenHandle, afs_status_p st)
415 afs_status_t tst = 0;
416 struct ubik_client *unauth_conn = NULL, *auth_conn = NULL;
418 struct ktc_encryptionKey key;
419 struct ktc_token auth_token;
420 struct ktc_token *token;
421 unsigned long now = time(0);
423 token = &tokenHandle->afs_token;
425 ka_StringToKey((char *)password, (char *)cellName, &key);
428 * Get an unauthenticated connection in the right cell to use for
429 * retrieving the token.
433 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
436 goto fail_GetAFSToken;
440 ka_ParseLoginName((char *)principal, tokenHandle->client.name,
441 tokenHandle->client.instance, NULL);
443 goto fail_GetAFSToken;
447 ka_Authenticate(tokenHandle->client.name,
448 tokenHandle->client.instance, (char *)cellName,
449 unauth_conn, KA_TICKET_GRANTING_SERVICE, &key, now,
450 now + ADMIN_TICKET_LIFETIME, &auth_token, &expire);
452 goto fail_GetAFSToken;
456 ka_AuthServerConn((char *)cellName, KA_TICKET_GRANTING_SERVICE, 0,
459 goto fail_GetAFSToken;
463 ka_CellToRealm((char *)cellName, tokenHandle->client.cell, (int *)0);
465 goto fail_GetAFSToken;
469 ka_GetToken("afs", "", (char *)cellName, tokenHandle->client.name,
470 tokenHandle->client.instance, auth_conn, now,
471 now + ADMIN_TICKET_LIFETIME, &auth_token,
472 tokenHandle->client.cell, token);
474 goto fail_GetAFSToken;
481 ubik_ClientDestroy(auth_conn);
485 ubik_ClientDestroy(unauth_conn);
496 * afsclient_TokenGetNew - get new tokens for a user and store them
497 * in the tokenHandle.
501 * IN cellName - the name of the cell where the tokens should be obtained.
503 * IN principal - the name of the user of the tokens.
505 * IN password - the password for the principal.
507 * OUT tokenHandle - a handle to the tokens if they were obtained
512 * No locks are obtained or released by this function
520 * Returns != 0 upon successful completion.
524 afsclient_TokenGetNew(const char *cellName, const char *principal,
525 const char *password, void **tokenHandle,
529 afs_status_t tst = 0;
530 afs_token_handle_p t_handle =
531 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
533 if (client_init == 0) {
534 tst = ADMCLIENTNOINIT;
535 goto fail_afsclient_TokenGetNew;
538 if (t_handle == NULL) {
540 goto fail_afsclient_TokenGetNew;
544 * Check to see if the principal or password is missing. If it is,
545 * get unauthenticated tokens for the cell
548 if ((principal == NULL) || (*principal == 0) || (password == NULL)
549 || (*password == 0)) {
550 t_handle->from_kernel = 0;
551 t_handle->afs_token_set = 1;
552 t_handle->kas_token_set = 1;
553 t_handle->sc_index = 0;
554 t_handle->afs_sc[t_handle->sc_index] =
555 rxnull_NewClientSecurityObject();
556 t_handle->afs_encrypt_sc[t_handle->sc_index] =
557 rxnull_NewClientSecurityObject();
558 t_handle->kas_sc[t_handle->sc_index] =
559 rxnull_NewClientSecurityObject();
560 t_handle->begin_magic = BEGIN_MAGIC;
561 t_handle->is_valid = 1;
562 t_handle->afs_token.endTime = 0;
563 t_handle->end_magic = END_MAGIC;
564 *tokenHandle = (void *)t_handle;
569 * create an authenticated token
572 if ((GetAFSToken(cellName, principal, password, t_handle, &tst))
573 && (GetKASToken(cellName, principal, password, t_handle, &tst))) {
574 strncpy(t_handle->cell, cellName, MAXCELLCHARS);
575 t_handle->cell[MAXCELLCHARS - 1] = '\0';
576 t_handle->from_kernel = 0;
577 t_handle->afs_token_set = 1;
578 t_handle->kas_token_set = 1;
579 t_handle->sc_index = 2;
580 t_handle->afs_sc[t_handle->sc_index] =
581 rxkad_NewClientSecurityObject(rxkad_clear,
582 &t_handle->afs_token.sessionKey,
583 t_handle->afs_token.kvno,
584 t_handle->afs_token.ticketLen,
585 t_handle->afs_token.ticket);
586 t_handle->afs_encrypt_sc[t_handle->sc_index] =
587 rxkad_NewClientSecurityObject(rxkad_crypt,
588 &t_handle->afs_token.sessionKey,
589 t_handle->afs_token.kvno,
590 t_handle->afs_token.ticketLen,
591 t_handle->afs_token.ticket);
592 t_handle->kas_sc[t_handle->sc_index] =
593 rxkad_NewClientSecurityObject(rxkad_crypt,
594 &t_handle->kas_token.sessionKey,
595 t_handle->kas_token.kvno,
596 t_handle->kas_token.ticketLen,
597 t_handle->kas_token.ticket);
598 if ((t_handle->afs_sc[t_handle->sc_index] != NULL)
599 && (t_handle->afs_encrypt_sc[t_handle->sc_index] != NULL)
600 && (t_handle->kas_sc[t_handle->sc_index] != NULL)) {
601 t_handle->begin_magic = BEGIN_MAGIC;
602 t_handle->is_valid = 1;
603 t_handle->end_magic = END_MAGIC;
604 *tokenHandle = (void *)t_handle;
606 tst = ADMCLIENTTOKENHANDLENOSECURITY;
607 goto fail_afsclient_TokenGetNew;
610 goto fail_afsclient_TokenGetNew;
615 fail_afsclient_TokenGetNew:
617 if ((rc == 0) && (t_handle != NULL)) {
628 * afsclient_TokenQuery - get the expiration time of the tokens.
632 * IN tokenHandle - a previously obtained valid token.
634 * OUT expirationDateP - the time at which the tokens expire.
636 * OUT principal - the owning principal
638 * OUT instance - principal instance if it exists.
640 * OUT cell - the principal's cell
642 * OUT hasKasTokens - set to 1 if the token handle contains kas tokens.
646 * No locks are obtained or released by this function
650 * We only check the AFS tokens since we always get these. The
651 * KAS tokens may expirer later than the AFS tokens, but this
652 * difference is minor and reporting an earlier time won't cause
657 * Returns != 0 upon successful completion.
661 afsclient_TokenQuery(void *tokenHandle, unsigned long *expirationDateP,
662 char *principal, char *instance, char *cell,
663 int *hasKasTokens, afs_status_p st)
666 afs_status_t tst = 0;
667 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
669 if (client_init == 0) {
670 tst = ADMCLIENTNOINIT;
672 goto fail_afsclient_TokenQuery;
675 if (IsTokenValid(t_handle, &tst)) {
676 if (principal != NULL) {
677 strcpy(principal, t_handle->client.name);
679 if (instance != NULL) {
680 strcpy(instance, t_handle->client.instance);
683 strcpy(cell, t_handle->client.cell);
685 if (hasKasTokens != NULL) {
686 *hasKasTokens = t_handle->kas_token_set;
688 if (expirationDateP != NULL) {
689 *expirationDateP = t_handle->afs_token.endTime;
694 fail_afsclient_TokenQuery:
703 * afsclient_TokenClose - close an existing token.
707 * IN token - the token to be closed.
711 * No locks are obtained or released by this function
719 * Returns != 0 upon successful completion.
723 afsclient_TokenClose(const void *tokenHandle, afs_status_p st)
726 afs_status_t tst = 0;
727 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
729 if (client_init == 0) {
730 tst = ADMCLIENTNOINIT;
731 goto fail_afsclient_TokenClose;
734 if (IsTokenValid(t_handle, &tst)) {
735 t_handle->is_valid = 0;
740 fail_afsclient_TokenClose:
748 #define NUM_SERVER_TYPES 3
750 /* must match NUM_SERVER_TYPES */
751 typedef enum { KAS, PTS, VOS } afs_server_list_t;
753 typedef struct afs_server {
756 struct ubik_client **ubik;
757 struct rx_securityClass *sc;
759 } afs_server_t, *afs_server_p;
762 * afsclient_CellOpen - Open a particular cell for work as a particular
767 * IN cellName - the cell where future admin calls will be made.
769 * IN tokenHandle - the tokens work will be done under.
771 * OUT cellHandleP - an opaque pointer that is the first parameter to
772 * almost all subsequent admin api calls.
776 * No locks are obtained or released by this function
784 * Returns != 0 upon successful completion.
788 afsclient_CellOpen(const char *cellName, const void *tokenHandle,
789 void **cellHandleP, afs_status_p st)
792 afs_status_t tst = 0;
793 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
794 afs_cell_handle_p c_handle = (afs_cell_handle_p)
795 calloc(1, sizeof(afs_cell_handle_t));
796 struct afsconf_dir *tdir = NULL;
797 struct afsconf_cell info;
798 struct rx_connection *serverconns[MAXSERVERS];
800 struct rx_securityClass *sc[3];
802 char copyCell[MAXCELLCHARS];
804 afs_server_t servers[NUM_SERVER_TYPES]
805 = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
806 {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
807 {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}
810 if (client_init == 0) {
811 tst = ADMCLIENTNOINIT;
812 goto fail_afsclient_CellOpen;
815 if (c_handle == NULL) {
817 goto fail_afsclient_CellOpen;
820 if (t_handle == NULL) {
821 tst = ADMCLIENTTOKENHANDLENULL;
822 goto fail_afsclient_CellOpen;
825 if ((cellName == NULL) || (*cellName == 0)) {
826 tst = ADMCLIENTCELLNAMENULL;
827 goto fail_afsclient_CellOpen;
830 if (cellHandleP == NULL) {
831 tst = ADMCLIENTCELLHANDLEPNULL;
832 goto fail_afsclient_CellOpen;
836 * Check that the token handle contains valid data and the calloc
839 if (!t_handle->afs_token_set) {
840 tst = ADMCLIENTCELLOPENBADTOKEN;
841 goto fail_afsclient_CellOpen;
845 * Use a table to initialize the cell handle structure, since
846 * most of the steps are the same for all the servers.
848 * Start by creating rx_securityClass objects for each of the
849 * servers. A potential optimization is to do this in
850 * afsclient_TokenGetNew and just keep the expiration time of
852 * Also, initialize the ubik client pointers in the table
854 servers[KAS].sc = t_handle->kas_sc[t_handle->sc_index];
855 servers[PTS].sc = t_handle->afs_sc[t_handle->sc_index];
856 servers[VOS].sc = servers[PTS].sc;
857 servers[KAS].ubik = &c_handle->kas;
858 servers[PTS].ubik = &c_handle->pts;
859 servers[VOS].ubik = &c_handle->vos;
860 servers[KAS].valid = &c_handle->kas_valid;
861 servers[PTS].valid = &c_handle->pts_valid;
862 servers[VOS].valid = &c_handle->vos_valid;
863 c_handle->vos_new = 1;
865 if ((servers[PTS].sc == NULL) || (servers[VOS].sc == NULL)) {
866 tst = ADMCLIENTBADTOKENHANDLE;
867 goto fail_afsclient_CellOpen;
871 * If the initialization has succeeded so far, get the address
872 * information for each server in the cell
875 strncpy(c_handle->working_cell, cellName, MAXCELLCHARS);
876 c_handle->working_cell[MAXCELLCHARS - 1] = '\0';
877 if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
878 tst = ADMCLIENTBADCLIENTCONFIG;
879 goto fail_afsclient_CellOpen;
883 * We must copy the cellName here because afsconf_GetCellInfo
884 * actually writes over the cell name it is passed.
886 strncpy(copyCell, cellName, MAXCELLCHARS);
887 copyCell[MAXCELLCHARS - 1] ='\0';
888 for (i = 0; (i < NUM_SERVER_TYPES); i++) {
891 ka_AuthServerConn((char *)cellName, servers[i].serviceId,
892 ((t_handle->sc_index == 0)
894 kas_token_set)) ? 0 : &t_handle->
895 kas_token, servers[i].ubik);
897 goto fail_afsclient_CellOpen;
900 tst = afsconf_GetCellInfo(tdir, copyCell, servers[i].serv, &info);
902 /* create ubik client handles for each server */
903 scIndex = t_handle->sc_index;
904 sc[scIndex] = servers[i].sc;
905 for (j = 0; (j < info.numServers); j++) {
907 rx_GetCachedConnection(info.hostAddr[j].sin_addr.
909 info.hostAddr[j].sin_port,
910 servers[i].serviceId,
911 sc[scIndex], scIndex);
914 tst = ubik_ClientInit(serverconns, servers[i].ubik);
916 goto fail_afsclient_CellOpen;
919 goto fail_afsclient_CellOpen;
922 /* initialization complete, mark handle valid */
923 *servers[i].valid = 1;
925 c_handle->tokens = t_handle;
928 fail_afsclient_CellOpen:
935 * Upon error, free any obtained resources.
938 if (c_handle != NULL) {
939 if (c_handle->kas_valid)
940 ubik_ClientDestroy(c_handle->kas);
941 if (c_handle->pts_valid)
942 ubik_ClientDestroy(c_handle->pts);
943 if (c_handle->vos_valid)
944 ubik_ClientDestroy(c_handle->vos);
948 c_handle->begin_magic = BEGIN_MAGIC;
949 c_handle->is_valid = 1;
950 c_handle->is_null = 0;
951 c_handle->server_list = NULL;
952 c_handle->server_ttl = 0;
953 c_handle->end_magic = END_MAGIC;
954 *cellHandleP = (void *)c_handle;
964 * afsclient_NullCellOpen - open a null cell handle for access.
968 * OUT cellHandleP - an opaque pointer that is the first parameter to
969 * almost all subsequent admin api calls.
973 * No locks are obtained or released by this function
981 * Returns != 0 upon successful completion.
985 afsclient_NullCellOpen(void **cellHandleP, afs_status_p st)
988 afs_status_t tst = 0;
989 afs_cell_handle_p c_handle = (afs_cell_handle_p)
990 calloc(1, sizeof(afs_cell_handle_t));
994 * Validate parameters
997 if (cellHandleP == NULL) {
998 tst = ADMCLIENTCELLHANDLEPNULL;
999 goto fail_afsclient_NullCellOpen;
1002 if (client_init == 0) {
1003 tst = ADMCLIENTNOINIT;
1004 goto fail_afsclient_NullCellOpen;
1007 if (c_handle == NULL) {
1009 goto fail_afsclient_NullCellOpen;
1013 * Get unauthenticated tokens for any cell
1016 if (!afsclient_TokenGetNew(0, 0, 0, (void *)&c_handle->tokens, &tst)) {
1017 goto fail_afsclient_NullCellOpen;
1020 c_handle->begin_magic = BEGIN_MAGIC;
1021 c_handle->is_valid = 1;
1022 c_handle->is_null = 1;
1023 c_handle->end_magic = END_MAGIC;
1024 c_handle->kas_valid = 0;
1025 c_handle->pts_valid = 0;
1026 c_handle->vos_valid = 0;
1027 c_handle->kas = NULL;
1028 c_handle->pts = NULL;
1029 c_handle->vos = NULL;
1030 c_handle->server_list = NULL;
1031 c_handle->server_ttl = 0;
1032 *cellHandleP = (void *)c_handle;
1035 fail_afsclient_NullCellOpen:
1044 * afsclient_CellClose - close a previously opened cellHandle.
1048 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
1052 * No locks are obtained or released by this function
1060 * Returns != 0 upon successful completion.
1064 afsclient_CellClose(const void *cellHandle, afs_status_p st)
1067 afs_status_t tst = 0;
1068 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1070 if (client_init == 0) {
1071 tst = ADMCLIENTNOINIT;
1072 goto fail_afsclient_CellClose;
1075 if (c_handle == NULL) {
1076 tst = ADMCLIENTCELLHANDLENULL;
1077 goto fail_afsclient_CellClose;
1080 if (c_handle->server_list)
1081 free(c_handle->server_list);
1082 if (c_handle->kas_valid)
1083 ubik_ClientDestroy(c_handle->kas);
1084 if (c_handle->pts_valid)
1085 ubik_ClientDestroy(c_handle->pts);
1086 if (c_handle->vos_valid)
1087 ubik_ClientDestroy(c_handle->vos);
1088 if (c_handle->is_null)
1089 afsclient_TokenClose(c_handle->tokens, 0);
1090 c_handle->kas_valid = 0;
1091 c_handle->pts_valid = 0;
1092 c_handle->vos_valid = 0;
1093 c_handle->is_valid = 0;
1097 fail_afsclient_CellClose:
1107 * afsclient_CellNameGet() -- get a pointer to the cell name in a cell handle
1111 * IN cellHandle - a valid cell handle
1112 * OUT cellNameP - a pointer to the cell name in the cell handle.
1116 * No locks are obtained or released by this function
1120 * If cellHandle is closed then the pointer returned by this function
1121 * is no longer valid.
1125 * Returns != 0 upon successful completion.
1128 afsclient_CellNameGet(const void *cellHandle, const char **cellNameP,
1132 afs_status_t tst = 0;
1133 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1135 if (!CellHandleIsValid(cellHandle, &tst)) {
1136 goto fail_afsclient_CellNameGet;
1139 *cellNameP = c_handle->working_cell;
1142 fail_afsclient_CellNameGet:
1152 * afsclient_LocalCellGet - get the name of the cell the machine
1153 * belongs to where this process is running.
1157 * OUT cellName - an array of characters that must be MAXCELLCHARS
1162 * No locks are obtained or released by this function
1166 * If cellName is smaller than MAXCELLCHARS chars, this function won't
1171 * Returns != 0 upon successful completion.
1175 afsclient_LocalCellGet(char *cellName, afs_status_p st)
1178 afs_status_t tst = 0;
1179 struct afsconf_dir *tdir = NULL;
1181 if (client_init == 0) {
1182 tst = ADMCLIENTNOINIT;
1183 goto fail_afsclient_LocalCellGet;
1186 if (cellName == NULL) {
1187 tst = ADMCLIENTCELLNAMENULL;
1188 goto fail_afsclient_LocalCellGet;
1191 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1194 tst = ADMCLIENTBADCLIENTCONFIG;
1195 goto fail_afsclient_LocalCellGet;
1198 if ((tst = afsconf_GetLocalCell(tdir, cellName, MAXCELLCHARS))) {
1199 goto fail_afsclient_LocalCellGet;
1204 fail_afsclient_LocalCellGet:
1207 afsconf_Close(tdir);
1220 client_ExtractDriveLetter(char *path)
1224 if (path[0] != 0 && path[1] == ':') {
1233 * Determine the parent directory of a give directory
1237 Parent(char *directory, char *parentDirectory)
1242 strcpy(parentDirectory, directory);
1243 tp = strrchr(parentDirectory, '\\');
1245 /* lv trailing slash so Parent("k:\foo") is "k:\" not "k :" */
1249 if (client_ExtractDriveLetter(parentDirectory)) {
1250 strcat(parentDirectory, ".");
1260 * Determine the parent directory of a give directory
1263 Parent(const char *directory, char *parentDirectory)
1268 strcpy(parentDirectory, directory);
1269 tp = strrchr(parentDirectory, '/');
1274 strcpy(parentDirectory, ".");
1283 * afsclient_MountPointCreate - create a mount point for a volume.
1287 * IN cellHandle - a handle to the cell where volumeName resides.
1289 * IN directory - the directory where the mountpoint should be created.
1291 * IN volumeName - the name of the volume to mount.
1293 * IN volType - the type of mount point to create.
1295 * IN volCheck - indicates whether or not to check the VLDB to see if
1296 * volumeName exists.
1300 * No locks are obtained or released by this function
1304 * Returns != 0 upon successful completion.
1307 #define TMP_DATA_SIZE 2048
1310 afsclient_MountPointCreate(const void *cellHandle, const char *directory,
1311 const char *volumeName, vol_type_t volType,
1312 vol_check_t volCheck, afs_status_p st)
1315 afs_status_t tst = 0;
1316 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1317 char parent_dir[TMP_DATA_SIZE];
1318 char space[TMP_DATA_SIZE];
1319 char directoryCell[MAXCELLCHARS];
1320 struct ViceIoctl idata;
1322 vos_vldbEntry_t vldbEntry;
1325 * Validate arguments
1328 if (client_init == 0) {
1329 tst = ADMCLIENTNOINIT;
1330 goto fail_afsclient_MountPointCreate;
1333 if ((directory == NULL) || (*directory == 0)) {
1334 tst = ADMCLIENTDIRECTORYNULL;
1335 goto fail_afsclient_MountPointCreate;
1338 if ((volumeName == NULL) || (*volumeName == 0)) {
1339 tst = ADMCLIENTVOLUMENAME;
1340 goto fail_afsclient_MountPointCreate;
1344 * Extract the parent directory and make sure it is in AFS.
1347 if (!Parent(directory, parent_dir)) {
1348 tst = ADMCLIENTBADDIRECTORY;
1349 goto fail_afsclient_MountPointCreate;
1353 idata.out_size = TMP_DATA_SIZE;
1355 i = pioctl(parent_dir, VIOC_FILE_CELL_NAME, &idata, 1);
1357 if ((errno == EINVAL) || (errno == ENOENT)) {
1358 tst = ADMCLIENTNOAFSDIRECTORY;
1359 goto fail_afsclient_MountPointCreate;
1362 strcpy(directoryCell, space);
1365 * If the user requested, check that the volume exists
1368 if (volCheck == CHECK_VOLUME) {
1369 if (!vos_VLDBGet(cellHandle, 0, 0, volumeName, &vldbEntry, &tst)) {
1370 goto fail_afsclient_MountPointCreate;
1375 * Begin constructing the pioctl buffer
1378 if (volType == READ_WRITE) {
1385 * Append the cell to the mount point if the volume is in a different
1386 * cell than the directory
1389 if (strcmp(c_handle->working_cell, directoryCell)) {
1390 strcat(space, c_handle->working_cell);
1393 strcat(space, volumeName);
1400 idata.in_size = 1 + strlen(space);
1402 if (tst = pioctl(directory, VIOC_AFS_CREATE_MT_PT, &idata, 0)) {
1403 goto fail_afsclient_MountPointCreate;
1406 if ((tst = symlink(space, directory))) {
1407 goto fail_afsclient_MountPointCreate;
1413 fail_afsclient_MountPointCreate:
1421 typedef struct Acl {
1429 afsclient_ACLEntryAdd(const char *directory, const char *user,
1430 const acl_p acl, afs_status_p st)
1433 afs_status_t tst = 0;
1434 struct ViceIoctl idata;
1435 char old_acl_string[2048];
1436 char new_acl_string[2048];
1441 int cur_user_acl = 0;
1446 if (client_init == 0) {
1447 tst = ADMCLIENTNOINIT;
1448 goto fail_afsclient_ACLEntryAdd;
1451 if ((directory == NULL) || (*directory == 0)) {
1452 tst = ADMMISCDIRECTORYNULL;
1453 goto fail_afsclient_ACLEntryAdd;
1456 if ((user == NULL) || (*user == 0)) {
1457 tst = ADMMISCUSERNULL;
1458 goto fail_afsclient_ACLEntryAdd;
1462 tst = ADMMISCACLNULL;
1463 goto fail_afsclient_ACLEntryAdd;
1466 if (acl->read == READ) {
1470 if (acl->write == WRITE) {
1474 if (acl->insert == INSERT) {
1478 if (acl->lookup == LOOKUP) {
1482 if (acl->del == DELETE) {
1486 if (acl->lock == LOCK) {
1490 if (acl->admin == ADMIN) {
1495 * Get the current acl for the directory
1498 idata.out_size = 2048;
1500 idata.in = idata.out = old_acl_string;
1501 tst = pioctl(directory, VIOCGETAL, &idata, 1);
1504 goto fail_afsclient_ACLEntryAdd;
1508 * The acl is presented to us in string format. The format of the
1511 * A header which contains the number of positive and negative entries
1512 * and a string indicating whether or not this is a dfs acl:
1514 * num_pos "\n" dfs_string "\n" num_neg
1516 * An entry for each acl that's of the form:
1520 * There are no blanks in the string between fields, but I use them here
1521 * to make the reading easier.
1523 * Since we are only going to add another entry to the acl, our approach
1524 * is simple. Get the num_pos dfs_string and num_neg from the current acl,
1525 * increment num_pos by one and create a new string. Concatenate the new
1526 * user and rights to the new string, and then concatenate the remaining
1527 * contents of the old acl to the new string.
1529 * Unfortunately, this approach doesn't work since the format the kernel
1530 * hands the acl back to us in, is NOT WHAT IT WANTS BACK!!!!
1531 * So instead we need to parse the entire freaking acl and put a space
1532 * between each user and their acl.
1534 * This is really ugly.
1538 * Parse the first few fields of the acl and see if this is a DFS
1543 sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs,
1545 ptr = strchr(old_acl_string, '\n');
1547 sscanf(ptr, "%d", &cur_acl.nminus);
1548 ptr = strchr(ptr, '\n');
1551 tst = ADMMISCNODFSACL;
1552 goto fail_afsclient_ACLEntryAdd;
1555 * It isn't a DFS file, so create the beginning of the string
1556 * we will hand back to the kernel
1558 sprintf(new_acl_string, "%d\n%d\n%s %d\n", (cur_acl.nplus + 1),
1559 cur_acl.nminus, user, newacl);
1563 * Finish scanning the old acl, parsing each user/acl pair and
1564 * adding a space in the new acl.
1567 for (i = 0; i < (cur_acl.nplus + cur_acl.nminus); i++) {
1568 sscanf(ptr, "%s%d\n", cur_user, &cur_user_acl);
1570 * Skip the entry for the user we are replacing/adding
1573 if (strcmp(cur_user, user)) {
1574 ptr = strchr(ptr, '\n');
1576 sprintf(tmp, "%s %d\n", cur_user, cur_user_acl);
1577 strcat(new_acl_string, tmp);
1581 strcat(new_acl_string, ptr);
1588 idata.in_size = strlen(new_acl_string) + 1;
1589 idata.in = idata.out = new_acl_string;
1590 tst = pioctl(directory, VIOCSETAL, &idata, 1);
1593 goto fail_afsclient_ACLEntryAdd;
1597 fail_afsclient_ACLEntryAdd:
1606 * afsclient_Init - initialize AFS components before use.
1612 * No locks are obtained or released by this function
1620 * Returns != 0 upon successful completion.
1624 afsclient_Init(afs_status_p st)
1627 afs_status_t tst = 0;
1630 pthread_once(&client_init_once, client_once);
1633 if (afs_winsockInit() < 0) {
1634 tst = ADMCLIENTCANTINITWINSOCK;
1635 goto fail_afsclient_Init;
1639 if (!(initAFSDirPath() & AFSDIR_CLIENT_PATHS_OK)) {
1640 tst = ADMCLIENTCANTINITAFSLOCATION;
1641 goto fail_afsclient_Init;
1644 if (rx_Init(0) < 0) {
1645 tst = ADMCLIENTCANTINITRX;
1646 goto fail_afsclient_Init;
1649 if ((tst = ka_CellConfig((char *)AFSDIR_CLIENT_ETC_DIRPATH))) {
1650 goto fail_afsclient_Init;
1655 fail_afsclient_Init:
1664 * afsclient_AFSServerGet - determine what kind of server serverName
1665 * is and fill in serverEntryP accordingly.
1669 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1671 * IN serverName - the hostname of the server of interest.
1673 * OUT serverEntryP - upon successful completion contains a description of
1678 * No locks are obtained or released by this function
1686 * Returns != 0 upon successful completion.
1690 afsclient_AFSServerGet(const void *cellHandle, const char *serverName,
1691 afs_serverEntry_p serverEntryP, afs_status_p st)
1694 afs_status_t tst = 0;
1696 int found_match = 0;
1698 if ((serverName == NULL) || (*serverName == 0)) {
1699 tst = ADMUTILSERVERNAMENULL;
1700 goto fail_afsclient_AFSServerGet;
1703 if (serverEntryP == NULL) {
1704 tst = ADMUTILSERVERENTRYPNULL;
1705 goto fail_afsclient_AFSServerGet;
1709 * Iterate over server entries and try to find a match for serverName
1712 if (!afsclient_AFSServerGetBegin(cellHandle, &iter, &tst)) {
1713 goto fail_afsclient_AFSServerGet;
1716 while (afsclient_AFSServerGetNext(iter, serverEntryP, &tst)) {
1717 if (!strcmp(serverName, serverEntryP->serverName)) {
1724 * If we didn't find a match, the iterator should have terminated
1725 * normally. If it didn't, return the error
1729 if (tst != ADMITERATORDONE) {
1730 afsclient_AFSServerGetDone(iter, 0);
1732 afsclient_AFSServerGetDone(iter, &tst);
1734 tst = ADMCLIENTNOMATCHINGSERVER;
1735 goto fail_afsclient_AFSServerGet;
1737 if (!afsclient_AFSServerGetDone(iter, &tst)) {
1738 goto fail_afsclient_AFSServerGet;
1743 fail_afsclient_AFSServerGet:
1752 * The iterator functions and data for the server retrieval functions
1755 typedef struct server_get {
1758 afs_serverEntry_t server[MAXHOSTSPERCELL + BADSERVERID];
1759 afs_serverEntry_t cache[CACHED_ITEMS];
1760 } server_get_t, *server_get_p;
1763 GetServerRPC(void *rpc_specific, int slot, int *last_item,
1764 int *last_item_contains_data, afs_status_p st)
1767 afs_status_t tst = 0;
1768 server_get_p serv = (server_get_p) rpc_specific;
1770 memcpy(&serv->cache[slot], &serv->server[serv->index],
1771 sizeof(afs_serverEntry_t));
1774 if (serv->index == serv->total) {
1776 *last_item_contains_data = 1;
1787 GetServerFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
1790 afs_status_t tst = 0;
1791 server_get_p serv = (server_get_p) rpc_specific;
1793 memcpy(dest, (const void *)&serv->cache[slot], sizeof(afs_serverEntry_t));
1803 * afsclient_AFSServerGetBegin - start the process of iterating over
1804 * every server in the cell.
1808 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1810 * OUT iterationIdP - - upon successful completion contains an iterator
1811 * that can be passed to afsclient_AFSServerGetNext.
1815 * No locks are obtained or released by this function
1823 * Returns != 0 upon successful completion.
1827 afsclient_AFSServerGetBegin(const void *cellHandle, void **iterationIdP,
1831 afs_status_t tst = 0;
1832 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1833 afs_admin_iterator_p iter =
1834 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1835 server_get_p serv = (server_get_p) calloc(1, sizeof(server_get_t));
1836 server_get_p serv_cache = NULL;
1837 const char *cellName;
1838 void *database_iter;
1839 util_databaseServerEntry_t database_entry;
1840 void *fileserver_iter;
1841 vos_fileServerEntry_t fileserver_entry;
1842 int iserv, iservaddr, ientryaddr, is_dup;
1843 struct hostent *host;
1845 if (!CellHandleIsValid(c_handle, &tst)) {
1846 goto fail_afsclient_AFSServerGetBegin;
1849 if (iterationIdP == NULL) {
1850 tst = ADMITERATIONIDPNULL;
1851 goto fail_afsclient_AFSServerGetBegin;
1854 if ((serv == NULL) || (iter == NULL)) {
1856 goto fail_afsclient_AFSServerGetBegin;
1861 if (c_handle->server_list != NULL && c_handle->server_ttl < time(NULL)) {
1862 serv_cache = c_handle->server_list;
1863 c_handle->server_list = NULL;
1865 UNLOCK_GLOBAL_MUTEX;
1867 if (c_handle->server_list == NULL) {
1868 if (serv_cache == NULL) {
1869 serv_cache = (server_get_p) calloc(1, sizeof(server_get_t));
1871 if (serv_cache == NULL) {
1873 goto fail_afsclient_AFSServerGetBegin;
1878 * Retrieve the list of database servers for this cell.
1881 if (!afsclient_CellNameGet(c_handle, &cellName, &tst)) {
1882 goto fail_afsclient_AFSServerGetBegin;
1885 if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
1886 goto fail_afsclient_AFSServerGetBegin;
1889 while (util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
1890 serv->server[serv->total].serverAddress[0] =
1891 database_entry.serverAddress;
1892 serv->server[serv->total].serverType = DATABASE_SERVER;
1896 if (tst != ADMITERATORDONE) {
1897 util_DatabaseServerGetDone(database_iter, 0);
1898 goto fail_afsclient_AFSServerGetBegin;
1901 if (!util_DatabaseServerGetDone(database_iter, &tst)) {
1902 goto fail_afsclient_AFSServerGetBegin;
1906 * Retrieve the list of file servers for this cell.
1909 if (!vos_FileServerGetBegin(c_handle, 0, &fileserver_iter, &tst)) {
1910 goto fail_afsclient_AFSServerGetBegin;
1913 while (vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
1915 * See if any of the addresses returned in this fileserver_entry
1916 * structure already exist in the list of servers we're building.
1917 * If not, create a new record for this server.
1920 for (iserv = 0; iserv < serv->total; iserv++) {
1921 for (ientryaddr = 0; ientryaddr < fileserver_entry.count; ientryaddr++) {
1922 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS; iservaddr++) {
1923 if (serv->server[iserv].serverAddress[iservaddr] ==
1924 fileserver_entry.serverAddress[ientryaddr]) {
1939 serv->server[iserv].serverType |= FILE_SERVER;
1941 iserv = serv->total++;
1942 serv->server[iserv].serverType = FILE_SERVER;
1946 * Add the addresses from the vldb list to the serv->server[iserv]
1947 * record. Remember that VLDB's list-of-addrs is not guaranteed
1948 * to be unique in a particular entry, or to return only one entry
1949 * per machine--so when we add addresses, always check for
1950 * duplicate entries.
1953 for (ientryaddr = 0; ientryaddr < fileserver_entry.count; ientryaddr++) {
1954 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS; iservaddr++) {
1955 if (serv->server[iserv].serverAddress[iservaddr] ==
1956 fileserver_entry.serverAddress[ientryaddr]) {
1960 if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
1961 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1963 if (!serv->server[iserv].serverAddress[iservaddr]) {
1964 serv->server[iserv].serverAddress[iservaddr] =
1965 fileserver_entry.serverAddress[ientryaddr];
1973 if (tst != ADMITERATORDONE) {
1974 vos_FileServerGetDone(fileserver_iter, 0);
1975 goto fail_afsclient_AFSServerGetBegin;
1978 if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
1979 goto fail_afsclient_AFSServerGetBegin;
1983 * Iterate over the list and fill in the hostname of each of the servers
1986 for (iserv = 0; iserv < serv->total; iserv++) {
1987 int addr = htonl(serv->server[iserv].serverAddress[0]);
1989 host = gethostbyaddr((const char *)&addr, sizeof(int), AF_INET);
1991 strncpy(serv->server[iserv].serverName, host->h_name,
1992 AFS_MAX_SERVER_NAME_LEN);
1993 serv->server[iserv].serverName[AFS_MAX_SERVER_NAME_LEN - 1] = '\0';
1995 UNLOCK_GLOBAL_MUTEX;
1998 memcpy(serv_cache, serv, sizeof(server_get_t));
2002 if (c_handle->server_list == NULL)
2005 memcpy(serv, c_handle->server_list, sizeof(server_get_t));
2006 UNLOCK_GLOBAL_MUTEX;
2012 (iter, (void *)serv, GetServerRPC, GetServerFromCache, NULL, NULL,
2014 *iterationIdP = (void *)iter;
2018 fail_afsclient_AFSServerGetBegin:
2025 if (serv_cache != NULL)
2030 /* in case there was a race and we constructed the list twice */
2031 if (c_handle->server_list)
2032 free(c_handle->server_list);
2034 c_handle->server_list = serv_cache;
2035 c_handle->server_ttl = time(NULL) + SERVER_TTL;
2036 UNLOCK_GLOBAL_MUTEX;
2047 * afsclient_AFSServerGetNext - retrieve the next server in the cell.
2051 * IN iterationId - an iterator previously returned by
2052 * afsclient_AFSServerGetBegin.
2054 * OUT serverEntryP - upon successful completion contains the next server.
2058 * No locks are obtained or released by this function
2066 * Returns != 0 upon successful completion.
2070 afsclient_AFSServerGetNext(void *iterationId, afs_serverEntry_p serverEntryP,
2074 afs_status_t tst = 0;
2075 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2077 if (iterationId == NULL) {
2078 tst = ADMITERATORNULL;
2079 goto fail_afsclient_AFSServerGetNext;
2082 if (serverEntryP == NULL) {
2083 tst = ADMUTILSERVERENTRYPNULL;
2084 goto fail_afsclient_AFSServerGetNext;
2087 rc = IteratorNext(iter, (void *)serverEntryP, &tst);
2089 fail_afsclient_AFSServerGetNext:
2098 * afsclient_AFSServerGetDone - finish using a server iterator.
2102 * IN iterationId - an iterator previously returned by
2103 * afsclient_AFSServerGetBegin.
2107 * No locks are obtained or released by this function
2115 * Returns != 0 upon successful completion.
2119 afsclient_AFSServerGetDone(void *iterationId, afs_status_p st)
2122 afs_status_t tst = 0;
2123 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2125 if (iterationId == NULL) {
2126 tst = ADMITERATORNULL;
2127 goto fail_afsclient_AFSServerGetDone;
2130 rc = IteratorDone(iter, &tst);
2132 fail_afsclient_AFSServerGetDone:
2141 * afsclient_RPCStatOpen - open an rx connection to a server to retrieve
2146 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2148 * IN serverName - the host name where the server resides.
2150 * IN type - what type of process to query
2152 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2156 * No locks are obtained or released by this function
2164 * Returns != 0 upon successful completion.
2168 afsclient_RPCStatOpen(const void *cellHandle, const char *serverName,
2169 afs_stat_source_t type,
2170 struct rx_connection **rpcStatHandleP, afs_status_p st)
2173 afs_status_t tst = 0;
2174 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2177 struct rx_securityClass *sc;
2179 if (!CellHandleIsValid(cellHandle, &tst)) {
2180 goto fail_afsclient_RPCStatOpen;
2183 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2184 goto fail_afsclient_RPCStatOpen;
2187 if (rpcStatHandleP == NULL) {
2188 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2189 goto fail_afsclient_RPCStatOpen;
2195 servPort = AFSCONF_NANNYPORT;
2198 case AFS_FILESERVER:
2199 servPort = AFSCONF_FILEPORT;
2203 servPort = AFSCONF_KAUTHPORT;
2207 servPort = AFSCONF_PROTPORT;
2211 servPort = AFSCONF_VOLUMEPORT;
2215 servPort = AFSCONF_VLDBPORT;
2219 servPort = AFSCONF_CALLBACKPORT;
2223 tst = ADMTYPEINVALID;
2224 goto fail_afsclient_RPCStatOpen;
2228 * special processing of tokens by server type
2231 if (type == AFS_KASERVER) {
2232 if (!c_handle->tokens->kas_token_set) {
2233 tst = ADMCLIENTNOKASTOKENS;
2234 goto fail_afsclient_RPCStatOpen;
2236 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2238 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2242 rx_GetCachedConnection(htonl(servAddr), htons(servPort),
2243 RX_STATS_SERVICE_ID, sc,
2244 c_handle->tokens->sc_index);
2246 if (*rpcStatHandleP == NULL) {
2247 tst = ADMCLIENTRPCSTATNOCONNECTION;
2248 goto fail_afsclient_RPCStatOpen;
2252 fail_afsclient_RPCStatOpen:
2261 * afsclient_RPCStatOpenPort - open an rx connection to a server to retrieve
2266 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2268 * IN serverName - the host name where the server resides.
2270 * IN port - the UDP port number where the server resides.
2272 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2276 * No locks are obtained or released by this function
2284 * Returns != 0 upon successful completion.
2288 afsclient_RPCStatOpenPort(const void *cellHandle, const char *serverName,
2289 const int serverPort,
2290 struct rx_connection **rpcStatHandleP,
2294 afs_status_t tst = 0;
2295 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2297 struct rx_securityClass *sc;
2299 if (!CellHandleIsValid(cellHandle, &tst)) {
2300 goto fail_afsclient_RPCStatOpenPort;
2303 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2304 goto fail_afsclient_RPCStatOpenPort;
2307 if (rpcStatHandleP == NULL) {
2308 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2309 goto fail_afsclient_RPCStatOpenPort;
2313 * special processing of tokens by server type
2316 if (serverPort == AFSCONF_KAUTHPORT) {
2317 if (!c_handle->tokens->kas_token_set) {
2318 tst = ADMCLIENTNOKASTOKENS;
2319 goto fail_afsclient_RPCStatOpenPort;
2321 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2323 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2327 rx_GetCachedConnection(htonl(servAddr), htons(serverPort),
2328 RX_STATS_SERVICE_ID, sc,
2329 c_handle->tokens->sc_index);
2331 if (*rpcStatHandleP == NULL) {
2332 tst = ADMCLIENTRPCSTATNOCONNECTION;
2333 goto fail_afsclient_RPCStatOpenPort;
2337 fail_afsclient_RPCStatOpenPort:
2346 * afsclient_RPCStatClose - close a previously opened rx connection.
2350 * IN rpcStatHandle - an rx connection returned by afsclient_RPCStatOpen
2354 * No locks are obtained or released by this function
2362 * Returns != 0 upon successful completion.
2366 afsclient_RPCStatClose(struct rx_connection *rpcStatHandle, afs_status_p st)
2369 afs_status_t tst = 0;
2371 if (rpcStatHandle == NULL) {
2372 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2373 goto fail_afsclient_RPCStatClose;
2376 rx_ReleaseCachedConnection(rpcStatHandle);
2378 fail_afsclient_RPCStatClose:
2387 * afsclient_CMStatOpen - open an rx connection to a server to retrieve
2392 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2394 * IN serverName - the host name where the server resides.
2396 * OUT cmStatHandleP - contains an rx connection to the server of interest
2400 * No locks are obtained or released by this function
2408 * Returns != 0 upon successful completion.
2412 afsclient_CMStatOpen(const void *cellHandle, const char *serverName,
2413 struct rx_connection **cmStatHandleP, afs_status_p st)
2416 afs_status_t tst = 0;
2417 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2419 struct rx_securityClass *sc;
2421 if (!CellHandleIsValid(cellHandle, &tst)) {
2422 goto fail_afsclient_CMStatOpen;
2425 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2426 goto fail_afsclient_CMStatOpen;
2429 if (cmStatHandleP == NULL) {
2430 tst = ADMCLIENTCMSTATHANDLEPNULL;
2431 goto fail_afsclient_CMStatOpen;
2434 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2437 rx_GetCachedConnection(htonl(servAddr), htons(AFSCONF_CALLBACKPORT),
2438 1, sc, c_handle->tokens->sc_index);
2440 if (*cmStatHandleP == NULL) {
2441 tst = ADMCLIENTCMSTATNOCONNECTION;
2442 goto fail_afsclient_CMStatOpen;
2446 fail_afsclient_CMStatOpen:
2455 * afsclient_CMStatOpenPort - open an rx connection to a server to retrieve
2460 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2462 * IN serverName - the host name where the server resides.
2464 * IN port - the UDP port number where the server resides.
2466 * OUT cmStatHandleP - contains an rx connection to the server of interest
2470 * No locks are obtained or released by this function
2478 * Returns != 0 upon successful completion.
2482 afsclient_CMStatOpenPort(const void *cellHandle, const char *serverName,
2483 const int serverPort,
2484 struct rx_connection **cmStatHandleP,
2488 afs_status_t tst = 0;
2489 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2491 struct rx_securityClass *sc;
2493 if (!CellHandleIsValid(cellHandle, &tst)) {
2494 goto fail_afsclient_CMStatOpenPort;
2497 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2498 goto fail_afsclient_CMStatOpenPort;
2501 if (cmStatHandleP == NULL) {
2502 tst = ADMCLIENTCMSTATHANDLEPNULL;
2503 goto fail_afsclient_CMStatOpenPort;
2506 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2509 rx_GetCachedConnection(htonl(servAddr), htons(serverPort), 1, sc,
2510 c_handle->tokens->sc_index);
2512 if (*cmStatHandleP == NULL) {
2513 tst = ADMCLIENTCMSTATNOCONNECTION;
2514 goto fail_afsclient_CMStatOpenPort;
2518 fail_afsclient_CMStatOpenPort:
2527 * afsclient_CMStatClose - close a previously opened rx connection.
2531 * IN cmStatHandle - an rx connection returned by afsclient_CMStatOpen
2535 * No locks are obtained or released by this function
2543 * Returns != 0 upon successful completion.
2547 afsclient_CMStatClose(struct rx_connection *cmStatHandle, afs_status_p st)
2550 afs_status_t tst = 0;
2552 if (cmStatHandle == NULL) {
2553 tst = ADMCLIENTCMSTATHANDLEPNULL;
2554 goto fail_afsclient_CMStatClose;
2557 rx_ReleaseCachedConnection(cmStatHandle);
2559 fail_afsclient_CMStatClose:
2568 * afsclient_RXDebugOpen - open an rxdebug handle to a server.
2572 * IN serverName - the host name where the server resides.
2574 * IN type - what type of process to query
2576 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2580 * No locks are obtained or released by this function
2588 * Returns != 0 upon successful completion.
2592 afsclient_RXDebugOpen(const char *serverName, afs_stat_source_t type,
2593 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2596 afs_status_t tst = 0;
2598 rxdebugHandle_p handle;
2599 rxdebugSocket_t sock;
2600 struct sockaddr_in taddr;
2604 if (rxdebugHandleP == NULL) {
2605 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2606 goto fail_afsclient_RXDebugOpen;
2612 serverPort = AFSCONF_NANNYPORT;
2615 case AFS_FILESERVER:
2616 serverPort = AFSCONF_FILEPORT;
2620 serverPort = AFSCONF_KAUTHPORT;
2624 serverPort = AFSCONF_PROTPORT;
2628 serverPort = AFSCONF_VOLUMEPORT;
2632 serverPort = AFSCONF_VLDBPORT;
2636 serverPort = AFSCONF_CALLBACKPORT;
2640 tst = ADMTYPEINVALID;
2641 goto fail_afsclient_RXDebugOpen;
2644 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2645 goto fail_afsclient_RXDebugOpen;
2648 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2649 if (sock == INVALID_RXDEBUG_SOCKET) {
2651 goto fail_afsclient_RXDebugOpen;
2654 memset(&taddr, 0, sizeof(taddr));
2655 taddr.sin_family = AF_INET;
2657 taddr.sin_addr.s_addr = INADDR_ANY;
2658 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2662 goto fail_afsclient_RXDebugOpen;
2665 handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
2669 goto fail_afsclient_RXDebugOpen;
2672 handle->sock = sock;
2673 handle->ipAddr = serverAddr;
2674 handle->udpPort = serverPort;
2675 handle->firstFlag = 1;
2676 handle->supportedStats = 0;
2677 *rxdebugHandleP = handle;
2680 fail_afsclient_RXDebugOpen:
2689 * afsclient_RXDebugOpenPort - open an rxdebug handle to a server.
2693 * IN serverName - the host name where the server resides.
2695 * IN port - the UDP port number where the server resides.
2697 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2701 * No locks are obtained or released by this function
2709 * Returns != 0 upon successful completion.
2713 afsclient_RXDebugOpenPort(const char *serverName, int serverPort,
2714 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2717 afs_status_t tst = 0;
2719 rxdebugHandle_p handle;
2720 rxdebugSocket_t sock;
2721 struct sockaddr_in taddr;
2724 if (rxdebugHandleP == NULL) {
2725 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2726 goto fail_afsclient_RXDebugOpenPort;
2729 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2730 goto fail_afsclient_RXDebugOpenPort;
2733 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2734 if (sock == INVALID_RXDEBUG_SOCKET) {
2736 goto fail_afsclient_RXDebugOpenPort;
2739 memset(&taddr, 0, sizeof(taddr));
2740 taddr.sin_family = AF_INET;
2742 taddr.sin_addr.s_addr = INADDR_ANY;
2743 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2747 goto fail_afsclient_RXDebugOpenPort;
2750 handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
2754 goto fail_afsclient_RXDebugOpenPort;
2757 handle->sock = sock;
2758 handle->ipAddr = serverAddr;
2759 handle->udpPort = serverPort;
2760 handle->firstFlag = 1;
2761 handle->supportedStats = 0;
2762 *rxdebugHandleP = handle;
2765 fail_afsclient_RXDebugOpenPort:
2774 * afsclient_RXDebugClose - close a previously opened rxdebug handle.
2778 * IN rxdebugHandle - an rxdebug handle returned by afsclient_RXDebugOpen
2782 * No locks are obtained or released by this function
2790 * Returns != 0 upon successful completion.
2794 afsclient_RXDebugClose(rxdebugHandle_p rxdebugHandle, afs_status_p st)
2797 afs_status_t tst = 0;
2799 if (rxdebugHandle == NULL) {
2800 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2801 goto fail_afsclient_RXDebugClose;
2804 close(rxdebugHandle->sock);
2805 free(rxdebugHandle);
2807 fail_afsclient_RXDebugClose: