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/afssyscalls.h>
18 #include <afs/fs_utils.h>
19 #define close(x) closesocket(x)
21 #include <afs/venus.h>
24 #include <rx/rxstat.h>
25 #include <rx/rx_null.h>
28 #include <afs/kautils.h>
29 #include <afs/dirpath.h>
30 #include <afs/afs_AdminErrors.h>
31 #include <afs/afs_vosAdmin.h>
32 #include <afs/afs_utilAdmin.h>
33 #include <afs/ptserver.h>
34 #include <afs/vlserver.h>
35 #include <afs/pthread_glock.h>
36 #include <afs/sys_prototypes.h>
38 #include "afs_clientAdmin.h"
39 #include "../adminutil/afs_AdminInternal.h"
42 * AFS client administration functions.
44 * Admin functions that are normally associated with the client.
46 * All of the functions related to authentication are here, plus
47 * some miscellaneous others.
51 static const unsigned long ADMIN_TICKET_LIFETIME = 24 * 3600;
53 static const unsigned long SERVER_TTL = 10 * 60;
56 * We need a way to track whether or not the client library has been
57 * initialized. We count on the fact that the other library initialization
58 * functions are protected by their own once mechanism. We only track
59 * our own internal status
62 static int client_init;
63 static pthread_once_t client_init_once = PTHREAD_ONCE_INIT;
72 * IsTokenValid - validate a token handle
76 * IN token - the token to be validated.
80 * No locks are obtained or released by this function
88 * Returns != 0 upon successful completion.
92 IsTokenValid(const afs_token_handle_p token, afs_status_p st)
98 tst = ADMCLIENTTOKENHANDLENULL;
99 goto fail_IsTokenValid;
102 if (token->is_valid == 0) {
103 tst = ADMCLIENTTOKENHANDLEINVALID;
104 goto fail_IsTokenValid;
107 if ((token->begin_magic != BEGIN_MAGIC)
108 || (token->end_magic != END_MAGIC)) {
109 tst = ADMCLIENTTOKENHANDLEBADMAGIC;
110 goto fail_IsTokenValid;
123 * afsclient_TokenGetExisting - get tokens that already exist and
124 * are held by the cache manager.
128 * IN cellName - the name of the cell where the token originated.
130 * OUT tokenHandle - a handle to the tokens if they were obtained
135 * No locks are obtained or released by this function
139 * The tokenHandle returned by this function cannot be used for kas
140 * related operations, since kas tokens aren't stored in the kernel.
144 * Returns != 0 upon successful completion.
148 afsclient_TokenGetExisting(const char *cellName, void **tokenHandle,
152 afs_status_t tst = 0;
153 struct ktc_principal afs_server;
154 afs_token_handle_p t_handle =
155 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
157 if (client_init == 0) {
158 tst = ADMCLIENTNOINIT;
159 goto fail_afsclient_TokenGetExisting;
162 if (cellName == NULL) {
163 tst = ADMCLIENTCELLNAMENULL;
164 goto fail_afsclient_TokenGetExisting;
167 if (tokenHandle == NULL) {
168 tst = ADMCLIENTTOKENHANDLENULL;
169 goto fail_afsclient_TokenGetExisting;
172 if (t_handle == NULL) {
174 goto fail_afsclient_TokenGetExisting;
177 strcpy(afs_server.name, "afs");
178 afs_server.instance[0] = 0;
179 strcpy(afs_server.cell, cellName);
183 ktc_GetToken(&afs_server, &t_handle->afs_token,
184 sizeof(t_handle->afs_token), &t_handle->client))) {
186 * The token has been retrieved successfully, initialize
187 * the rest of the token handle structure
189 strncpy(t_handle->cell, cellName, MAXCELLCHARS);
190 t_handle->cell[MAXCELLCHARS - 1] = '\0';
191 t_handle->afs_token_set = 1;
192 t_handle->from_kernel = 1;
193 t_handle->kas_token_set = 0;
194 t_handle->sc_index = 2;
195 t_handle->afs_sc[t_handle->sc_index] =
196 rxkad_NewClientSecurityObject(rxkad_clear,
197 &t_handle->afs_token.sessionKey,
198 t_handle->afs_token.kvno,
199 t_handle->afs_token.ticketLen,
200 t_handle->afs_token.ticket);
201 t_handle->afs_encrypt_sc[t_handle->sc_index] =
202 rxkad_NewClientSecurityObject(rxkad_crypt,
203 &t_handle->afs_token.sessionKey,
204 t_handle->afs_token.kvno,
205 t_handle->afs_token.ticketLen,
206 t_handle->afs_token.ticket);
207 if ((t_handle->afs_sc[t_handle->sc_index] == NULL)
208 || (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
209 tst = ADMCLIENTTOKENHANDLENOSECURITY;
210 goto fail_afsclient_TokenGetExisting;
212 t_handle->begin_magic = BEGIN_MAGIC;
213 t_handle->is_valid = 1;
214 t_handle->end_magic = END_MAGIC;
215 *tokenHandle = (void *)t_handle;
218 goto fail_afsclient_TokenGetExisting;
222 fail_afsclient_TokenGetExisting:
224 if ((rc == 0) && (t_handle != NULL)) {
234 * afsclient_TokenSet - set the tokens represented by tokenHandle to be
235 * active in the kernel (aka ka_SetToken).
239 * IN cellName - the name of the cell where the token originated.
241 * OUT tokenHandle - a handle to the tokens if they were obtained
246 * No locks are obtained or released by this function
250 * The tokenHandle returned by this function cannot be used for kas
251 * related operations, since kas tokens aren't stored in the kernel.
255 * Returns != 0 upon successful completion.
259 afsclient_TokenSet(const void *tokenHandle, afs_status_p st)
262 afs_status_t tst = 0;
263 struct ktc_principal afs_server;
264 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
266 if (!IsTokenValid(t_handle, &tst)) {
267 goto fail_afsclient_TokenSet;
270 strcpy(afs_server.name, "afs");
271 afs_server.instance[0] = 0;
272 strcpy(afs_server.cell, t_handle->cell);
275 ktc_SetToken(&afs_server, &t_handle->afs_token, &t_handle->client, 0);
281 fail_afsclient_TokenSet:
290 * GetKASToken - get a KAS token and store it in the tokenHandle.
294 * IN cellName - the name of the cell where the token should be obtained.
296 * IN principal - the name of the user of the token.
298 * IN password - the password for the principal.
300 * OUT tokenHandle - a handle to the tokens if they were obtained
305 * No locks are obtained or released by this function
313 * Returns != 0 upon successful completion.
317 GetKASToken(const char *cellName, const char *principal, const char *password,
318 afs_token_handle_p tokenHandle, afs_status_p st)
321 afs_status_t tst = 0;
322 struct ubik_client *unauth_conn;
324 struct ktc_encryptionKey key;
325 struct ktc_token *token;
326 unsigned long now = time(0);
327 char name[MAXKTCNAMELEN];
328 char inst[MAXKTCNAMELEN];
329 int have_server_conn = 0;
331 token = &tokenHandle->kas_token;
333 ka_StringToKey((char *)password, (char *)cellName, &key);
336 * Get an unauthenticated connection in the right cell to use for
337 * retrieving the token.
341 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
344 goto fail_GetKASToken;
346 have_server_conn = 1;
348 tst = ka_ParseLoginName((char *)principal, name, inst, NULL);
350 goto fail_GetKASToken;
354 ka_Authenticate(name, inst, (char *)cellName, unauth_conn,
355 KA_MAINTENANCE_SERVICE, &key, now,
356 now + ADMIN_TICKET_LIFETIME, token, &expire);
358 goto fail_GetKASToken;
364 if (have_server_conn) {
365 ubik_ClientDestroy(unauth_conn);
375 * GetAFSToken - get a AFS token and store it in the tokenHandle.
379 * IN cellName - the name of the cell where the token should be obtained.
381 * IN principal - the name of the user of the token.
383 * IN password - the password for the principal.
385 * OUT tokenHandle - a handle to the tokens if they were obtained
390 * No locks are obtained or released by this function
398 * Returns != 0 upon successful completion.
402 GetAFSToken(const char *cellName, const char *principal, const char *password,
403 afs_token_handle_p tokenHandle, afs_status_p st)
406 afs_status_t tst = 0;
407 struct ubik_client *unauth_conn = NULL, *auth_conn = NULL;
409 struct ktc_encryptionKey key;
410 struct ktc_token auth_token;
411 struct ktc_token *token;
412 unsigned long now = time(0);
414 token = &tokenHandle->afs_token;
416 ka_StringToKey((char *)password, (char *)cellName, &key);
419 * Get an unauthenticated connection in the right cell to use for
420 * retrieving the token.
424 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
427 goto fail_GetAFSToken;
431 ka_ParseLoginName((char *)principal, tokenHandle->client.name,
432 tokenHandle->client.instance, NULL);
434 goto fail_GetAFSToken;
438 ka_Authenticate(tokenHandle->client.name,
439 tokenHandle->client.instance, (char *)cellName,
440 unauth_conn, KA_TICKET_GRANTING_SERVICE, &key, now,
441 now + ADMIN_TICKET_LIFETIME, &auth_token, &expire);
443 goto fail_GetAFSToken;
447 ka_AuthServerConn((char *)cellName, KA_TICKET_GRANTING_SERVICE, 0,
450 goto fail_GetAFSToken;
454 ka_CellToRealm((char *)cellName, tokenHandle->client.cell, (int *)0);
456 goto fail_GetAFSToken;
460 ka_GetToken("afs", "", (char *)cellName, tokenHandle->client.name,
461 tokenHandle->client.instance, auth_conn, now,
462 now + ADMIN_TICKET_LIFETIME, &auth_token,
463 tokenHandle->client.cell, token);
465 goto fail_GetAFSToken;
472 ubik_ClientDestroy(auth_conn);
476 ubik_ClientDestroy(unauth_conn);
487 * afsclient_TokenGetNew - get new tokens for a user and store them
488 * in the tokenHandle.
492 * IN cellName - the name of the cell where the tokens should be obtained.
494 * IN principal - the name of the user of the tokens.
496 * IN password - the password for the principal.
498 * OUT tokenHandle - a handle to the tokens if they were obtained
503 * No locks are obtained or released by this function
511 * Returns != 0 upon successful completion.
515 afsclient_TokenGetNew(const char *cellName, const char *principal,
516 const char *password, void **tokenHandle,
520 afs_status_t tst = 0;
521 afs_token_handle_p t_handle =
522 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
524 if (client_init == 0) {
525 tst = ADMCLIENTNOINIT;
526 goto fail_afsclient_TokenGetNew;
529 if (t_handle == NULL) {
531 goto fail_afsclient_TokenGetNew;
535 * Check to see if the principal or password is missing. If it is,
536 * get unauthenticated tokens for the cell
539 if ((principal == NULL) || (*principal == 0) || (password == NULL)
540 || (*password == 0)) {
541 t_handle->from_kernel = 0;
542 t_handle->afs_token_set = 1;
543 t_handle->kas_token_set = 1;
544 t_handle->sc_index = 0;
545 t_handle->afs_sc[t_handle->sc_index] =
546 rxnull_NewClientSecurityObject();
547 t_handle->afs_encrypt_sc[t_handle->sc_index] =
548 rxnull_NewClientSecurityObject();
549 t_handle->kas_sc[t_handle->sc_index] =
550 rxnull_NewClientSecurityObject();
551 t_handle->begin_magic = BEGIN_MAGIC;
552 t_handle->is_valid = 1;
553 t_handle->afs_token.endTime = 0;
554 t_handle->end_magic = END_MAGIC;
555 *tokenHandle = (void *)t_handle;
560 * create an authenticated token
563 if ((GetAFSToken(cellName, principal, password, t_handle, &tst))
564 && (GetKASToken(cellName, principal, password, t_handle, &tst))) {
565 strncpy(t_handle->cell, cellName, MAXCELLCHARS);
566 t_handle->cell[MAXCELLCHARS - 1] = '\0';
567 t_handle->from_kernel = 0;
568 t_handle->afs_token_set = 1;
569 t_handle->kas_token_set = 1;
570 t_handle->sc_index = 2;
571 t_handle->afs_sc[t_handle->sc_index] =
572 rxkad_NewClientSecurityObject(rxkad_clear,
573 &t_handle->afs_token.sessionKey,
574 t_handle->afs_token.kvno,
575 t_handle->afs_token.ticketLen,
576 t_handle->afs_token.ticket);
577 t_handle->afs_encrypt_sc[t_handle->sc_index] =
578 rxkad_NewClientSecurityObject(rxkad_crypt,
579 &t_handle->afs_token.sessionKey,
580 t_handle->afs_token.kvno,
581 t_handle->afs_token.ticketLen,
582 t_handle->afs_token.ticket);
583 t_handle->kas_sc[t_handle->sc_index] =
584 rxkad_NewClientSecurityObject(rxkad_crypt,
585 &t_handle->kas_token.sessionKey,
586 t_handle->kas_token.kvno,
587 t_handle->kas_token.ticketLen,
588 t_handle->kas_token.ticket);
589 if ((t_handle->afs_sc[t_handle->sc_index] != NULL)
590 && (t_handle->afs_encrypt_sc[t_handle->sc_index] != NULL)
591 && (t_handle->kas_sc[t_handle->sc_index] != NULL)) {
592 t_handle->begin_magic = BEGIN_MAGIC;
593 t_handle->is_valid = 1;
594 t_handle->end_magic = END_MAGIC;
595 *tokenHandle = (void *)t_handle;
597 tst = ADMCLIENTTOKENHANDLENOSECURITY;
598 goto fail_afsclient_TokenGetNew;
601 goto fail_afsclient_TokenGetNew;
606 fail_afsclient_TokenGetNew:
608 if ((rc == 0) && (t_handle != NULL)) {
619 * afsclient_TokenQuery - get the expiration time of the tokens.
623 * IN tokenHandle - a previously obtained valid token.
625 * OUT expirationDateP - the time at which the tokens expire.
627 * OUT principal - the owning principal
629 * OUT instance - principal instance if it exists.
631 * OUT cell - the principal's cell
633 * OUT hasKasTokens - set to 1 if the token handle contains kas tokens.
637 * No locks are obtained or released by this function
641 * We only check the AFS tokens since we always get these. The
642 * KAS tokens may expirer later than the AFS tokens, but this
643 * difference is minor and reporting an earlier time won't cause
648 * Returns != 0 upon successful completion.
652 afsclient_TokenQuery(void *tokenHandle, unsigned long *expirationDateP,
653 char *principal, char *instance, char *cell,
654 int *hasKasTokens, afs_status_p st)
657 afs_status_t tst = 0;
658 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
660 if (client_init == 0) {
661 tst = ADMCLIENTNOINIT;
663 goto fail_afsclient_TokenQuery;
666 if (IsTokenValid(t_handle, &tst)) {
667 if (principal != NULL) {
668 strcpy(principal, t_handle->client.name);
670 if (instance != NULL) {
671 strcpy(instance, t_handle->client.instance);
674 strcpy(cell, t_handle->client.cell);
676 if (hasKasTokens != NULL) {
677 *hasKasTokens = t_handle->kas_token_set;
679 if (expirationDateP != NULL) {
680 *expirationDateP = t_handle->afs_token.endTime;
685 fail_afsclient_TokenQuery:
694 * afsclient_TokenClose - close an existing token.
698 * IN token - the token to be closed.
702 * No locks are obtained or released by this function
710 * Returns != 0 upon successful completion.
714 afsclient_TokenClose(const void *tokenHandle, afs_status_p st)
717 afs_status_t tst = 0;
718 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
720 if (client_init == 0) {
721 tst = ADMCLIENTNOINIT;
722 goto fail_afsclient_TokenClose;
725 if (IsTokenValid(t_handle, &tst)) {
726 t_handle->is_valid = 0;
731 fail_afsclient_TokenClose:
739 #define NUM_SERVER_TYPES 3
741 /* must match NUM_SERVER_TYPES */
742 typedef enum { KAS, PTS, VOS } afs_server_list_t;
744 typedef struct afs_server {
747 struct ubik_client **ubik;
748 struct rx_securityClass *sc;
750 } afs_server_t, *afs_server_p;
753 * afsclient_CellOpen - Open a particular cell for work as a particular
758 * IN cellName - the cell where future admin calls will be made.
760 * IN tokenHandle - the tokens work will be done under.
762 * OUT cellHandleP - an opaque pointer that is the first parameter to
763 * almost all subsequent admin api calls.
767 * No locks are obtained or released by this function
775 * Returns != 0 upon successful completion.
779 afsclient_CellOpen(const char *cellName, const void *tokenHandle,
780 void **cellHandleP, afs_status_p st)
783 afs_status_t tst = 0;
784 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
785 afs_cell_handle_p c_handle = (afs_cell_handle_p)
786 calloc(1, sizeof(afs_cell_handle_t));
787 struct afsconf_dir *tdir = NULL;
788 struct afsconf_cell info;
789 struct rx_connection *serverconns[MAXSERVERS];
791 struct rx_securityClass *sc[3];
793 char copyCell[MAXCELLCHARS];
795 afs_server_t servers[NUM_SERVER_TYPES]
796 = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
797 {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
798 {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}
801 if (client_init == 0) {
802 tst = ADMCLIENTNOINIT;
803 goto fail_afsclient_CellOpen;
806 if (c_handle == NULL) {
808 goto fail_afsclient_CellOpen;
811 if (t_handle == NULL) {
812 tst = ADMCLIENTTOKENHANDLENULL;
813 goto fail_afsclient_CellOpen;
816 if ((cellName == NULL) || (*cellName == 0)) {
817 tst = ADMCLIENTCELLNAMENULL;
818 goto fail_afsclient_CellOpen;
821 if (cellHandleP == NULL) {
822 tst = ADMCLIENTCELLHANDLEPNULL;
823 goto fail_afsclient_CellOpen;
827 * Check that the token handle contains valid data and the calloc
830 if (!t_handle->afs_token_set) {
831 tst = ADMCLIENTCELLOPENBADTOKEN;
832 goto fail_afsclient_CellOpen;
836 * Use a table to initialize the cell handle structure, since
837 * most of the steps are the same for all the servers.
839 * Start by creating rx_securityClass objects for each of the
840 * servers. A potential optimization is to do this in
841 * afsclient_TokenGetNew and just keep the expiration time of
843 * Also, initialize the ubik client pointers in the table
845 servers[KAS].sc = t_handle->kas_sc[t_handle->sc_index];
846 servers[PTS].sc = t_handle->afs_sc[t_handle->sc_index];
847 servers[VOS].sc = servers[PTS].sc;
848 servers[KAS].ubik = &c_handle->kas;
849 servers[PTS].ubik = &c_handle->pts;
850 servers[VOS].ubik = &c_handle->vos;
851 servers[KAS].valid = &c_handle->kas_valid;
852 servers[PTS].valid = &c_handle->pts_valid;
853 servers[VOS].valid = &c_handle->vos_valid;
854 c_handle->vos_new = 1;
856 if ((servers[PTS].sc == NULL) || (servers[VOS].sc == NULL)) {
857 tst = ADMCLIENTBADTOKENHANDLE;
858 goto fail_afsclient_CellOpen;
862 * If the initialization has succeeded so far, get the address
863 * information for each server in the cell
866 strncpy(c_handle->working_cell, cellName, MAXCELLCHARS);
867 c_handle->working_cell[MAXCELLCHARS - 1] = '\0';
868 if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
869 tst = ADMCLIENTBADCLIENTCONFIG;
870 goto fail_afsclient_CellOpen;
874 * We must copy the cellName here because afsconf_GetCellInfo
875 * actually writes over the cell name it is passed.
877 strncpy(copyCell, cellName, MAXCELLCHARS);
878 copyCell[MAXCELLCHARS - 1] ='\0';
879 for (i = 0; (i < NUM_SERVER_TYPES); i++) {
882 ka_AuthServerConn((char *)cellName, servers[i].serviceId,
883 ((t_handle->sc_index == 0)
885 kas_token_set)) ? 0 : &t_handle->
886 kas_token, servers[i].ubik);
888 goto fail_afsclient_CellOpen;
891 tst = afsconf_GetCellInfo(tdir, copyCell, servers[i].serv, &info);
893 /* create ubik client handles for each server */
894 scIndex = t_handle->sc_index;
895 sc[scIndex] = servers[i].sc;
896 for (j = 0; (j < info.numServers); j++) {
898 rx_GetCachedConnection(info.hostAddr[j].sin_addr.
900 info.hostAddr[j].sin_port,
901 servers[i].serviceId,
902 sc[scIndex], scIndex);
905 tst = ubik_ClientInit(serverconns, servers[i].ubik);
907 goto fail_afsclient_CellOpen;
910 goto fail_afsclient_CellOpen;
913 /* initialization complete, mark handle valid */
914 *servers[i].valid = 1;
916 c_handle->tokens = t_handle;
919 fail_afsclient_CellOpen:
926 * Upon error, free any obtained resources.
929 if (c_handle != NULL) {
930 if (c_handle->kas_valid)
931 ubik_ClientDestroy(c_handle->kas);
932 if (c_handle->pts_valid)
933 ubik_ClientDestroy(c_handle->pts);
934 if (c_handle->vos_valid)
935 ubik_ClientDestroy(c_handle->vos);
939 c_handle->begin_magic = BEGIN_MAGIC;
940 c_handle->is_valid = 1;
941 c_handle->is_null = 0;
942 c_handle->server_list = NULL;
943 c_handle->server_ttl = 0;
944 c_handle->end_magic = END_MAGIC;
945 *cellHandleP = (void *)c_handle;
955 * afsclient_NullCellOpen - open a null cell handle for access.
959 * OUT cellHandleP - an opaque pointer that is the first parameter to
960 * almost all subsequent admin api calls.
964 * No locks are obtained or released by this function
972 * Returns != 0 upon successful completion.
976 afsclient_NullCellOpen(void **cellHandleP, afs_status_p st)
979 afs_status_t tst = 0;
980 afs_cell_handle_p c_handle = (afs_cell_handle_p)
981 calloc(1, sizeof(afs_cell_handle_t));
985 * Validate parameters
988 if (cellHandleP == NULL) {
989 tst = ADMCLIENTCELLHANDLEPNULL;
990 goto fail_afsclient_NullCellOpen;
993 if (client_init == 0) {
994 tst = ADMCLIENTNOINIT;
995 goto fail_afsclient_NullCellOpen;
998 if (c_handle == NULL) {
1000 goto fail_afsclient_NullCellOpen;
1004 * Get unauthenticated tokens for any cell
1007 if (!afsclient_TokenGetNew(0, 0, 0, (void *)&c_handle->tokens, &tst)) {
1008 goto fail_afsclient_NullCellOpen;
1011 c_handle->begin_magic = BEGIN_MAGIC;
1012 c_handle->is_valid = 1;
1013 c_handle->is_null = 1;
1014 c_handle->end_magic = END_MAGIC;
1015 c_handle->kas_valid = 0;
1016 c_handle->pts_valid = 0;
1017 c_handle->vos_valid = 0;
1018 c_handle->kas = NULL;
1019 c_handle->pts = NULL;
1020 c_handle->vos = NULL;
1021 c_handle->server_list = NULL;
1022 c_handle->server_ttl = 0;
1023 *cellHandleP = (void *)c_handle;
1026 fail_afsclient_NullCellOpen:
1035 * afsclient_CellClose - close a previously opened cellHandle.
1039 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
1043 * No locks are obtained or released by this function
1051 * Returns != 0 upon successful completion.
1055 afsclient_CellClose(const void *cellHandle, afs_status_p st)
1058 afs_status_t tst = 0;
1059 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1061 if (client_init == 0) {
1062 tst = ADMCLIENTNOINIT;
1063 goto fail_afsclient_CellClose;
1066 if (c_handle == NULL) {
1067 tst = ADMCLIENTCELLHANDLENULL;
1068 goto fail_afsclient_CellClose;
1071 if (c_handle->server_list)
1072 free(c_handle->server_list);
1073 if (c_handle->kas_valid)
1074 ubik_ClientDestroy(c_handle->kas);
1075 if (c_handle->pts_valid)
1076 ubik_ClientDestroy(c_handle->pts);
1077 if (c_handle->vos_valid)
1078 ubik_ClientDestroy(c_handle->vos);
1079 if (c_handle->is_null)
1080 afsclient_TokenClose(c_handle->tokens, 0);
1081 c_handle->kas_valid = 0;
1082 c_handle->pts_valid = 0;
1083 c_handle->vos_valid = 0;
1084 c_handle->is_valid = 0;
1088 fail_afsclient_CellClose:
1098 * afsclient_CellNameGet() -- get a pointer to the cell name in a cell handle
1102 * IN cellHandle - a valid cell handle
1103 * OUT cellNameP - a pointer to the cell name in the cell handle.
1107 * No locks are obtained or released by this function
1111 * If cellHandle is closed then the pointer returned by this function
1112 * is no longer valid.
1116 * Returns != 0 upon successful completion.
1119 afsclient_CellNameGet(const void *cellHandle, const char **cellNameP,
1123 afs_status_t tst = 0;
1124 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1126 if (!CellHandleIsValid(cellHandle, &tst)) {
1127 goto fail_afsclient_CellNameGet;
1130 *cellNameP = c_handle->working_cell;
1133 fail_afsclient_CellNameGet:
1143 * afsclient_LocalCellGet - get the name of the cell the machine
1144 * belongs to where this process is running.
1148 * OUT cellName - an array of characters that must be MAXCELLCHARS
1153 * No locks are obtained or released by this function
1157 * If cellName is smaller than MAXCELLCHARS chars, this function won't
1162 * Returns != 0 upon successful completion.
1166 afsclient_LocalCellGet(char *cellName, afs_status_p st)
1169 afs_status_t tst = 0;
1170 struct afsconf_dir *tdir = NULL;
1172 if (client_init == 0) {
1173 tst = ADMCLIENTNOINIT;
1174 goto fail_afsclient_LocalCellGet;
1177 if (cellName == NULL) {
1178 tst = ADMCLIENTCELLNAMENULL;
1179 goto fail_afsclient_LocalCellGet;
1182 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1185 tst = ADMCLIENTBADCLIENTCONFIG;
1186 goto fail_afsclient_LocalCellGet;
1189 if ((tst = afsconf_GetLocalCell(tdir, cellName, MAXCELLCHARS))) {
1190 goto fail_afsclient_LocalCellGet;
1195 fail_afsclient_LocalCellGet:
1198 afsconf_Close(tdir);
1211 client_ExtractDriveLetter(char *path)
1215 if (path[0] != 0 && path[1] == ':') {
1224 * Determine the parent directory of a give directory
1228 Parent(char *directory, char *parentDirectory)
1233 strcpy(parentDirectory, directory);
1234 tp = strrchr(parentDirectory, '\\');
1236 /* lv trailing slash so Parent("k:\foo") is "k:\" not "k :" */
1240 if (client_ExtractDriveLetter(parentDirectory)) {
1241 strcat(parentDirectory, ".");
1251 * Determine the parent directory of a give directory
1254 Parent(const char *directory, char *parentDirectory)
1259 strcpy(parentDirectory, directory);
1260 tp = strrchr(parentDirectory, '/');
1265 strcpy(parentDirectory, ".");
1274 * afsclient_MountPointCreate - create a mount point for a volume.
1278 * IN cellHandle - a handle to the cell where volumeName resides.
1280 * IN directory - the directory where the mountpoint should be created.
1282 * IN volumeName - the name of the volume to mount.
1284 * IN volType - the type of mount point to create.
1286 * IN volCheck - indicates whether or not to check the VLDB to see if
1287 * volumeName exists.
1291 * No locks are obtained or released by this function
1295 * Returns != 0 upon successful completion.
1298 #define TMP_DATA_SIZE 2048
1301 afsclient_MountPointCreate(const void *cellHandle, const char *directory,
1302 const char *volumeName, vol_type_t volType,
1303 vol_check_t volCheck, afs_status_p st)
1306 afs_status_t tst = 0;
1307 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1308 char parent_dir[TMP_DATA_SIZE];
1309 char space[TMP_DATA_SIZE];
1310 char directoryCell[MAXCELLCHARS];
1311 struct ViceIoctl idata;
1313 vos_vldbEntry_t vldbEntry;
1316 * Validate arguments
1319 if (client_init == 0) {
1320 tst = ADMCLIENTNOINIT;
1321 goto fail_afsclient_MountPointCreate;
1324 if ((directory == NULL) || (*directory == 0)) {
1325 tst = ADMCLIENTDIRECTORYNULL;
1326 goto fail_afsclient_MountPointCreate;
1329 if ((volumeName == NULL) || (*volumeName == 0)) {
1330 tst = ADMCLIENTVOLUMENAME;
1331 goto fail_afsclient_MountPointCreate;
1335 * Extract the parent directory and make sure it is in AFS.
1338 if (!Parent(directory, parent_dir)) {
1339 tst = ADMCLIENTBADDIRECTORY;
1340 goto fail_afsclient_MountPointCreate;
1344 idata.out_size = TMP_DATA_SIZE;
1346 i = pioctl(parent_dir, VIOC_FILE_CELL_NAME, &idata, 1);
1348 if ((errno == EINVAL) || (errno == ENOENT)) {
1349 tst = ADMCLIENTNOAFSDIRECTORY;
1350 goto fail_afsclient_MountPointCreate;
1353 strcpy(directoryCell, space);
1356 * If the user requested, check that the volume exists
1359 if (volCheck == CHECK_VOLUME) {
1360 if (!vos_VLDBGet(cellHandle, 0, 0, (char *)volumeName, &vldbEntry,
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((char *)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 %1024s", &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, "%63s%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((char *) 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 = malloc(sizeof(afs_admin_iterator_t));
1826 server_get_p serv = calloc(1, sizeof(server_get_t));
1827 server_get_p serv_cache = NULL;
1828 const char *cellName = NULL;
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;
1852 if (c_handle->server_list != NULL && c_handle->server_ttl < time(NULL)) {
1853 serv_cache = c_handle->server_list;
1854 c_handle->server_list = NULL;
1856 UNLOCK_GLOBAL_MUTEX;
1858 if (c_handle->server_list == NULL) {
1859 if (serv_cache == NULL) {
1860 serv_cache = (server_get_p) calloc(1, sizeof(server_get_t));
1862 if (serv_cache == NULL) {
1864 goto fail_afsclient_AFSServerGetBegin;
1869 * Retrieve the list of database servers for this cell.
1872 if (!afsclient_CellNameGet(c_handle, &cellName, &tst)) {
1873 goto fail_afsclient_AFSServerGetBegin;
1876 if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
1877 goto fail_afsclient_AFSServerGetBegin;
1880 while (util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
1881 serv->server[serv->total].serverAddress[0] =
1882 database_entry.serverAddress;
1883 serv->server[serv->total].serverType = DATABASE_SERVER;
1887 if (tst != ADMITERATORDONE) {
1888 util_DatabaseServerGetDone(database_iter, 0);
1889 goto fail_afsclient_AFSServerGetBegin;
1892 if (!util_DatabaseServerGetDone(database_iter, &tst)) {
1893 goto fail_afsclient_AFSServerGetBegin;
1897 * Retrieve the list of file servers for this cell.
1900 if (!vos_FileServerGetBegin(c_handle, 0, &fileserver_iter, &tst)) {
1901 goto fail_afsclient_AFSServerGetBegin;
1904 while (vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
1906 * See if any of the addresses returned in this fileserver_entry
1907 * structure already exist in the list of servers we're building.
1908 * If not, create a new record for this server.
1911 for (iserv = 0; iserv < serv->total; iserv++) {
1912 for (ientryaddr = 0; ientryaddr < fileserver_entry.count; ientryaddr++) {
1913 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS; iservaddr++) {
1914 if (serv->server[iserv].serverAddress[iservaddr] ==
1915 fileserver_entry.serverAddress[ientryaddr]) {
1930 serv->server[iserv].serverType |= FILE_SERVER;
1932 iserv = serv->total++;
1933 serv->server[iserv].serverType = FILE_SERVER;
1937 * Add the addresses from the vldb list to the serv->server[iserv]
1938 * record. Remember that VLDB's list-of-addrs is not guaranteed
1939 * to be unique in a particular entry, or to return only one entry
1940 * per machine--so when we add addresses, always check for
1941 * duplicate entries.
1944 for (ientryaddr = 0; ientryaddr < fileserver_entry.count; ientryaddr++) {
1945 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS; iservaddr++) {
1946 if (serv->server[iserv].serverAddress[iservaddr] ==
1947 fileserver_entry.serverAddress[ientryaddr]) {
1951 if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
1952 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1954 if (!serv->server[iserv].serverAddress[iservaddr]) {
1955 serv->server[iserv].serverAddress[iservaddr] =
1956 fileserver_entry.serverAddress[ientryaddr];
1964 if (tst != ADMITERATORDONE) {
1965 vos_FileServerGetDone(fileserver_iter, 0);
1966 goto fail_afsclient_AFSServerGetBegin;
1969 if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
1970 goto fail_afsclient_AFSServerGetBegin;
1974 * Iterate over the list and fill in the hostname of each of the servers
1977 for (iserv = 0; iserv < serv->total; iserv++) {
1978 int addr = htonl(serv->server[iserv].serverAddress[0]);
1980 host = gethostbyaddr((const char *)&addr, sizeof(int), AF_INET);
1982 strncpy(serv->server[iserv].serverName, host->h_name,
1983 AFS_MAX_SERVER_NAME_LEN);
1984 serv->server[iserv].serverName[AFS_MAX_SERVER_NAME_LEN - 1] = '\0';
1986 UNLOCK_GLOBAL_MUTEX;
1989 memcpy(serv_cache, serv, sizeof(server_get_t));
1993 if (c_handle->server_list == NULL)
1996 memcpy(serv, c_handle->server_list, sizeof(server_get_t));
1997 UNLOCK_GLOBAL_MUTEX;
2003 (iter, (void *)serv, GetServerRPC, GetServerFromCache, NULL, NULL,
2005 *iterationIdP = (void *)iter;
2009 fail_afsclient_AFSServerGetBegin:
2016 if (serv_cache != NULL)
2021 /* in case there was a race and we constructed the list twice */
2022 if (c_handle->server_list)
2023 free(c_handle->server_list);
2025 c_handle->server_list = serv_cache;
2026 c_handle->server_ttl = time(NULL) + SERVER_TTL;
2027 UNLOCK_GLOBAL_MUTEX;
2038 * afsclient_AFSServerGetNext - retrieve the next server in the cell.
2042 * IN iterationId - an iterator previously returned by
2043 * afsclient_AFSServerGetBegin.
2045 * OUT serverEntryP - upon successful completion contains the next server.
2049 * No locks are obtained or released by this function
2057 * Returns != 0 upon successful completion.
2061 afsclient_AFSServerGetNext(void *iterationId, afs_serverEntry_p serverEntryP,
2065 afs_status_t tst = 0;
2066 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2068 if (iterationId == NULL) {
2069 tst = ADMITERATORNULL;
2070 goto fail_afsclient_AFSServerGetNext;
2073 if (serverEntryP == NULL) {
2074 tst = ADMUTILSERVERENTRYPNULL;
2075 goto fail_afsclient_AFSServerGetNext;
2078 rc = IteratorNext(iter, (void *)serverEntryP, &tst);
2080 fail_afsclient_AFSServerGetNext:
2089 * afsclient_AFSServerGetDone - finish using a server iterator.
2093 * IN iterationId - an iterator previously returned by
2094 * afsclient_AFSServerGetBegin.
2098 * No locks are obtained or released by this function
2106 * Returns != 0 upon successful completion.
2110 afsclient_AFSServerGetDone(void *iterationId, afs_status_p st)
2113 afs_status_t tst = 0;
2114 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2116 if (iterationId == NULL) {
2117 tst = ADMITERATORNULL;
2118 goto fail_afsclient_AFSServerGetDone;
2121 rc = IteratorDone(iter, &tst);
2123 fail_afsclient_AFSServerGetDone:
2132 * afsclient_RPCStatOpen - open an rx connection to a server to retrieve
2137 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2139 * IN serverName - the host name where the server resides.
2141 * IN type - what type of process to query
2143 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2147 * No locks are obtained or released by this function
2155 * Returns != 0 upon successful completion.
2159 afsclient_RPCStatOpen(const void *cellHandle, const char *serverName,
2160 afs_stat_source_t type,
2161 struct rx_connection **rpcStatHandleP, afs_status_p st)
2164 afs_status_t tst = 0;
2165 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2168 struct rx_securityClass *sc;
2170 if (!CellHandleIsValid(cellHandle, &tst)) {
2171 goto fail_afsclient_RPCStatOpen;
2174 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2175 goto fail_afsclient_RPCStatOpen;
2178 if (rpcStatHandleP == NULL) {
2179 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2180 goto fail_afsclient_RPCStatOpen;
2186 servPort = AFSCONF_NANNYPORT;
2189 case AFS_FILESERVER:
2190 servPort = AFSCONF_FILEPORT;
2194 servPort = AFSCONF_KAUTHPORT;
2198 servPort = AFSCONF_PROTPORT;
2202 servPort = AFSCONF_VOLUMEPORT;
2206 servPort = AFSCONF_VLDBPORT;
2210 servPort = AFSCONF_CALLBACKPORT;
2214 tst = ADMTYPEINVALID;
2215 goto fail_afsclient_RPCStatOpen;
2219 * special processing of tokens by server type
2222 if (type == AFS_KASERVER) {
2223 if (!c_handle->tokens->kas_token_set) {
2224 tst = ADMCLIENTNOKASTOKENS;
2225 goto fail_afsclient_RPCStatOpen;
2227 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2229 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2233 rx_GetCachedConnection(htonl(servAddr), htons(servPort),
2234 RX_STATS_SERVICE_ID, sc,
2235 c_handle->tokens->sc_index);
2237 if (*rpcStatHandleP == NULL) {
2238 tst = ADMCLIENTRPCSTATNOCONNECTION;
2239 goto fail_afsclient_RPCStatOpen;
2243 fail_afsclient_RPCStatOpen:
2252 * afsclient_RPCStatOpenPort - open an rx connection to a server to retrieve
2257 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2259 * IN serverName - the host name where the server resides.
2261 * IN port - the UDP port number where the server resides.
2263 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2267 * No locks are obtained or released by this function
2275 * Returns != 0 upon successful completion.
2279 afsclient_RPCStatOpenPort(const void *cellHandle, const char *serverName,
2280 const int serverPort,
2281 struct rx_connection **rpcStatHandleP,
2285 afs_status_t tst = 0;
2286 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2288 struct rx_securityClass *sc;
2290 if (!CellHandleIsValid(cellHandle, &tst)) {
2291 goto fail_afsclient_RPCStatOpenPort;
2294 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2295 goto fail_afsclient_RPCStatOpenPort;
2298 if (rpcStatHandleP == NULL) {
2299 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2300 goto fail_afsclient_RPCStatOpenPort;
2304 * special processing of tokens by server type
2307 if (serverPort == AFSCONF_KAUTHPORT) {
2308 if (!c_handle->tokens->kas_token_set) {
2309 tst = ADMCLIENTNOKASTOKENS;
2310 goto fail_afsclient_RPCStatOpenPort;
2312 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2314 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2318 rx_GetCachedConnection(htonl(servAddr), htons(serverPort),
2319 RX_STATS_SERVICE_ID, sc,
2320 c_handle->tokens->sc_index);
2322 if (*rpcStatHandleP == NULL) {
2323 tst = ADMCLIENTRPCSTATNOCONNECTION;
2324 goto fail_afsclient_RPCStatOpenPort;
2328 fail_afsclient_RPCStatOpenPort:
2337 * afsclient_RPCStatClose - close a previously opened rx connection.
2341 * IN rpcStatHandle - an rx connection returned by afsclient_RPCStatOpen
2345 * No locks are obtained or released by this function
2353 * Returns != 0 upon successful completion.
2357 afsclient_RPCStatClose(struct rx_connection *rpcStatHandle, afs_status_p st)
2360 afs_status_t tst = 0;
2362 if (rpcStatHandle == NULL) {
2363 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2364 goto fail_afsclient_RPCStatClose;
2367 rx_ReleaseCachedConnection(rpcStatHandle);
2369 fail_afsclient_RPCStatClose:
2378 * afsclient_CMStatOpen - open an rx connection to a server to retrieve
2383 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2385 * IN serverName - the host name where the server resides.
2387 * OUT cmStatHandleP - contains an rx connection to the server of interest
2391 * No locks are obtained or released by this function
2399 * Returns != 0 upon successful completion.
2403 afsclient_CMStatOpen(const void *cellHandle, const char *serverName,
2404 struct rx_connection **cmStatHandleP, afs_status_p st)
2407 afs_status_t tst = 0;
2408 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2410 struct rx_securityClass *sc;
2412 if (!CellHandleIsValid(cellHandle, &tst)) {
2413 goto fail_afsclient_CMStatOpen;
2416 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2417 goto fail_afsclient_CMStatOpen;
2420 if (cmStatHandleP == NULL) {
2421 tst = ADMCLIENTCMSTATHANDLEPNULL;
2422 goto fail_afsclient_CMStatOpen;
2425 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2428 rx_GetCachedConnection(htonl(servAddr), htons(AFSCONF_CALLBACKPORT),
2429 1, sc, c_handle->tokens->sc_index);
2431 if (*cmStatHandleP == NULL) {
2432 tst = ADMCLIENTCMSTATNOCONNECTION;
2433 goto fail_afsclient_CMStatOpen;
2437 fail_afsclient_CMStatOpen:
2446 * afsclient_CMStatOpenPort - open an rx connection to a server to retrieve
2451 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2453 * IN serverName - the host name where the server resides.
2455 * IN port - the UDP port number where the server resides.
2457 * OUT cmStatHandleP - contains an rx connection to the server of interest
2461 * No locks are obtained or released by this function
2469 * Returns != 0 upon successful completion.
2473 afsclient_CMStatOpenPort(const void *cellHandle, const char *serverName,
2474 const int serverPort,
2475 struct rx_connection **cmStatHandleP,
2479 afs_status_t tst = 0;
2480 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2482 struct rx_securityClass *sc;
2484 if (!CellHandleIsValid(cellHandle, &tst)) {
2485 goto fail_afsclient_CMStatOpenPort;
2488 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2489 goto fail_afsclient_CMStatOpenPort;
2492 if (cmStatHandleP == NULL) {
2493 tst = ADMCLIENTCMSTATHANDLEPNULL;
2494 goto fail_afsclient_CMStatOpenPort;
2497 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2500 rx_GetCachedConnection(htonl(servAddr), htons(serverPort), 1, sc,
2501 c_handle->tokens->sc_index);
2503 if (*cmStatHandleP == NULL) {
2504 tst = ADMCLIENTCMSTATNOCONNECTION;
2505 goto fail_afsclient_CMStatOpenPort;
2509 fail_afsclient_CMStatOpenPort:
2518 * afsclient_CMStatClose - close a previously opened rx connection.
2522 * IN cmStatHandle - an rx connection returned by afsclient_CMStatOpen
2526 * No locks are obtained or released by this function
2534 * Returns != 0 upon successful completion.
2538 afsclient_CMStatClose(struct rx_connection *cmStatHandle, afs_status_p st)
2541 afs_status_t tst = 0;
2543 if (cmStatHandle == NULL) {
2544 tst = ADMCLIENTCMSTATHANDLEPNULL;
2545 goto fail_afsclient_CMStatClose;
2548 rx_ReleaseCachedConnection(cmStatHandle);
2550 fail_afsclient_CMStatClose:
2559 * afsclient_RXDebugOpen - open an rxdebug handle to a server.
2563 * IN serverName - the host name where the server resides.
2565 * IN type - what type of process to query
2567 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2571 * No locks are obtained or released by this function
2579 * Returns != 0 upon successful completion.
2583 afsclient_RXDebugOpen(const char *serverName, afs_stat_source_t type,
2584 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2587 afs_status_t tst = 0;
2589 rxdebugHandle_p handle;
2590 rxdebugSocket_t sock;
2591 struct sockaddr_in taddr;
2595 if (rxdebugHandleP == NULL) {
2596 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2597 goto fail_afsclient_RXDebugOpen;
2603 serverPort = AFSCONF_NANNYPORT;
2606 case AFS_FILESERVER:
2607 serverPort = AFSCONF_FILEPORT;
2611 serverPort = AFSCONF_KAUTHPORT;
2615 serverPort = AFSCONF_PROTPORT;
2619 serverPort = AFSCONF_VOLUMEPORT;
2623 serverPort = AFSCONF_VLDBPORT;
2627 serverPort = AFSCONF_CALLBACKPORT;
2631 tst = ADMTYPEINVALID;
2632 goto fail_afsclient_RXDebugOpen;
2635 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2636 goto fail_afsclient_RXDebugOpen;
2639 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2640 if (sock == INVALID_RXDEBUG_SOCKET) {
2642 goto fail_afsclient_RXDebugOpen;
2645 memset(&taddr, 0, sizeof(taddr));
2646 taddr.sin_family = AF_INET;
2648 taddr.sin_addr.s_addr = INADDR_ANY;
2649 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2653 goto fail_afsclient_RXDebugOpen;
2656 handle = malloc(sizeof(rxdebugHandle_t));
2660 goto fail_afsclient_RXDebugOpen;
2663 handle->sock = sock;
2664 handle->ipAddr = serverAddr;
2665 handle->udpPort = serverPort;
2666 handle->firstFlag = 1;
2667 handle->supportedStats = 0;
2668 *rxdebugHandleP = handle;
2671 fail_afsclient_RXDebugOpen:
2680 * afsclient_RXDebugOpenPort - open an rxdebug handle to a server.
2684 * IN serverName - the host name where the server resides.
2686 * IN port - the UDP port number where the server resides.
2688 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2692 * No locks are obtained or released by this function
2700 * Returns != 0 upon successful completion.
2704 afsclient_RXDebugOpenPort(const char *serverName, int serverPort,
2705 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2708 afs_status_t tst = 0;
2710 rxdebugHandle_p handle;
2711 rxdebugSocket_t sock;
2712 struct sockaddr_in taddr;
2715 if (rxdebugHandleP == NULL) {
2716 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2717 goto fail_afsclient_RXDebugOpenPort;
2720 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2721 goto fail_afsclient_RXDebugOpenPort;
2724 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2725 if (sock == INVALID_RXDEBUG_SOCKET) {
2727 goto fail_afsclient_RXDebugOpenPort;
2730 memset(&taddr, 0, sizeof(taddr));
2731 taddr.sin_family = AF_INET;
2733 taddr.sin_addr.s_addr = INADDR_ANY;
2734 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2738 goto fail_afsclient_RXDebugOpenPort;
2741 handle = malloc(sizeof(rxdebugHandle_t));
2745 goto fail_afsclient_RXDebugOpenPort;
2748 handle->sock = sock;
2749 handle->ipAddr = serverAddr;
2750 handle->udpPort = serverPort;
2751 handle->firstFlag = 1;
2752 handle->supportedStats = 0;
2753 *rxdebugHandleP = handle;
2756 fail_afsclient_RXDebugOpenPort:
2765 * afsclient_RXDebugClose - close a previously opened rxdebug handle.
2769 * IN rxdebugHandle - an rxdebug handle returned by afsclient_RXDebugOpen
2773 * No locks are obtained or released by this function
2781 * Returns != 0 upon successful completion.
2785 afsclient_RXDebugClose(rxdebugHandle_p rxdebugHandle, afs_status_p st)
2788 afs_status_t tst = 0;
2790 if (rxdebugHandle == NULL) {
2791 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2792 goto fail_afsclient_RXDebugClose;
2795 close(rxdebugHandle->sock);
2796 free(rxdebugHandle);
2798 fail_afsclient_RXDebugClose: