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 strncpy(t_handle->cell, cellName, MAXCELLCHARS);
197 t_handle->cell[MAXCELLCHARS - 1] = '\0';
198 t_handle->afs_token_set = 1;
199 t_handle->from_kernel = 1;
200 t_handle->kas_token_set = 0;
201 t_handle->sc_index = 2;
202 t_handle->afs_sc[t_handle->sc_index] =
203 rxkad_NewClientSecurityObject(rxkad_clear,
204 &t_handle->afs_token.sessionKey,
205 t_handle->afs_token.kvno,
206 t_handle->afs_token.ticketLen,
207 t_handle->afs_token.ticket);
208 t_handle->afs_encrypt_sc[t_handle->sc_index] =
209 rxkad_NewClientSecurityObject(rxkad_crypt,
210 &t_handle->afs_token.sessionKey,
211 t_handle->afs_token.kvno,
212 t_handle->afs_token.ticketLen,
213 t_handle->afs_token.ticket);
214 if ((t_handle->afs_sc[t_handle->sc_index] == NULL)
215 || (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
216 tst = ADMCLIENTTOKENHANDLENOSECURITY;
217 goto fail_afsclient_TokenGetExisting;
219 t_handle->begin_magic = BEGIN_MAGIC;
220 t_handle->is_valid = 1;
221 t_handle->end_magic = END_MAGIC;
222 *tokenHandle = (void *)t_handle;
225 goto fail_afsclient_TokenGetExisting;
229 fail_afsclient_TokenGetExisting:
231 if ((rc == 0) && (t_handle != NULL)) {
241 * afsclient_TokenSet - set the tokens represented by tokenHandle to be
242 * active in the kernel (aka ka_SetToken).
246 * IN cellName - the name of the cell where the token originated.
248 * OUT tokenHandle - a handle to the tokens if they were obtained
253 * No locks are obtained or released by this function
257 * The tokenHandle returned by this function cannot be used for kas
258 * related operations, since kas tokens aren't stored in the kernel.
262 * Returns != 0 upon successful completion.
266 afsclient_TokenSet(const void *tokenHandle, afs_status_p st)
269 afs_status_t tst = 0;
270 struct ktc_principal afs_server;
271 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
273 if (!IsTokenValid(t_handle, &tst)) {
274 goto fail_afsclient_TokenSet;
277 strcpy(afs_server.name, "afs");
278 afs_server.instance[0] = 0;
279 strcpy(afs_server.cell, t_handle->cell);
282 ktc_SetToken(&afs_server, &t_handle->afs_token, &t_handle->client, 0);
288 fail_afsclient_TokenSet:
297 * GetKASToken - get a KAS token and store it in the tokenHandle.
301 * IN cellName - the name of the cell where the token should be obtained.
303 * IN principal - the name of the user of the token.
305 * IN password - the password for the principal.
307 * OUT tokenHandle - a handle to the tokens if they were obtained
312 * No locks are obtained or released by this function
320 * Returns != 0 upon successful completion.
324 GetKASToken(const char *cellName, const char *principal, const char *password,
325 afs_token_handle_p tokenHandle, afs_status_p st)
328 afs_status_t tst = 0;
329 struct ubik_client *unauth_conn;
331 struct ktc_encryptionKey key;
332 struct ktc_token *token;
333 unsigned long now = time(0);
334 char name[MAXKTCNAMELEN];
335 char inst[MAXKTCNAMELEN];
336 int have_server_conn = 0;
338 token = &tokenHandle->kas_token;
340 ka_StringToKey((char *)password, (char *)cellName, &key);
343 * Get an unauthenticated connection in the right cell to use for
344 * retrieving the token.
348 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
351 goto fail_GetKASToken;
353 have_server_conn = 1;
355 tst = ka_ParseLoginName((char *)principal, name, inst, NULL);
357 goto fail_GetKASToken;
361 ka_Authenticate(name, inst, (char *)cellName, unauth_conn,
362 KA_MAINTENANCE_SERVICE, &key, now,
363 now + ADMIN_TICKET_LIFETIME, token, &expire);
365 goto fail_GetKASToken;
371 if (have_server_conn) {
372 ubik_ClientDestroy(unauth_conn);
382 * GetAFSToken - get a AFS token and store it in the tokenHandle.
386 * IN cellName - the name of the cell where the token should be obtained.
388 * IN principal - the name of the user of the token.
390 * IN password - the password for the principal.
392 * OUT tokenHandle - a handle to the tokens if they were obtained
397 * No locks are obtained or released by this function
405 * Returns != 0 upon successful completion.
409 GetAFSToken(const char *cellName, const char *principal, const char *password,
410 afs_token_handle_p tokenHandle, afs_status_p st)
413 afs_status_t tst = 0;
414 struct ubik_client *unauth_conn = NULL, *auth_conn = NULL;
416 struct ktc_encryptionKey key;
417 struct ktc_token auth_token;
418 struct ktc_token *token;
419 unsigned long now = time(0);
421 token = &tokenHandle->afs_token;
423 ka_StringToKey((char *)password, (char *)cellName, &key);
426 * Get an unauthenticated connection in the right cell to use for
427 * retrieving the token.
431 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
434 goto fail_GetAFSToken;
438 ka_ParseLoginName((char *)principal, tokenHandle->client.name,
439 tokenHandle->client.instance, NULL);
441 goto fail_GetAFSToken;
445 ka_Authenticate(tokenHandle->client.name,
446 tokenHandle->client.instance, (char *)cellName,
447 unauth_conn, KA_TICKET_GRANTING_SERVICE, &key, now,
448 now + ADMIN_TICKET_LIFETIME, &auth_token, &expire);
450 goto fail_GetAFSToken;
454 ka_AuthServerConn((char *)cellName, KA_TICKET_GRANTING_SERVICE, 0,
457 goto fail_GetAFSToken;
461 ka_CellToRealm((char *)cellName, tokenHandle->client.cell, (int *)0);
463 goto fail_GetAFSToken;
467 ka_GetToken("afs", "", (char *)cellName, tokenHandle->client.name,
468 tokenHandle->client.instance, auth_conn, now,
469 now + ADMIN_TICKET_LIFETIME, &auth_token,
470 tokenHandle->client.cell, token);
472 goto fail_GetAFSToken;
479 ubik_ClientDestroy(auth_conn);
483 ubik_ClientDestroy(unauth_conn);
494 * afsclient_TokenGetNew - get new tokens for a user and store them
495 * in the tokenHandle.
499 * IN cellName - the name of the cell where the tokens should be obtained.
501 * IN principal - the name of the user of the tokens.
503 * IN password - the password for the principal.
505 * OUT tokenHandle - a handle to the tokens if they were obtained
510 * No locks are obtained or released by this function
518 * Returns != 0 upon successful completion.
522 afsclient_TokenGetNew(const char *cellName, const char *principal,
523 const char *password, void **tokenHandle,
527 afs_status_t tst = 0;
528 afs_token_handle_p t_handle =
529 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
531 if (client_init == 0) {
532 tst = ADMCLIENTNOINIT;
533 goto fail_afsclient_TokenGetNew;
536 if (t_handle == NULL) {
538 goto fail_afsclient_TokenGetNew;
542 * Check to see if the principal or password is missing. If it is,
543 * get unauthenticated tokens for the cell
546 if ((principal == NULL) || (*principal == 0) || (password == NULL)
547 || (*password == 0)) {
548 t_handle->from_kernel = 0;
549 t_handle->afs_token_set = 1;
550 t_handle->kas_token_set = 1;
551 t_handle->sc_index = 0;
552 t_handle->afs_sc[t_handle->sc_index] =
553 rxnull_NewClientSecurityObject();
554 t_handle->afs_encrypt_sc[t_handle->sc_index] =
555 rxnull_NewClientSecurityObject();
556 t_handle->kas_sc[t_handle->sc_index] =
557 rxnull_NewClientSecurityObject();
558 t_handle->begin_magic = BEGIN_MAGIC;
559 t_handle->is_valid = 1;
560 t_handle->afs_token.endTime = 0;
561 t_handle->end_magic = END_MAGIC;
562 *tokenHandle = (void *)t_handle;
567 * create an authenticated token
570 if ((GetAFSToken(cellName, principal, password, t_handle, &tst))
571 && (GetKASToken(cellName, principal, password, t_handle, &tst))) {
572 strncpy(t_handle->cell, cellName, MAXCELLCHARS);
573 t_handle->cell[MAXCELLCHARS - 1] = '\0';
574 t_handle->from_kernel = 0;
575 t_handle->afs_token_set = 1;
576 t_handle->kas_token_set = 1;
577 t_handle->sc_index = 2;
578 t_handle->afs_sc[t_handle->sc_index] =
579 rxkad_NewClientSecurityObject(rxkad_clear,
580 &t_handle->afs_token.sessionKey,
581 t_handle->afs_token.kvno,
582 t_handle->afs_token.ticketLen,
583 t_handle->afs_token.ticket);
584 t_handle->afs_encrypt_sc[t_handle->sc_index] =
585 rxkad_NewClientSecurityObject(rxkad_crypt,
586 &t_handle->afs_token.sessionKey,
587 t_handle->afs_token.kvno,
588 t_handle->afs_token.ticketLen,
589 t_handle->afs_token.ticket);
590 t_handle->kas_sc[t_handle->sc_index] =
591 rxkad_NewClientSecurityObject(rxkad_crypt,
592 &t_handle->kas_token.sessionKey,
593 t_handle->kas_token.kvno,
594 t_handle->kas_token.ticketLen,
595 t_handle->kas_token.ticket);
596 if ((t_handle->afs_sc[t_handle->sc_index] != NULL)
597 && (t_handle->afs_encrypt_sc[t_handle->sc_index] != NULL)
598 && (t_handle->kas_sc[t_handle->sc_index] != NULL)) {
599 t_handle->begin_magic = BEGIN_MAGIC;
600 t_handle->is_valid = 1;
601 t_handle->end_magic = END_MAGIC;
602 *tokenHandle = (void *)t_handle;
604 tst = ADMCLIENTTOKENHANDLENOSECURITY;
605 goto fail_afsclient_TokenGetNew;
608 goto fail_afsclient_TokenGetNew;
613 fail_afsclient_TokenGetNew:
615 if ((rc == 0) && (t_handle != NULL)) {
626 * afsclient_TokenQuery - get the expiration time of the tokens.
630 * IN tokenHandle - a previously obtained valid token.
632 * OUT expirationDateP - the time at which the tokens expire.
634 * OUT principal - the owning principal
636 * OUT instance - principal instance if it exists.
638 * OUT cell - the principal's cell
640 * OUT hasKasTokens - set to 1 if the token handle contains kas tokens.
644 * No locks are obtained or released by this function
648 * We only check the AFS tokens since we always get these. The
649 * KAS tokens may expirer later than the AFS tokens, but this
650 * difference is minor and reporting an earlier time won't cause
655 * Returns != 0 upon successful completion.
659 afsclient_TokenQuery(void *tokenHandle, unsigned long *expirationDateP,
660 char *principal, char *instance, char *cell,
661 int *hasKasTokens, afs_status_p st)
664 afs_status_t tst = 0;
665 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
667 if (client_init == 0) {
668 tst = ADMCLIENTNOINIT;
670 goto fail_afsclient_TokenQuery;
673 if (IsTokenValid(t_handle, &tst)) {
674 if (principal != NULL) {
675 strcpy(principal, t_handle->client.name);
677 if (instance != NULL) {
678 strcpy(instance, t_handle->client.instance);
681 strcpy(cell, t_handle->client.cell);
683 if (hasKasTokens != NULL) {
684 *hasKasTokens = t_handle->kas_token_set;
686 if (expirationDateP != NULL) {
687 *expirationDateP = t_handle->afs_token.endTime;
692 fail_afsclient_TokenQuery:
701 * afsclient_TokenClose - close an existing token.
705 * IN token - the token to be closed.
709 * No locks are obtained or released by this function
717 * Returns != 0 upon successful completion.
721 afsclient_TokenClose(const void *tokenHandle, afs_status_p st)
724 afs_status_t tst = 0;
725 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
727 if (client_init == 0) {
728 tst = ADMCLIENTNOINIT;
729 goto fail_afsclient_TokenClose;
732 if (IsTokenValid(t_handle, &tst)) {
733 t_handle->is_valid = 0;
738 fail_afsclient_TokenClose:
746 #define NUM_SERVER_TYPES 3
748 /* must match NUM_SERVER_TYPES */
749 typedef enum { KAS, PTS, VOS } afs_server_list_t;
751 typedef struct afs_server {
754 struct ubik_client **ubik;
755 struct rx_securityClass *sc;
757 } afs_server_t, *afs_server_p;
760 * afsclient_CellOpen - Open a particular cell for work as a particular
765 * IN cellName - the cell where future admin calls will be made.
767 * IN tokenHandle - the tokens work will be done under.
769 * OUT cellHandleP - an opaque pointer that is the first parameter to
770 * almost all subsequent admin api calls.
774 * No locks are obtained or released by this function
782 * Returns != 0 upon successful completion.
786 afsclient_CellOpen(const char *cellName, const void *tokenHandle,
787 void **cellHandleP, afs_status_p st)
790 afs_status_t tst = 0;
791 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
792 afs_cell_handle_p c_handle = (afs_cell_handle_p)
793 calloc(1, sizeof(afs_cell_handle_t));
794 struct afsconf_dir *tdir = NULL;
795 struct afsconf_cell info;
796 struct rx_connection *serverconns[MAXSERVERS];
798 struct rx_securityClass *sc[3];
800 char copyCell[MAXCELLCHARS];
802 afs_server_t servers[NUM_SERVER_TYPES]
803 = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
804 {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
805 {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}
808 if (client_init == 0) {
809 tst = ADMCLIENTNOINIT;
810 goto fail_afsclient_CellOpen;
813 if (c_handle == NULL) {
815 goto fail_afsclient_CellOpen;
818 if (t_handle == NULL) {
819 tst = ADMCLIENTTOKENHANDLENULL;
820 goto fail_afsclient_CellOpen;
823 if ((cellName == NULL) || (*cellName == 0)) {
824 tst = ADMCLIENTCELLNAMENULL;
825 goto fail_afsclient_CellOpen;
828 if (cellHandleP == NULL) {
829 tst = ADMCLIENTCELLHANDLEPNULL;
830 goto fail_afsclient_CellOpen;
834 * Check that the token handle contains valid data and the calloc
837 if (!t_handle->afs_token_set) {
838 tst = ADMCLIENTCELLOPENBADTOKEN;
839 goto fail_afsclient_CellOpen;
843 * Use a table to initialize the cell handle structure, since
844 * most of the steps are the same for all the servers.
846 * Start by creating rx_securityClass objects for each of the
847 * servers. A potential optimization is to do this in
848 * afsclient_TokenGetNew and just keep the expiration time of
850 * Also, initialize the ubik client pointers in the table
852 servers[KAS].sc = t_handle->kas_sc[t_handle->sc_index];
853 servers[PTS].sc = t_handle->afs_sc[t_handle->sc_index];
854 servers[VOS].sc = servers[PTS].sc;
855 servers[KAS].ubik = &c_handle->kas;
856 servers[PTS].ubik = &c_handle->pts;
857 servers[VOS].ubik = &c_handle->vos;
858 servers[KAS].valid = &c_handle->kas_valid;
859 servers[PTS].valid = &c_handle->pts_valid;
860 servers[VOS].valid = &c_handle->vos_valid;
861 c_handle->vos_new = 1;
863 if ((servers[PTS].sc == NULL) || (servers[VOS].sc == NULL)) {
864 tst = ADMCLIENTBADTOKENHANDLE;
865 goto fail_afsclient_CellOpen;
869 * If the initialization has succeeded so far, get the address
870 * information for each server in the cell
873 strncpy(c_handle->working_cell, cellName, MAXCELLCHARS);
874 c_handle->working_cell[MAXCELLCHARS - 1] = '\0';
875 if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
876 tst = ADMCLIENTBADCLIENTCONFIG;
877 goto fail_afsclient_CellOpen;
881 * We must copy the cellName here because afsconf_GetCellInfo
882 * actually writes over the cell name it is passed.
884 strncpy(copyCell, cellName, MAXCELLCHARS);
885 copyCell[MAXCELLCHARS - 1] ='\0';
886 for (i = 0; (i < NUM_SERVER_TYPES); i++) {
889 ka_AuthServerConn((char *)cellName, servers[i].serviceId,
890 ((t_handle->sc_index == 0)
892 kas_token_set)) ? 0 : &t_handle->
893 kas_token, servers[i].ubik);
895 goto fail_afsclient_CellOpen;
898 tst = afsconf_GetCellInfo(tdir, copyCell, servers[i].serv, &info);
900 /* create ubik client handles for each server */
901 scIndex = t_handle->sc_index;
902 sc[scIndex] = servers[i].sc;
903 for (j = 0; (j < info.numServers); j++) {
905 rx_GetCachedConnection(info.hostAddr[j].sin_addr.
907 info.hostAddr[j].sin_port,
908 servers[i].serviceId,
909 sc[scIndex], scIndex);
912 tst = ubik_ClientInit(serverconns, servers[i].ubik);
914 goto fail_afsclient_CellOpen;
917 goto fail_afsclient_CellOpen;
920 /* initialization complete, mark handle valid */
921 *servers[i].valid = 1;
923 c_handle->tokens = t_handle;
926 fail_afsclient_CellOpen:
933 * Upon error, free any obtained resources.
936 if (c_handle != NULL) {
937 if (c_handle->kas_valid)
938 ubik_ClientDestroy(c_handle->kas);
939 if (c_handle->pts_valid)
940 ubik_ClientDestroy(c_handle->pts);
941 if (c_handle->vos_valid)
942 ubik_ClientDestroy(c_handle->vos);
946 c_handle->begin_magic = BEGIN_MAGIC;
947 c_handle->is_valid = 1;
948 c_handle->is_null = 0;
949 c_handle->end_magic = END_MAGIC;
950 *cellHandleP = (void *)c_handle;
960 * afsclient_NullCellOpen - open a null cell handle for access.
964 * OUT cellHandleP - an opaque pointer that is the first parameter to
965 * almost all subsequent admin api calls.
969 * No locks are obtained or released by this function
977 * Returns != 0 upon successful completion.
981 afsclient_NullCellOpen(void **cellHandleP, afs_status_p st)
984 afs_status_t tst = 0;
985 afs_cell_handle_p c_handle = (afs_cell_handle_p)
986 calloc(1, sizeof(afs_cell_handle_t));
990 * Validate parameters
993 if (cellHandleP == NULL) {
994 tst = ADMCLIENTCELLHANDLEPNULL;
995 goto fail_afsclient_NullCellOpen;
998 if (client_init == 0) {
999 tst = ADMCLIENTNOINIT;
1000 goto fail_afsclient_NullCellOpen;
1003 if (c_handle == NULL) {
1005 goto fail_afsclient_NullCellOpen;
1009 * Get unauthenticated tokens for any cell
1012 if (!afsclient_TokenGetNew(0, 0, 0, (void *)&c_handle->tokens, &tst)) {
1013 goto fail_afsclient_NullCellOpen;
1016 c_handle->begin_magic = BEGIN_MAGIC;
1017 c_handle->is_valid = 1;
1018 c_handle->is_null = 1;
1019 c_handle->end_magic = END_MAGIC;
1020 c_handle->kas_valid = 0;
1021 c_handle->pts_valid = 0;
1022 c_handle->vos_valid = 0;
1026 *cellHandleP = (void *)c_handle;
1029 fail_afsclient_NullCellOpen:
1038 * afsclient_CellClose - close a previously opened cellHandle.
1042 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
1046 * No locks are obtained or released by this function
1054 * Returns != 0 upon successful completion.
1058 afsclient_CellClose(const void *cellHandle, afs_status_p st)
1061 afs_status_t tst = 0;
1062 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1064 if (client_init == 0) {
1065 tst = ADMCLIENTNOINIT;
1066 goto fail_afsclient_CellClose;
1069 if (c_handle == NULL) {
1070 tst = ADMCLIENTCELLHANDLENULL;
1071 goto fail_afsclient_CellClose;
1074 if (c_handle->kas_valid)
1075 ubik_ClientDestroy(c_handle->kas);
1076 if (c_handle->pts_valid)
1077 ubik_ClientDestroy(c_handle->pts);
1078 if (c_handle->vos_valid)
1079 ubik_ClientDestroy(c_handle->vos);
1080 if (c_handle->is_null)
1081 afsclient_TokenClose(c_handle->tokens, 0);
1082 c_handle->kas_valid = 0;
1083 c_handle->pts_valid = 0;
1084 c_handle->vos_valid = 0;
1085 c_handle->is_valid = 0;
1089 fail_afsclient_CellClose:
1099 * afsclient_CellNameGet() -- get a pointer to the cell name in a cell handle
1103 * IN cellHandle - a valid cell handle
1104 * OUT cellNameP - a pointer to the cell name in the cell handle.
1108 * No locks are obtained or released by this function
1112 * If cellHandle is closed then the pointer returned by this function
1113 * is no longer valid.
1117 * Returns != 0 upon successful completion.
1120 afsclient_CellNameGet(const void *cellHandle, const char **cellNameP,
1124 afs_status_t tst = 0;
1125 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1127 if (!CellHandleIsValid(cellHandle, &tst)) {
1128 goto fail_afsclient_CellNameGet;
1131 *cellNameP = c_handle->working_cell;
1134 fail_afsclient_CellNameGet:
1144 * afsclient_LocalCellGet - get the name of the cell the machine
1145 * belongs to where this process is running.
1149 * OUT cellName - an array of characters that must be MAXCELLCHARS
1154 * No locks are obtained or released by this function
1158 * If cellName is smaller than MAXCELLCHARS chars, this function won't
1163 * Returns != 0 upon successful completion.
1167 afsclient_LocalCellGet(char *cellName, afs_status_p st)
1170 afs_status_t tst = 0;
1171 struct afsconf_dir *tdir = NULL;
1173 if (client_init == 0) {
1174 tst = ADMCLIENTNOINIT;
1175 goto fail_afsclient_LocalCellGet;
1178 if (cellName == NULL) {
1179 tst = ADMCLIENTCELLNAMENULL;
1180 goto fail_afsclient_LocalCellGet;
1183 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1186 tst = ADMCLIENTBADCLIENTCONFIG;
1187 goto fail_afsclient_LocalCellGet;
1190 if ((tst = afsconf_GetLocalCell(tdir, cellName, MAXCELLCHARS))) {
1191 goto fail_afsclient_LocalCellGet;
1196 fail_afsclient_LocalCellGet:
1199 afsconf_Close(tdir);
1212 client_ExtractDriveLetter(char *path)
1216 if (path[0] != 0 && path[1] == ':') {
1225 * Determine the parent directory of a give directory
1229 Parent(char *directory, char *parentDirectory)
1234 strcpy(parentDirectory, directory);
1235 tp = strrchr(parentDirectory, '\\');
1237 /* lv trailing slash so Parent("k:\foo") is "k:\" not "k :" */
1241 if (client_ExtractDriveLetter(parentDirectory)) {
1242 strcat(parentDirectory, ".");
1252 * Determine the parent directory of a give directory
1255 Parent(const char *directory, char *parentDirectory)
1260 strcpy(parentDirectory, directory);
1261 tp = strrchr(parentDirectory, '/');
1266 strcpy(parentDirectory, ".");
1275 * afsclient_MountPointCreate - create a mount point for a volume.
1279 * IN cellHandle - a handle to the cell where volumeName resides.
1281 * IN directory - the directory where the mountpoint should be created.
1283 * IN volumeName - the name of the volume to mount.
1285 * IN volType - the type of mount point to create.
1287 * IN volCheck - indicates whether or not to check the VLDB to see if
1288 * volumeName exists.
1292 * No locks are obtained or released by this function
1296 * Returns != 0 upon successful completion.
1299 #define TMP_DATA_SIZE 2048
1302 afsclient_MountPointCreate(const void *cellHandle, const char *directory,
1303 const char *volumeName, vol_type_t volType,
1304 vol_check_t volCheck, afs_status_p st)
1307 afs_status_t tst = 0;
1308 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1309 char parent_dir[TMP_DATA_SIZE];
1310 char space[TMP_DATA_SIZE];
1311 char directoryCell[MAXCELLCHARS];
1312 struct ViceIoctl idata;
1314 vos_vldbEntry_t vldbEntry;
1317 * Validate arguments
1320 if (client_init == 0) {
1321 tst = ADMCLIENTNOINIT;
1322 goto fail_afsclient_MountPointCreate;
1325 if ((directory == NULL) || (*directory == 0)) {
1326 tst = ADMCLIENTDIRECTORYNULL;
1327 goto fail_afsclient_MountPointCreate;
1330 if ((volumeName == NULL) || (*volumeName == 0)) {
1331 tst = ADMCLIENTVOLUMENAME;
1332 goto fail_afsclient_MountPointCreate;
1336 * Extract the parent directory and make sure it is in AFS.
1339 if (!Parent(directory, parent_dir)) {
1340 tst = ADMCLIENTBADDIRECTORY;
1341 goto fail_afsclient_MountPointCreate;
1345 idata.out_size = TMP_DATA_SIZE;
1347 i = pioctl(parent_dir, VIOC_FILE_CELL_NAME, &idata, 1);
1349 if ((errno == EINVAL) || (errno == ENOENT)) {
1350 tst = ADMCLIENTNOAFSDIRECTORY;
1351 goto fail_afsclient_MountPointCreate;
1354 strcpy(directoryCell, space);
1357 * If the user requested, check that the volume exists
1360 if (volCheck == CHECK_VOLUME) {
1361 if (!vos_VLDBGet(cellHandle, 0, 0, volumeName, &vldbEntry, &tst)) {
1362 goto fail_afsclient_MountPointCreate;
1367 * Begin constructing the pioctl buffer
1370 if (volType == READ_WRITE) {
1377 * Append the cell to the mount point if the volume is in a different
1378 * cell than the directory
1381 if (strcmp(c_handle->working_cell, directoryCell)) {
1382 strcat(space, c_handle->working_cell);
1385 strcat(space, volumeName);
1392 idata.in_size = 1 + strlen(space);
1394 if (tst = pioctl(directory, VIOC_AFS_CREATE_MT_PT, &idata, 0)) {
1395 goto fail_afsclient_MountPointCreate;
1398 if ((tst = symlink(space, directory))) {
1399 goto fail_afsclient_MountPointCreate;
1405 fail_afsclient_MountPointCreate:
1413 typedef struct Acl {
1421 afsclient_ACLEntryAdd(const char *directory, const char *user,
1422 const acl_p acl, afs_status_p st)
1425 afs_status_t tst = 0;
1426 struct ViceIoctl idata;
1427 char old_acl_string[2048];
1428 char new_acl_string[2048];
1433 int cur_user_acl = 0;
1438 if (client_init == 0) {
1439 tst = ADMCLIENTNOINIT;
1440 goto fail_afsclient_ACLEntryAdd;
1443 if ((directory == NULL) || (*directory == 0)) {
1444 tst = ADMMISCDIRECTORYNULL;
1445 goto fail_afsclient_ACLEntryAdd;
1448 if ((user == NULL) || (*user == 0)) {
1449 tst = ADMMISCUSERNULL;
1450 goto fail_afsclient_ACLEntryAdd;
1454 tst = ADMMISCACLNULL;
1455 goto fail_afsclient_ACLEntryAdd;
1458 if (acl->read == READ) {
1462 if (acl->write == WRITE) {
1466 if (acl->insert == INSERT) {
1470 if (acl->lookup == LOOKUP) {
1474 if (acl->del == DELETE) {
1478 if (acl->lock == LOCK) {
1482 if (acl->admin == ADMIN) {
1487 * Get the current acl for the directory
1490 idata.out_size = 2048;
1492 idata.in = idata.out = old_acl_string;
1493 tst = pioctl(directory, VIOCGETAL, &idata, 1);
1496 goto fail_afsclient_ACLEntryAdd;
1500 * The acl is presented to us in string format. The format of the
1503 * A header which contains the number of positive and negative entries
1504 * and a string indicating whether or not this is a dfs acl:
1506 * num_pos "\n" dfs_string "\n" num_neg
1508 * An entry for each acl that's of the form:
1512 * There are no blanks in the string between fields, but I use them here
1513 * to make the reading easier.
1515 * Since we are only going to add another entry to the acl, our approach
1516 * is simple. Get the num_pos dfs_string and num_neg from the current acl,
1517 * increment num_pos by one and create a new string. Concatenate the new
1518 * user and rights to the new string, and then concatenate the remaining
1519 * contents of the old acl to the new string.
1521 * Unfortunately, this approach doesn't work since the format the kernel
1522 * hands the acl back to us in, is NOT WHAT IT WANTS BACK!!!!
1523 * So instead we need to parse the entire freaking acl and put a space
1524 * between each user and their acl.
1526 * This is really ugly.
1530 * Parse the first few fields of the acl and see if this is a DFS
1535 sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs,
1537 ptr = strchr(old_acl_string, '\n');
1539 sscanf(ptr, "%d", &cur_acl.nminus);
1540 ptr = strchr(ptr, '\n');
1543 tst = ADMMISCNODFSACL;
1544 goto fail_afsclient_ACLEntryAdd;
1547 * It isn't a DFS file, so create the beginning of the string
1548 * we will hand back to the kernel
1550 sprintf(new_acl_string, "%d\n%d\n%s %d\n", (cur_acl.nplus + 1),
1551 cur_acl.nminus, user, newacl);
1555 * Finish scanning the old acl, parsing each user/acl pair and
1556 * adding a space in the new acl.
1559 for (i = 0; i < (cur_acl.nplus + cur_acl.nminus); i++) {
1560 sscanf(ptr, "%s%d\n", cur_user, &cur_user_acl);
1562 * Skip the entry for the user we are replacing/adding
1565 if (strcmp(cur_user, user)) {
1566 ptr = strchr(ptr, '\n');
1568 sprintf(tmp, "%s %d\n", cur_user, cur_user_acl);
1569 strcat(new_acl_string, tmp);
1573 strcat(new_acl_string, ptr);
1580 idata.in_size = strlen(new_acl_string) + 1;
1581 idata.in = idata.out = new_acl_string;
1582 tst = pioctl(directory, VIOCSETAL, &idata, 1);
1585 goto fail_afsclient_ACLEntryAdd;
1589 fail_afsclient_ACLEntryAdd:
1598 * afsclient_Init - initialize AFS components before use.
1604 * No locks are obtained or released by this function
1612 * Returns != 0 upon successful completion.
1616 afsclient_Init(afs_status_p st)
1619 afs_status_t tst = 0;
1622 pthread_once(&client_init_once, client_once);
1625 if (afs_winsockInit() < 0) {
1626 tst = ADMCLIENTCANTINITWINSOCK;
1627 goto fail_afsclient_Init;
1631 if (!(initAFSDirPath() & AFSDIR_CLIENT_PATHS_OK)) {
1632 tst = ADMCLIENTCANTINITAFSLOCATION;
1633 goto fail_afsclient_Init;
1636 if (rx_Init(0) < 0) {
1637 tst = ADMCLIENTCANTINITRX;
1638 goto fail_afsclient_Init;
1641 if ((tst = ka_CellConfig((char *)AFSDIR_CLIENT_ETC_DIRPATH))) {
1642 goto fail_afsclient_Init;
1647 fail_afsclient_Init:
1656 * afsclient_AFSServerGet - determine what kind of server serverName
1657 * is and fill in serverEntryP accordingly.
1661 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1663 * IN serverName - the hostname of the server of interest.
1665 * OUT serverEntryP - upon successful completion contains a description of
1670 * No locks are obtained or released by this function
1678 * Returns != 0 upon successful completion.
1682 afsclient_AFSServerGet(const void *cellHandle, const char *serverName,
1683 afs_serverEntry_p serverEntryP, afs_status_p st)
1686 afs_status_t tst = 0;
1688 int found_match = 0;
1690 if ((serverName == NULL) || (*serverName == 0)) {
1691 tst = ADMUTILSERVERNAMENULL;
1692 goto fail_afsclient_AFSServerGet;
1695 if (serverEntryP == NULL) {
1696 tst = ADMUTILSERVERENTRYPNULL;
1697 goto fail_afsclient_AFSServerGet;
1701 * Iterate over server entries and try to find a match for serverName
1704 if (!afsclient_AFSServerGetBegin(cellHandle, &iter, &tst)) {
1705 goto fail_afsclient_AFSServerGet;
1708 while (afsclient_AFSServerGetNext(iter, serverEntryP, &tst)) {
1709 if (!strcmp(serverName, serverEntryP->serverName)) {
1716 * If we didn't find a match, the iterator should have terminated
1717 * normally. If it didn't, return the error
1721 if (tst != ADMITERATORDONE) {
1722 afsclient_AFSServerGetDone(iter, 0);
1724 afsclient_AFSServerGetDone(iter, &tst);
1726 tst = ADMCLIENTNOMATCHINGSERVER;
1727 goto fail_afsclient_AFSServerGet;
1729 if (!afsclient_AFSServerGetDone(iter, &tst)) {
1730 goto fail_afsclient_AFSServerGet;
1735 fail_afsclient_AFSServerGet:
1744 * The iterator functions and data for the server retrieval functions
1747 typedef struct server_get {
1750 afs_serverEntry_t server[MAXHOSTSPERCELL + BADSERVERID];
1751 afs_serverEntry_t cache[CACHED_ITEMS];
1752 } server_get_t, *server_get_p;
1755 GetServerRPC(void *rpc_specific, int slot, int *last_item,
1756 int *last_item_contains_data, afs_status_p st)
1759 afs_status_t tst = 0;
1760 server_get_p serv = (server_get_p) rpc_specific;
1762 memcpy(&serv->cache[slot], &serv->server[serv->index],
1763 sizeof(afs_serverEntry_t));
1766 if (serv->index == serv->total) {
1768 *last_item_contains_data = 1;
1779 GetServerFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
1782 afs_status_t tst = 0;
1783 server_get_p serv = (server_get_p) rpc_specific;
1785 memcpy(dest, (const void *)&serv->cache[slot], sizeof(afs_serverEntry_t));
1795 * afsclient_AFSServerGetBegin - start the process of iterating over
1796 * every server in the cell.
1800 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1802 * OUT iterationIdP - - upon successful completion contains an iterator
1803 * that can be passed to afsclient_AFSServerGetNext.
1807 * No locks are obtained or released by this function
1815 * Returns != 0 upon successful completion.
1819 afsclient_AFSServerGetBegin(const void *cellHandle, void **iterationIdP,
1823 afs_status_t tst = 0;
1824 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1825 afs_admin_iterator_p iter =
1826 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1827 server_get_p serv = (server_get_p) calloc(1, sizeof(server_get_t));
1828 const char *cellName;
1829 void *database_iter;
1830 util_databaseServerEntry_t database_entry;
1831 void *fileserver_iter;
1832 vos_fileServerEntry_t fileserver_entry;
1833 int iserv, iservaddr, ientryaddr, is_dup;
1834 struct hostent *host;
1836 if (!CellHandleIsValid(c_handle, &tst)) {
1837 goto fail_afsclient_AFSServerGetBegin;
1840 if (iterationIdP == NULL) {
1841 tst = ADMITERATIONIDPNULL;
1842 goto fail_afsclient_AFSServerGetBegin;
1845 if ((serv == NULL) || (iter == NULL)) {
1847 goto fail_afsclient_AFSServerGetBegin;
1851 * Retrieve the list of database servers for this cell.
1854 if (!afsclient_CellNameGet(cellHandle, &cellName, &tst)) {
1855 goto fail_afsclient_AFSServerGetBegin;
1858 if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
1859 goto fail_afsclient_AFSServerGetBegin;
1862 while (util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
1863 serv->server[serv->total].serverAddress[0] =
1864 database_entry.serverAddress;
1865 serv->server[serv->total].serverType = DATABASE_SERVER;
1869 if (tst != ADMITERATORDONE) {
1870 util_DatabaseServerGetDone(database_iter, 0);
1871 goto fail_afsclient_AFSServerGetBegin;
1874 if (!util_DatabaseServerGetDone(database_iter, &tst)) {
1875 goto fail_afsclient_AFSServerGetBegin;
1879 * Retrieve the list of file servers for this cell.
1882 if (!vos_FileServerGetBegin(cellHandle, 0, &fileserver_iter, &tst)) {
1883 goto fail_afsclient_AFSServerGetBegin;
1886 while (vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
1888 * See if any of the addresses returned in this fileserver_entry
1889 * structure already exist in the list of servers we're building.
1890 * If not, create a new record for this server.
1893 for (iserv = 0; iserv < serv->total; iserv++) {
1894 for (ientryaddr = 0; ientryaddr < fileserver_entry.count;
1896 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1898 if (serv->server[iserv].serverAddress[iservaddr] ==
1899 fileserver_entry.serverAddress[ientryaddr]) {
1914 serv->server[iserv].serverType |= FILE_SERVER;
1916 iserv = serv->total++;
1917 serv->server[iserv].serverType = FILE_SERVER;
1921 * Add the addresses from the vldb list to the serv->server[iserv]
1922 * record. Remember that VLDB's list-of-addrs is not guaranteed
1923 * to be unique in a particular entry, or to return only one entry
1924 * per machine--so when we add addresses, always check for
1925 * duplicate entries.
1928 for (ientryaddr = 0; ientryaddr < fileserver_entry.count;
1930 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1932 if (serv->server[iserv].serverAddress[iservaddr] ==
1933 fileserver_entry.serverAddress[ientryaddr]) {
1937 if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
1938 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1940 if (!serv->server[iserv].serverAddress[iservaddr]) {
1941 serv->server[iserv].serverAddress[iservaddr] =
1942 fileserver_entry.serverAddress[ientryaddr];
1950 if (tst != ADMITERATORDONE) {
1951 vos_FileServerGetDone(fileserver_iter, 0);
1952 goto fail_afsclient_AFSServerGetBegin;
1955 if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
1956 goto fail_afsclient_AFSServerGetBegin;
1960 * Iterate over the list and fill in the hostname of each of the servers
1964 for (iserv = 0; iserv < serv->total; iserv++) {
1965 int addr = htonl(serv->server[iserv].serverAddress[0]);
1966 host = gethostbyaddr((const char *)&addr, sizeof(int), AF_INET);
1968 strncpy(serv->server[iserv].serverName, host->h_name,
1969 AFS_MAX_SERVER_NAME_LEN);
1970 serv->server[iserv].serverName[AFS_MAX_SERVER_NAME_LEN - 1] = '\0';
1973 UNLOCK_GLOBAL_MUTEX;
1975 (iter, (void *)serv, GetServerRPC, GetServerFromCache, NULL, NULL,
1977 *iterationIdP = (void *)iter;
1981 fail_afsclient_AFSServerGetBegin:
1999 * afsclient_AFSServerGetNext - retrieve the next server in the cell.
2003 * IN iterationId - an iterator previously returned by
2004 * afsclient_AFSServerGetBegin.
2006 * OUT serverEntryP - upon successful completion contains the next server.
2010 * No locks are obtained or released by this function
2018 * Returns != 0 upon successful completion.
2022 afsclient_AFSServerGetNext(void *iterationId, afs_serverEntry_p serverEntryP,
2026 afs_status_t tst = 0;
2027 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2029 if (iterationId == NULL) {
2030 tst = ADMITERATORNULL;
2031 goto fail_afsclient_AFSServerGetNext;
2034 if (serverEntryP == NULL) {
2035 tst = ADMUTILSERVERENTRYPNULL;
2036 goto fail_afsclient_AFSServerGetNext;
2039 rc = IteratorNext(iter, (void *)serverEntryP, &tst);
2041 fail_afsclient_AFSServerGetNext:
2050 * afsclient_AFSServerGetDone - finish using a server iterator.
2054 * IN iterationId - an iterator previously returned by
2055 * afsclient_AFSServerGetBegin.
2059 * No locks are obtained or released by this function
2067 * Returns != 0 upon successful completion.
2071 afsclient_AFSServerGetDone(void *iterationId, afs_status_p st)
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_AFSServerGetDone;
2082 rc = IteratorDone(iter, &tst);
2084 fail_afsclient_AFSServerGetDone:
2093 * afsclient_RPCStatOpen - open an rx connection to a server to retrieve
2098 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2100 * IN serverName - the host name where the server resides.
2102 * IN type - what type of process to query
2104 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2108 * No locks are obtained or released by this function
2116 * Returns != 0 upon successful completion.
2120 afsclient_RPCStatOpen(const void *cellHandle, const char *serverName,
2121 afs_stat_source_t type,
2122 struct rx_connection **rpcStatHandleP, afs_status_p st)
2125 afs_status_t tst = 0;
2126 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2129 struct rx_securityClass *sc;
2131 if (!CellHandleIsValid(cellHandle, &tst)) {
2132 goto fail_afsclient_RPCStatOpen;
2135 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2136 goto fail_afsclient_RPCStatOpen;
2139 if (rpcStatHandleP == NULL) {
2140 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2141 goto fail_afsclient_RPCStatOpen;
2147 servPort = AFSCONF_NANNYPORT;
2150 case AFS_FILESERVER:
2151 servPort = AFSCONF_FILEPORT;
2155 servPort = AFSCONF_KAUTHPORT;
2159 servPort = AFSCONF_PROTPORT;
2163 servPort = AFSCONF_VOLUMEPORT;
2167 servPort = AFSCONF_VLDBPORT;
2171 servPort = AFSCONF_CALLBACKPORT;
2175 tst = ADMTYPEINVALID;
2176 goto fail_afsclient_RPCStatOpen;
2180 * special processing of tokens by server type
2183 if (type == AFS_KASERVER) {
2184 if (!c_handle->tokens->kas_token_set) {
2185 tst = ADMCLIENTNOKASTOKENS;
2186 goto fail_afsclient_RPCStatOpen;
2188 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2190 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2194 rx_GetCachedConnection(htonl(servAddr), htons(servPort),
2195 RX_STATS_SERVICE_ID, sc,
2196 c_handle->tokens->sc_index);
2198 if (*rpcStatHandleP == NULL) {
2199 tst = ADMCLIENTRPCSTATNOCONNECTION;
2200 goto fail_afsclient_RPCStatOpen;
2204 fail_afsclient_RPCStatOpen:
2213 * afsclient_RPCStatOpenPort - open an rx connection to a server to retrieve
2218 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2220 * IN serverName - the host name where the server resides.
2222 * IN port - the UDP port number where the server resides.
2224 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2228 * No locks are obtained or released by this function
2236 * Returns != 0 upon successful completion.
2240 afsclient_RPCStatOpenPort(const void *cellHandle, const char *serverName,
2241 const int serverPort,
2242 struct rx_connection **rpcStatHandleP,
2246 afs_status_t tst = 0;
2247 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2249 struct rx_securityClass *sc;
2251 if (!CellHandleIsValid(cellHandle, &tst)) {
2252 goto fail_afsclient_RPCStatOpenPort;
2255 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2256 goto fail_afsclient_RPCStatOpenPort;
2259 if (rpcStatHandleP == NULL) {
2260 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2261 goto fail_afsclient_RPCStatOpenPort;
2265 * special processing of tokens by server type
2268 if (serverPort == AFSCONF_KAUTHPORT) {
2269 if (!c_handle->tokens->kas_token_set) {
2270 tst = ADMCLIENTNOKASTOKENS;
2271 goto fail_afsclient_RPCStatOpenPort;
2273 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2275 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2279 rx_GetCachedConnection(htonl(servAddr), htons(serverPort),
2280 RX_STATS_SERVICE_ID, sc,
2281 c_handle->tokens->sc_index);
2283 if (*rpcStatHandleP == NULL) {
2284 tst = ADMCLIENTRPCSTATNOCONNECTION;
2285 goto fail_afsclient_RPCStatOpenPort;
2289 fail_afsclient_RPCStatOpenPort:
2298 * afsclient_RPCStatClose - close a previously opened rx connection.
2302 * IN rpcStatHandle - an rx connection returned by afsclient_RPCStatOpen
2306 * No locks are obtained or released by this function
2314 * Returns != 0 upon successful completion.
2318 afsclient_RPCStatClose(struct rx_connection *rpcStatHandle, afs_status_p st)
2321 afs_status_t tst = 0;
2323 if (rpcStatHandle == NULL) {
2324 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2325 goto fail_afsclient_RPCStatClose;
2328 rx_ReleaseCachedConnection(rpcStatHandle);
2330 fail_afsclient_RPCStatClose:
2339 * afsclient_CMStatOpen - open an rx connection to a server to retrieve
2344 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2346 * IN serverName - the host name where the server resides.
2348 * OUT cmStatHandleP - contains an rx connection to the server of interest
2352 * No locks are obtained or released by this function
2360 * Returns != 0 upon successful completion.
2364 afsclient_CMStatOpen(const void *cellHandle, const char *serverName,
2365 struct rx_connection **cmStatHandleP, afs_status_p st)
2368 afs_status_t tst = 0;
2369 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2371 struct rx_securityClass *sc;
2373 if (!CellHandleIsValid(cellHandle, &tst)) {
2374 goto fail_afsclient_CMStatOpen;
2377 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2378 goto fail_afsclient_CMStatOpen;
2381 if (cmStatHandleP == NULL) {
2382 tst = ADMCLIENTCMSTATHANDLEPNULL;
2383 goto fail_afsclient_CMStatOpen;
2386 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2389 rx_GetCachedConnection(htonl(servAddr), htons(AFSCONF_CALLBACKPORT),
2390 1, sc, c_handle->tokens->sc_index);
2392 if (*cmStatHandleP == NULL) {
2393 tst = ADMCLIENTCMSTATNOCONNECTION;
2394 goto fail_afsclient_CMStatOpen;
2398 fail_afsclient_CMStatOpen:
2407 * afsclient_CMStatOpenPort - open an rx connection to a server to retrieve
2412 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2414 * IN serverName - the host name where the server resides.
2416 * IN port - the UDP port number where the server resides.
2418 * OUT cmStatHandleP - contains an rx connection to the server of interest
2422 * No locks are obtained or released by this function
2430 * Returns != 0 upon successful completion.
2434 afsclient_CMStatOpenPort(const void *cellHandle, const char *serverName,
2435 const int serverPort,
2436 struct rx_connection **cmStatHandleP,
2440 afs_status_t tst = 0;
2441 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2443 struct rx_securityClass *sc;
2445 if (!CellHandleIsValid(cellHandle, &tst)) {
2446 goto fail_afsclient_CMStatOpenPort;
2449 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2450 goto fail_afsclient_CMStatOpenPort;
2453 if (cmStatHandleP == NULL) {
2454 tst = ADMCLIENTCMSTATHANDLEPNULL;
2455 goto fail_afsclient_CMStatOpenPort;
2458 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2461 rx_GetCachedConnection(htonl(servAddr), htons(serverPort), 1, sc,
2462 c_handle->tokens->sc_index);
2464 if (*cmStatHandleP == NULL) {
2465 tst = ADMCLIENTCMSTATNOCONNECTION;
2466 goto fail_afsclient_CMStatOpenPort;
2470 fail_afsclient_CMStatOpenPort:
2479 * afsclient_CMStatClose - close a previously opened rx connection.
2483 * IN cmStatHandle - an rx connection returned by afsclient_CMStatOpen
2487 * No locks are obtained or released by this function
2495 * Returns != 0 upon successful completion.
2499 afsclient_CMStatClose(struct rx_connection *cmStatHandle, afs_status_p st)
2502 afs_status_t tst = 0;
2504 if (cmStatHandle == NULL) {
2505 tst = ADMCLIENTCMSTATHANDLEPNULL;
2506 goto fail_afsclient_CMStatClose;
2509 rx_ReleaseCachedConnection(cmStatHandle);
2511 fail_afsclient_CMStatClose:
2520 * afsclient_RXDebugOpen - open an rxdebug handle to a server.
2524 * IN serverName - the host name where the server resides.
2526 * IN type - what type of process to query
2528 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2532 * No locks are obtained or released by this function
2540 * Returns != 0 upon successful completion.
2544 afsclient_RXDebugOpen(const char *serverName, afs_stat_source_t type,
2545 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2548 afs_status_t tst = 0;
2550 rxdebugHandle_p handle;
2551 rxdebugSocket_t sock;
2552 struct sockaddr_in taddr;
2556 if (rxdebugHandleP == NULL) {
2557 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2558 goto fail_afsclient_RXDebugOpen;
2564 serverPort = AFSCONF_NANNYPORT;
2567 case AFS_FILESERVER:
2568 serverPort = AFSCONF_FILEPORT;
2572 serverPort = AFSCONF_KAUTHPORT;
2576 serverPort = AFSCONF_PROTPORT;
2580 serverPort = AFSCONF_VOLUMEPORT;
2584 serverPort = AFSCONF_VLDBPORT;
2588 serverPort = AFSCONF_CALLBACKPORT;
2592 tst = ADMTYPEINVALID;
2593 goto fail_afsclient_RXDebugOpen;
2596 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2597 goto fail_afsclient_RXDebugOpen;
2600 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2601 if (sock == INVALID_RXDEBUG_SOCKET) {
2603 goto fail_afsclient_RXDebugOpen;
2606 memset(&taddr, 0, sizeof(taddr));
2607 taddr.sin_family = AF_INET;
2609 taddr.sin_addr.s_addr = INADDR_ANY;
2610 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2614 goto fail_afsclient_RXDebugOpen;
2617 handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
2621 goto fail_afsclient_RXDebugOpen;
2624 handle->sock = sock;
2625 handle->ipAddr = serverAddr;
2626 handle->udpPort = serverPort;
2627 handle->firstFlag = 1;
2628 handle->supportedStats = 0;
2629 *rxdebugHandleP = handle;
2632 fail_afsclient_RXDebugOpen:
2641 * afsclient_RXDebugOpenPort - open an rxdebug handle to a server.
2645 * IN serverName - the host name where the server resides.
2647 * IN port - the UDP port number where the server resides.
2649 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2653 * No locks are obtained or released by this function
2661 * Returns != 0 upon successful completion.
2665 afsclient_RXDebugOpenPort(const char *serverName, int serverPort,
2666 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2669 afs_status_t tst = 0;
2671 rxdebugHandle_p handle;
2672 rxdebugSocket_t sock;
2673 struct sockaddr_in taddr;
2676 if (rxdebugHandleP == NULL) {
2677 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2678 goto fail_afsclient_RXDebugOpenPort;
2681 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2682 goto fail_afsclient_RXDebugOpenPort;
2685 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2686 if (sock == INVALID_RXDEBUG_SOCKET) {
2688 goto fail_afsclient_RXDebugOpenPort;
2691 memset(&taddr, 0, sizeof(taddr));
2692 taddr.sin_family = AF_INET;
2694 taddr.sin_addr.s_addr = INADDR_ANY;
2695 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2699 goto fail_afsclient_RXDebugOpenPort;
2702 handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
2706 goto fail_afsclient_RXDebugOpenPort;
2709 handle->sock = sock;
2710 handle->ipAddr = serverAddr;
2711 handle->udpPort = serverPort;
2712 handle->firstFlag = 1;
2713 handle->supportedStats = 0;
2714 *rxdebugHandleP = handle;
2717 fail_afsclient_RXDebugOpenPort:
2726 * afsclient_RXDebugClose - close a previously opened rxdebug handle.
2730 * IN rxdebugHandle - an rxdebug handle returned by afsclient_RXDebugOpen
2734 * No locks are obtained or released by this function
2742 * Returns != 0 upon successful completion.
2746 afsclient_RXDebugClose(rxdebugHandle_p rxdebugHandle, afs_status_p st)
2749 afs_status_t tst = 0;
2751 if (rxdebugHandle == NULL) {
2752 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2753 goto fail_afsclient_RXDebugClose;
2756 close(rxdebugHandle->sock);
2757 free(rxdebugHandle);
2759 fail_afsclient_RXDebugClose: