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>
27 #define close(x) closesocket(x)
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
33 #include <afs/venus.h>
39 #include <afs/kautils.h>
41 #include <rx/rxstat.h>
42 #include <rx/rx_null.h>
44 #include <afs/dirpath.h>
45 #include <afs/afs_AdminErrors.h>
46 #include <afs/afs_vosAdmin.h>
47 #include <afs/afs_utilAdmin.h>
48 #include <afs/ptserver.h>
49 #include <afs/vlserver.h>
50 #include <afs/pthread_glock.h>
53 * AFS client administration functions.
55 * Admin functions that are normally associated with the client.
57 * All of the functions related to authentication are here, plus
58 * some miscellaneous others.
62 static const unsigned long ADMIN_TICKET_LIFETIME = 24 * 3600;
64 static const unsigned long SERVER_TTL = 10 * 60;
67 * We need a way to track whether or not the client library has been
68 * initialized. We count on the fact that the other library initialization
69 * functions are protected by their own once mechanism. We only track
70 * our own internal status
73 static int client_init;
74 static pthread_once_t client_init_once = PTHREAD_ONCE_INIT;
83 * IsTokenValid - validate a token handle
87 * IN token - the token to be validated.
91 * No locks are obtained or released by this function
99 * Returns != 0 upon successful completion.
103 IsTokenValid(const afs_token_handle_p token, afs_status_p st)
106 afs_status_t tst = 0;
109 tst = ADMCLIENTTOKENHANDLENULL;
110 goto fail_IsTokenValid;
113 if (token->is_valid == 0) {
114 tst = ADMCLIENTTOKENHANDLEINVALID;
115 goto fail_IsTokenValid;
118 if ((token->begin_magic != BEGIN_MAGIC)
119 || (token->end_magic != END_MAGIC)) {
120 tst = ADMCLIENTTOKENHANDLEBADMAGIC;
121 goto fail_IsTokenValid;
134 * afsclient_TokenGetExisting - get tokens that already exist and
135 * are held by the cache manager.
139 * IN cellName - the name of the cell where the token originated.
141 * OUT tokenHandle - a handle to the tokens if they were obtained
146 * No locks are obtained or released by this function
150 * The tokenHandle returned by this function cannot be used for kas
151 * related operations, since kas tokens aren't stored in the kernel.
155 * Returns != 0 upon successful completion.
159 afsclient_TokenGetExisting(const char *cellName, void **tokenHandle,
163 afs_status_t tst = 0;
164 struct ktc_principal afs_server;
165 afs_token_handle_p t_handle =
166 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
168 if (client_init == 0) {
169 tst = ADMCLIENTNOINIT;
170 goto fail_afsclient_TokenGetExisting;
173 if (cellName == NULL) {
174 tst = ADMCLIENTCELLNAMENULL;
175 goto fail_afsclient_TokenGetExisting;
178 if (tokenHandle == NULL) {
179 tst = ADMCLIENTTOKENHANDLENULL;
180 goto fail_afsclient_TokenGetExisting;
183 if (t_handle == NULL) {
185 goto fail_afsclient_TokenGetExisting;
188 strcpy(afs_server.name, "afs");
189 afs_server.instance[0] = 0;
190 strcpy(afs_server.cell, cellName);
194 ktc_GetToken(&afs_server, &t_handle->afs_token,
195 sizeof(t_handle->afs_token), &t_handle->client))) {
197 * The token has been retrieved successfully, initialize
198 * the rest of the token handle structure
200 strncpy(t_handle->cell, cellName, MAXCELLCHARS);
201 t_handle->cell[MAXCELLCHARS - 1] = '\0';
202 t_handle->afs_token_set = 1;
203 t_handle->from_kernel = 1;
204 t_handle->kas_token_set = 0;
205 t_handle->sc_index = 2;
206 t_handle->afs_sc[t_handle->sc_index] =
207 rxkad_NewClientSecurityObject(rxkad_clear,
208 &t_handle->afs_token.sessionKey,
209 t_handle->afs_token.kvno,
210 t_handle->afs_token.ticketLen,
211 t_handle->afs_token.ticket);
212 t_handle->afs_encrypt_sc[t_handle->sc_index] =
213 rxkad_NewClientSecurityObject(rxkad_crypt,
214 &t_handle->afs_token.sessionKey,
215 t_handle->afs_token.kvno,
216 t_handle->afs_token.ticketLen,
217 t_handle->afs_token.ticket);
218 if ((t_handle->afs_sc[t_handle->sc_index] == NULL)
219 || (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
220 tst = ADMCLIENTTOKENHANDLENOSECURITY;
221 goto fail_afsclient_TokenGetExisting;
223 t_handle->begin_magic = BEGIN_MAGIC;
224 t_handle->is_valid = 1;
225 t_handle->end_magic = END_MAGIC;
226 *tokenHandle = (void *)t_handle;
229 goto fail_afsclient_TokenGetExisting;
233 fail_afsclient_TokenGetExisting:
235 if ((rc == 0) && (t_handle != NULL)) {
245 * afsclient_TokenSet - set the tokens represented by tokenHandle to be
246 * active in the kernel (aka ka_SetToken).
250 * IN cellName - the name of the cell where the token originated.
252 * OUT tokenHandle - a handle to the tokens if they were obtained
257 * No locks are obtained or released by this function
261 * The tokenHandle returned by this function cannot be used for kas
262 * related operations, since kas tokens aren't stored in the kernel.
266 * Returns != 0 upon successful completion.
270 afsclient_TokenSet(const void *tokenHandle, afs_status_p st)
273 afs_status_t tst = 0;
274 struct ktc_principal afs_server;
275 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
277 if (!IsTokenValid(t_handle, &tst)) {
278 goto fail_afsclient_TokenSet;
281 strcpy(afs_server.name, "afs");
282 afs_server.instance[0] = 0;
283 strcpy(afs_server.cell, t_handle->cell);
286 ktc_SetToken(&afs_server, &t_handle->afs_token, &t_handle->client, 0);
292 fail_afsclient_TokenSet:
301 * GetKASToken - get a KAS token and store it in the tokenHandle.
305 * IN cellName - the name of the cell where the token should be obtained.
307 * IN principal - the name of the user of the token.
309 * IN password - the password for the principal.
311 * OUT tokenHandle - a handle to the tokens if they were obtained
316 * No locks are obtained or released by this function
324 * Returns != 0 upon successful completion.
328 GetKASToken(const char *cellName, const char *principal, const char *password,
329 afs_token_handle_p tokenHandle, afs_status_p st)
332 afs_status_t tst = 0;
333 struct ubik_client *unauth_conn;
335 struct ktc_encryptionKey key;
336 struct ktc_token *token;
337 unsigned long now = time(0);
338 char name[MAXKTCNAMELEN];
339 char inst[MAXKTCNAMELEN];
340 int have_server_conn = 0;
342 token = &tokenHandle->kas_token;
344 ka_StringToKey((char *)password, (char *)cellName, &key);
347 * Get an unauthenticated connection in the right cell to use for
348 * retrieving the token.
352 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
355 goto fail_GetKASToken;
357 have_server_conn = 1;
359 tst = ka_ParseLoginName((char *)principal, name, inst, NULL);
361 goto fail_GetKASToken;
365 ka_Authenticate(name, inst, (char *)cellName, unauth_conn,
366 KA_MAINTENANCE_SERVICE, &key, now,
367 now + ADMIN_TICKET_LIFETIME, token, &expire);
369 goto fail_GetKASToken;
375 if (have_server_conn) {
376 ubik_ClientDestroy(unauth_conn);
386 * GetAFSToken - get a AFS token and store it in the tokenHandle.
390 * IN cellName - the name of the cell where the token should be obtained.
392 * IN principal - the name of the user of the token.
394 * IN password - the password for the principal.
396 * OUT tokenHandle - a handle to the tokens if they were obtained
401 * No locks are obtained or released by this function
409 * Returns != 0 upon successful completion.
413 GetAFSToken(const char *cellName, const char *principal, const char *password,
414 afs_token_handle_p tokenHandle, afs_status_p st)
417 afs_status_t tst = 0;
418 struct ubik_client *unauth_conn = NULL, *auth_conn = NULL;
420 struct ktc_encryptionKey key;
421 struct ktc_token auth_token;
422 struct ktc_token *token;
423 unsigned long now = time(0);
425 token = &tokenHandle->afs_token;
427 ka_StringToKey((char *)password, (char *)cellName, &key);
430 * Get an unauthenticated connection in the right cell to use for
431 * retrieving the token.
435 ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
438 goto fail_GetAFSToken;
442 ka_ParseLoginName((char *)principal, tokenHandle->client.name,
443 tokenHandle->client.instance, NULL);
445 goto fail_GetAFSToken;
449 ka_Authenticate(tokenHandle->client.name,
450 tokenHandle->client.instance, (char *)cellName,
451 unauth_conn, KA_TICKET_GRANTING_SERVICE, &key, now,
452 now + ADMIN_TICKET_LIFETIME, &auth_token, &expire);
454 goto fail_GetAFSToken;
458 ka_AuthServerConn((char *)cellName, KA_TICKET_GRANTING_SERVICE, 0,
461 goto fail_GetAFSToken;
465 ka_CellToRealm((char *)cellName, tokenHandle->client.cell, (int *)0);
467 goto fail_GetAFSToken;
471 ka_GetToken("afs", "", (char *)cellName, tokenHandle->client.name,
472 tokenHandle->client.instance, auth_conn, now,
473 now + ADMIN_TICKET_LIFETIME, &auth_token,
474 tokenHandle->client.cell, token);
476 goto fail_GetAFSToken;
483 ubik_ClientDestroy(auth_conn);
487 ubik_ClientDestroy(unauth_conn);
498 * afsclient_TokenGetNew - get new tokens for a user and store them
499 * in the tokenHandle.
503 * IN cellName - the name of the cell where the tokens should be obtained.
505 * IN principal - the name of the user of the tokens.
507 * IN password - the password for the principal.
509 * OUT tokenHandle - a handle to the tokens if they were obtained
514 * No locks are obtained or released by this function
522 * Returns != 0 upon successful completion.
526 afsclient_TokenGetNew(const char *cellName, const char *principal,
527 const char *password, void **tokenHandle,
531 afs_status_t tst = 0;
532 afs_token_handle_p t_handle =
533 (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
535 if (client_init == 0) {
536 tst = ADMCLIENTNOINIT;
537 goto fail_afsclient_TokenGetNew;
540 if (t_handle == NULL) {
542 goto fail_afsclient_TokenGetNew;
546 * Check to see if the principal or password is missing. If it is,
547 * get unauthenticated tokens for the cell
550 if ((principal == NULL) || (*principal == 0) || (password == NULL)
551 || (*password == 0)) {
552 t_handle->from_kernel = 0;
553 t_handle->afs_token_set = 1;
554 t_handle->kas_token_set = 1;
555 t_handle->sc_index = 0;
556 t_handle->afs_sc[t_handle->sc_index] =
557 rxnull_NewClientSecurityObject();
558 t_handle->afs_encrypt_sc[t_handle->sc_index] =
559 rxnull_NewClientSecurityObject();
560 t_handle->kas_sc[t_handle->sc_index] =
561 rxnull_NewClientSecurityObject();
562 t_handle->begin_magic = BEGIN_MAGIC;
563 t_handle->is_valid = 1;
564 t_handle->afs_token.endTime = 0;
565 t_handle->end_magic = END_MAGIC;
566 *tokenHandle = (void *)t_handle;
571 * create an authenticated token
574 if ((GetAFSToken(cellName, principal, password, t_handle, &tst))
575 && (GetKASToken(cellName, principal, password, t_handle, &tst))) {
576 strncpy(t_handle->cell, cellName, MAXCELLCHARS);
577 t_handle->cell[MAXCELLCHARS - 1] = '\0';
578 t_handle->from_kernel = 0;
579 t_handle->afs_token_set = 1;
580 t_handle->kas_token_set = 1;
581 t_handle->sc_index = 2;
582 t_handle->afs_sc[t_handle->sc_index] =
583 rxkad_NewClientSecurityObject(rxkad_clear,
584 &t_handle->afs_token.sessionKey,
585 t_handle->afs_token.kvno,
586 t_handle->afs_token.ticketLen,
587 t_handle->afs_token.ticket);
588 t_handle->afs_encrypt_sc[t_handle->sc_index] =
589 rxkad_NewClientSecurityObject(rxkad_crypt,
590 &t_handle->afs_token.sessionKey,
591 t_handle->afs_token.kvno,
592 t_handle->afs_token.ticketLen,
593 t_handle->afs_token.ticket);
594 t_handle->kas_sc[t_handle->sc_index] =
595 rxkad_NewClientSecurityObject(rxkad_crypt,
596 &t_handle->kas_token.sessionKey,
597 t_handle->kas_token.kvno,
598 t_handle->kas_token.ticketLen,
599 t_handle->kas_token.ticket);
600 if ((t_handle->afs_sc[t_handle->sc_index] != NULL)
601 && (t_handle->afs_encrypt_sc[t_handle->sc_index] != NULL)
602 && (t_handle->kas_sc[t_handle->sc_index] != NULL)) {
603 t_handle->begin_magic = BEGIN_MAGIC;
604 t_handle->is_valid = 1;
605 t_handle->end_magic = END_MAGIC;
606 *tokenHandle = (void *)t_handle;
608 tst = ADMCLIENTTOKENHANDLENOSECURITY;
609 goto fail_afsclient_TokenGetNew;
612 goto fail_afsclient_TokenGetNew;
617 fail_afsclient_TokenGetNew:
619 if ((rc == 0) && (t_handle != NULL)) {
630 * afsclient_TokenQuery - get the expiration time of the tokens.
634 * IN tokenHandle - a previously obtained valid token.
636 * OUT expirationDateP - the time at which the tokens expire.
638 * OUT principal - the owning principal
640 * OUT instance - principal instance if it exists.
642 * OUT cell - the principal's cell
644 * OUT hasKasTokens - set to 1 if the token handle contains kas tokens.
648 * No locks are obtained or released by this function
652 * We only check the AFS tokens since we always get these. The
653 * KAS tokens may expirer later than the AFS tokens, but this
654 * difference is minor and reporting an earlier time won't cause
659 * Returns != 0 upon successful completion.
663 afsclient_TokenQuery(void *tokenHandle, unsigned long *expirationDateP,
664 char *principal, char *instance, char *cell,
665 int *hasKasTokens, afs_status_p st)
668 afs_status_t tst = 0;
669 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
671 if (client_init == 0) {
672 tst = ADMCLIENTNOINIT;
674 goto fail_afsclient_TokenQuery;
677 if (IsTokenValid(t_handle, &tst)) {
678 if (principal != NULL) {
679 strcpy(principal, t_handle->client.name);
681 if (instance != NULL) {
682 strcpy(instance, t_handle->client.instance);
685 strcpy(cell, t_handle->client.cell);
687 if (hasKasTokens != NULL) {
688 *hasKasTokens = t_handle->kas_token_set;
690 if (expirationDateP != NULL) {
691 *expirationDateP = t_handle->afs_token.endTime;
696 fail_afsclient_TokenQuery:
705 * afsclient_TokenClose - close an existing token.
709 * IN token - the token to be closed.
713 * No locks are obtained or released by this function
721 * Returns != 0 upon successful completion.
725 afsclient_TokenClose(const void *tokenHandle, afs_status_p st)
728 afs_status_t tst = 0;
729 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
731 if (client_init == 0) {
732 tst = ADMCLIENTNOINIT;
733 goto fail_afsclient_TokenClose;
736 if (IsTokenValid(t_handle, &tst)) {
737 t_handle->is_valid = 0;
742 fail_afsclient_TokenClose:
750 #define NUM_SERVER_TYPES 3
752 /* must match NUM_SERVER_TYPES */
753 typedef enum { KAS, PTS, VOS } afs_server_list_t;
755 typedef struct afs_server {
758 struct ubik_client **ubik;
759 struct rx_securityClass *sc;
761 } afs_server_t, *afs_server_p;
764 * afsclient_CellOpen - Open a particular cell for work as a particular
769 * IN cellName - the cell where future admin calls will be made.
771 * IN tokenHandle - the tokens work will be done under.
773 * OUT cellHandleP - an opaque pointer that is the first parameter to
774 * almost all subsequent admin api calls.
778 * No locks are obtained or released by this function
786 * Returns != 0 upon successful completion.
790 afsclient_CellOpen(const char *cellName, const void *tokenHandle,
791 void **cellHandleP, afs_status_p st)
794 afs_status_t tst = 0;
795 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
796 afs_cell_handle_p c_handle = (afs_cell_handle_p)
797 calloc(1, sizeof(afs_cell_handle_t));
798 struct afsconf_dir *tdir = NULL;
799 struct afsconf_cell info;
800 struct rx_connection *serverconns[MAXSERVERS];
802 struct rx_securityClass *sc[3];
804 char copyCell[MAXCELLCHARS];
806 afs_server_t servers[NUM_SERVER_TYPES]
807 = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
808 {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
809 {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}
812 if (client_init == 0) {
813 tst = ADMCLIENTNOINIT;
814 goto fail_afsclient_CellOpen;
817 if (c_handle == NULL) {
819 goto fail_afsclient_CellOpen;
822 if (t_handle == NULL) {
823 tst = ADMCLIENTTOKENHANDLENULL;
824 goto fail_afsclient_CellOpen;
827 if ((cellName == NULL) || (*cellName == 0)) {
828 tst = ADMCLIENTCELLNAMENULL;
829 goto fail_afsclient_CellOpen;
832 if (cellHandleP == NULL) {
833 tst = ADMCLIENTCELLHANDLEPNULL;
834 goto fail_afsclient_CellOpen;
838 * Check that the token handle contains valid data and the calloc
841 if (!t_handle->afs_token_set) {
842 tst = ADMCLIENTCELLOPENBADTOKEN;
843 goto fail_afsclient_CellOpen;
847 * Use a table to initialize the cell handle structure, since
848 * most of the steps are the same for all the servers.
850 * Start by creating rx_securityClass objects for each of the
851 * servers. A potential optimization is to do this in
852 * afsclient_TokenGetNew and just keep the expiration time of
854 * Also, initialize the ubik client pointers in the table
856 servers[KAS].sc = t_handle->kas_sc[t_handle->sc_index];
857 servers[PTS].sc = t_handle->afs_sc[t_handle->sc_index];
858 servers[VOS].sc = servers[PTS].sc;
859 servers[KAS].ubik = &c_handle->kas;
860 servers[PTS].ubik = &c_handle->pts;
861 servers[VOS].ubik = &c_handle->vos;
862 servers[KAS].valid = &c_handle->kas_valid;
863 servers[PTS].valid = &c_handle->pts_valid;
864 servers[VOS].valid = &c_handle->vos_valid;
865 c_handle->vos_new = 1;
867 if ((servers[PTS].sc == NULL) || (servers[VOS].sc == NULL)) {
868 tst = ADMCLIENTBADTOKENHANDLE;
869 goto fail_afsclient_CellOpen;
873 * If the initialization has succeeded so far, get the address
874 * information for each server in the cell
877 strncpy(c_handle->working_cell, cellName, MAXCELLCHARS);
878 c_handle->working_cell[MAXCELLCHARS - 1] = '\0';
879 if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
880 tst = ADMCLIENTBADCLIENTCONFIG;
881 goto fail_afsclient_CellOpen;
885 * We must copy the cellName here because afsconf_GetCellInfo
886 * actually writes over the cell name it is passed.
888 strncpy(copyCell, cellName, MAXCELLCHARS);
889 copyCell[MAXCELLCHARS - 1] ='\0';
890 for (i = 0; (i < NUM_SERVER_TYPES); i++) {
893 ka_AuthServerConn((char *)cellName, servers[i].serviceId,
894 ((t_handle->sc_index == 0)
896 kas_token_set)) ? 0 : &t_handle->
897 kas_token, servers[i].ubik);
899 goto fail_afsclient_CellOpen;
902 tst = afsconf_GetCellInfo(tdir, copyCell, servers[i].serv, &info);
904 /* create ubik client handles for each server */
905 scIndex = t_handle->sc_index;
906 sc[scIndex] = servers[i].sc;
907 for (j = 0; (j < info.numServers); j++) {
909 rx_GetCachedConnection(info.hostAddr[j].sin_addr.
911 info.hostAddr[j].sin_port,
912 servers[i].serviceId,
913 sc[scIndex], scIndex);
916 tst = ubik_ClientInit(serverconns, servers[i].ubik);
918 goto fail_afsclient_CellOpen;
921 goto fail_afsclient_CellOpen;
924 /* initialization complete, mark handle valid */
925 *servers[i].valid = 1;
927 c_handle->tokens = t_handle;
930 fail_afsclient_CellOpen:
937 * Upon error, free any obtained resources.
940 if (c_handle != NULL) {
941 if (c_handle->kas_valid)
942 ubik_ClientDestroy(c_handle->kas);
943 if (c_handle->pts_valid)
944 ubik_ClientDestroy(c_handle->pts);
945 if (c_handle->vos_valid)
946 ubik_ClientDestroy(c_handle->vos);
950 c_handle->begin_magic = BEGIN_MAGIC;
951 c_handle->is_valid = 1;
952 c_handle->is_null = 0;
953 c_handle->server_list = NULL;
954 c_handle->server_ttl = 0;
955 c_handle->end_magic = END_MAGIC;
956 *cellHandleP = (void *)c_handle;
966 * afsclient_NullCellOpen - open a null cell handle for access.
970 * OUT cellHandleP - an opaque pointer that is the first parameter to
971 * almost all subsequent admin api calls.
975 * No locks are obtained or released by this function
983 * Returns != 0 upon successful completion.
987 afsclient_NullCellOpen(void **cellHandleP, afs_status_p st)
990 afs_status_t tst = 0;
991 afs_cell_handle_p c_handle = (afs_cell_handle_p)
992 calloc(1, sizeof(afs_cell_handle_t));
996 * Validate parameters
999 if (cellHandleP == NULL) {
1000 tst = ADMCLIENTCELLHANDLEPNULL;
1001 goto fail_afsclient_NullCellOpen;
1004 if (client_init == 0) {
1005 tst = ADMCLIENTNOINIT;
1006 goto fail_afsclient_NullCellOpen;
1009 if (c_handle == NULL) {
1011 goto fail_afsclient_NullCellOpen;
1015 * Get unauthenticated tokens for any cell
1018 if (!afsclient_TokenGetNew(0, 0, 0, (void *)&c_handle->tokens, &tst)) {
1019 goto fail_afsclient_NullCellOpen;
1022 c_handle->begin_magic = BEGIN_MAGIC;
1023 c_handle->is_valid = 1;
1024 c_handle->is_null = 1;
1025 c_handle->end_magic = END_MAGIC;
1026 c_handle->kas_valid = 0;
1027 c_handle->pts_valid = 0;
1028 c_handle->vos_valid = 0;
1029 c_handle->kas = NULL;
1030 c_handle->pts = NULL;
1031 c_handle->vos = NULL;
1032 c_handle->server_list = NULL;
1033 c_handle->server_ttl = 0;
1034 *cellHandleP = (void *)c_handle;
1037 fail_afsclient_NullCellOpen:
1046 * afsclient_CellClose - close a previously opened cellHandle.
1050 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
1054 * No locks are obtained or released by this function
1062 * Returns != 0 upon successful completion.
1066 afsclient_CellClose(const void *cellHandle, afs_status_p st)
1069 afs_status_t tst = 0;
1070 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1072 if (client_init == 0) {
1073 tst = ADMCLIENTNOINIT;
1074 goto fail_afsclient_CellClose;
1077 if (c_handle == NULL) {
1078 tst = ADMCLIENTCELLHANDLENULL;
1079 goto fail_afsclient_CellClose;
1082 if (c_handle->server_list)
1083 free(c_handle->server_list);
1084 if (c_handle->kas_valid)
1085 ubik_ClientDestroy(c_handle->kas);
1086 if (c_handle->pts_valid)
1087 ubik_ClientDestroy(c_handle->pts);
1088 if (c_handle->vos_valid)
1089 ubik_ClientDestroy(c_handle->vos);
1090 if (c_handle->is_null)
1091 afsclient_TokenClose(c_handle->tokens, 0);
1092 c_handle->kas_valid = 0;
1093 c_handle->pts_valid = 0;
1094 c_handle->vos_valid = 0;
1095 c_handle->is_valid = 0;
1099 fail_afsclient_CellClose:
1109 * afsclient_CellNameGet() -- get a pointer to the cell name in a cell handle
1113 * IN cellHandle - a valid cell handle
1114 * OUT cellNameP - a pointer to the cell name in the cell handle.
1118 * No locks are obtained or released by this function
1122 * If cellHandle is closed then the pointer returned by this function
1123 * is no longer valid.
1127 * Returns != 0 upon successful completion.
1130 afsclient_CellNameGet(const void *cellHandle, const char **cellNameP,
1134 afs_status_t tst = 0;
1135 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1137 if (!CellHandleIsValid(cellHandle, &tst)) {
1138 goto fail_afsclient_CellNameGet;
1141 *cellNameP = c_handle->working_cell;
1144 fail_afsclient_CellNameGet:
1154 * afsclient_LocalCellGet - get the name of the cell the machine
1155 * belongs to where this process is running.
1159 * OUT cellName - an array of characters that must be MAXCELLCHARS
1164 * No locks are obtained or released by this function
1168 * If cellName is smaller than MAXCELLCHARS chars, this function won't
1173 * Returns != 0 upon successful completion.
1177 afsclient_LocalCellGet(char *cellName, afs_status_p st)
1180 afs_status_t tst = 0;
1181 struct afsconf_dir *tdir = NULL;
1183 if (client_init == 0) {
1184 tst = ADMCLIENTNOINIT;
1185 goto fail_afsclient_LocalCellGet;
1188 if (cellName == NULL) {
1189 tst = ADMCLIENTCELLNAMENULL;
1190 goto fail_afsclient_LocalCellGet;
1193 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1196 tst = ADMCLIENTBADCLIENTCONFIG;
1197 goto fail_afsclient_LocalCellGet;
1200 if ((tst = afsconf_GetLocalCell(tdir, cellName, MAXCELLCHARS))) {
1201 goto fail_afsclient_LocalCellGet;
1206 fail_afsclient_LocalCellGet:
1209 afsconf_Close(tdir);
1222 client_ExtractDriveLetter(char *path)
1226 if (path[0] != 0 && path[1] == ':') {
1235 * Determine the parent directory of a give directory
1239 Parent(char *directory, char *parentDirectory)
1244 strcpy(parentDirectory, directory);
1245 tp = strrchr(parentDirectory, '\\');
1247 /* lv trailing slash so Parent("k:\foo") is "k:\" not "k :" */
1251 if (client_ExtractDriveLetter(parentDirectory)) {
1252 strcat(parentDirectory, ".");
1262 * Determine the parent directory of a give directory
1265 Parent(const char *directory, char *parentDirectory)
1270 strcpy(parentDirectory, directory);
1271 tp = strrchr(parentDirectory, '/');
1276 strcpy(parentDirectory, ".");
1285 * afsclient_MountPointCreate - create a mount point for a volume.
1289 * IN cellHandle - a handle to the cell where volumeName resides.
1291 * IN directory - the directory where the mountpoint should be created.
1293 * IN volumeName - the name of the volume to mount.
1295 * IN volType - the type of mount point to create.
1297 * IN volCheck - indicates whether or not to check the VLDB to see if
1298 * volumeName exists.
1302 * No locks are obtained or released by this function
1306 * Returns != 0 upon successful completion.
1309 #define TMP_DATA_SIZE 2048
1312 afsclient_MountPointCreate(const void *cellHandle, const char *directory,
1313 const char *volumeName, vol_type_t volType,
1314 vol_check_t volCheck, afs_status_p st)
1317 afs_status_t tst = 0;
1318 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1319 char parent_dir[TMP_DATA_SIZE];
1320 char space[TMP_DATA_SIZE];
1321 char directoryCell[MAXCELLCHARS];
1322 struct ViceIoctl idata;
1324 vos_vldbEntry_t vldbEntry;
1327 * Validate arguments
1330 if (client_init == 0) {
1331 tst = ADMCLIENTNOINIT;
1332 goto fail_afsclient_MountPointCreate;
1335 if ((directory == NULL) || (*directory == 0)) {
1336 tst = ADMCLIENTDIRECTORYNULL;
1337 goto fail_afsclient_MountPointCreate;
1340 if ((volumeName == NULL) || (*volumeName == 0)) {
1341 tst = ADMCLIENTVOLUMENAME;
1342 goto fail_afsclient_MountPointCreate;
1346 * Extract the parent directory and make sure it is in AFS.
1349 if (!Parent(directory, parent_dir)) {
1350 tst = ADMCLIENTBADDIRECTORY;
1351 goto fail_afsclient_MountPointCreate;
1355 idata.out_size = TMP_DATA_SIZE;
1357 i = pioctl(parent_dir, VIOC_FILE_CELL_NAME, &idata, 1);
1359 if ((errno == EINVAL) || (errno == ENOENT)) {
1360 tst = ADMCLIENTNOAFSDIRECTORY;
1361 goto fail_afsclient_MountPointCreate;
1364 strcpy(directoryCell, space);
1367 * If the user requested, check that the volume exists
1370 if (volCheck == CHECK_VOLUME) {
1371 if (!vos_VLDBGet(cellHandle, 0, 0, volumeName, &vldbEntry, &tst)) {
1372 goto fail_afsclient_MountPointCreate;
1377 * Begin constructing the pioctl buffer
1380 if (volType == READ_WRITE) {
1387 * Append the cell to the mount point if the volume is in a different
1388 * cell than the directory
1391 if (strcmp(c_handle->working_cell, directoryCell)) {
1392 strcat(space, c_handle->working_cell);
1395 strcat(space, volumeName);
1402 idata.in_size = 1 + strlen(space);
1404 if (tst = pioctl(directory, VIOC_AFS_CREATE_MT_PT, &idata, 0)) {
1405 goto fail_afsclient_MountPointCreate;
1408 if ((tst = symlink(space, directory))) {
1409 goto fail_afsclient_MountPointCreate;
1415 fail_afsclient_MountPointCreate:
1423 typedef struct Acl {
1431 afsclient_ACLEntryAdd(const char *directory, const char *user,
1432 const acl_p acl, afs_status_p st)
1435 afs_status_t tst = 0;
1436 struct ViceIoctl idata;
1437 char old_acl_string[2048];
1438 char new_acl_string[2048];
1443 int cur_user_acl = 0;
1448 if (client_init == 0) {
1449 tst = ADMCLIENTNOINIT;
1450 goto fail_afsclient_ACLEntryAdd;
1453 if ((directory == NULL) || (*directory == 0)) {
1454 tst = ADMMISCDIRECTORYNULL;
1455 goto fail_afsclient_ACLEntryAdd;
1458 if ((user == NULL) || (*user == 0)) {
1459 tst = ADMMISCUSERNULL;
1460 goto fail_afsclient_ACLEntryAdd;
1464 tst = ADMMISCACLNULL;
1465 goto fail_afsclient_ACLEntryAdd;
1468 if (acl->read == READ) {
1472 if (acl->write == WRITE) {
1476 if (acl->insert == INSERT) {
1480 if (acl->lookup == LOOKUP) {
1484 if (acl->del == DELETE) {
1488 if (acl->lock == LOCK) {
1492 if (acl->admin == ADMIN) {
1497 * Get the current acl for the directory
1500 idata.out_size = 2048;
1502 idata.in = idata.out = old_acl_string;
1503 tst = pioctl(directory, VIOCGETAL, &idata, 1);
1506 goto fail_afsclient_ACLEntryAdd;
1510 * The acl is presented to us in string format. The format of the
1513 * A header which contains the number of positive and negative entries
1514 * and a string indicating whether or not this is a dfs acl:
1516 * num_pos "\n" dfs_string "\n" num_neg
1518 * An entry for each acl that's of the form:
1522 * There are no blanks in the string between fields, but I use them here
1523 * to make the reading easier.
1525 * Since we are only going to add another entry to the acl, our approach
1526 * is simple. Get the num_pos dfs_string and num_neg from the current acl,
1527 * increment num_pos by one and create a new string. Concatenate the new
1528 * user and rights to the new string, and then concatenate the remaining
1529 * contents of the old acl to the new string.
1531 * Unfortunately, this approach doesn't work since the format the kernel
1532 * hands the acl back to us in, is NOT WHAT IT WANTS BACK!!!!
1533 * So instead we need to parse the entire freaking acl and put a space
1534 * between each user and their acl.
1536 * This is really ugly.
1540 * Parse the first few fields of the acl and see if this is a DFS
1545 sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs,
1547 ptr = strchr(old_acl_string, '\n');
1549 sscanf(ptr, "%d", &cur_acl.nminus);
1550 ptr = strchr(ptr, '\n');
1553 tst = ADMMISCNODFSACL;
1554 goto fail_afsclient_ACLEntryAdd;
1557 * It isn't a DFS file, so create the beginning of the string
1558 * we will hand back to the kernel
1560 sprintf(new_acl_string, "%d\n%d\n%s %d\n", (cur_acl.nplus + 1),
1561 cur_acl.nminus, user, newacl);
1565 * Finish scanning the old acl, parsing each user/acl pair and
1566 * adding a space in the new acl.
1569 for (i = 0; i < (cur_acl.nplus + cur_acl.nminus); i++) {
1570 sscanf(ptr, "%s%d\n", cur_user, &cur_user_acl);
1572 * Skip the entry for the user we are replacing/adding
1575 if (strcmp(cur_user, user)) {
1576 ptr = strchr(ptr, '\n');
1578 sprintf(tmp, "%s %d\n", cur_user, cur_user_acl);
1579 strcat(new_acl_string, tmp);
1583 strcat(new_acl_string, ptr);
1590 idata.in_size = strlen(new_acl_string) + 1;
1591 idata.in = idata.out = new_acl_string;
1592 tst = pioctl(directory, VIOCSETAL, &idata, 1);
1595 goto fail_afsclient_ACLEntryAdd;
1599 fail_afsclient_ACLEntryAdd:
1608 * afsclient_Init - initialize AFS components before use.
1614 * No locks are obtained or released by this function
1622 * Returns != 0 upon successful completion.
1626 afsclient_Init(afs_status_p st)
1629 afs_status_t tst = 0;
1632 pthread_once(&client_init_once, client_once);
1635 if (afs_winsockInit() < 0) {
1636 tst = ADMCLIENTCANTINITWINSOCK;
1637 goto fail_afsclient_Init;
1641 if (!(initAFSDirPath() & AFSDIR_CLIENT_PATHS_OK)) {
1642 tst = ADMCLIENTCANTINITAFSLOCATION;
1643 goto fail_afsclient_Init;
1646 if (rx_Init(0) < 0) {
1647 tst = ADMCLIENTCANTINITRX;
1648 goto fail_afsclient_Init;
1651 if ((tst = ka_CellConfig((char *)AFSDIR_CLIENT_ETC_DIRPATH))) {
1652 goto fail_afsclient_Init;
1657 fail_afsclient_Init:
1666 * afsclient_AFSServerGet - determine what kind of server serverName
1667 * is and fill in serverEntryP accordingly.
1671 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1673 * IN serverName - the hostname of the server of interest.
1675 * OUT serverEntryP - upon successful completion contains a description of
1680 * No locks are obtained or released by this function
1688 * Returns != 0 upon successful completion.
1692 afsclient_AFSServerGet(const void *cellHandle, const char *serverName,
1693 afs_serverEntry_p serverEntryP, afs_status_p st)
1696 afs_status_t tst = 0;
1698 int found_match = 0;
1700 if ((serverName == NULL) || (*serverName == 0)) {
1701 tst = ADMUTILSERVERNAMENULL;
1702 goto fail_afsclient_AFSServerGet;
1705 if (serverEntryP == NULL) {
1706 tst = ADMUTILSERVERENTRYPNULL;
1707 goto fail_afsclient_AFSServerGet;
1711 * Iterate over server entries and try to find a match for serverName
1714 if (!afsclient_AFSServerGetBegin(cellHandle, &iter, &tst)) {
1715 goto fail_afsclient_AFSServerGet;
1718 while (afsclient_AFSServerGetNext(iter, serverEntryP, &tst)) {
1719 if (!strcmp(serverName, serverEntryP->serverName)) {
1726 * If we didn't find a match, the iterator should have terminated
1727 * normally. If it didn't, return the error
1731 if (tst != ADMITERATORDONE) {
1732 afsclient_AFSServerGetDone(iter, 0);
1734 afsclient_AFSServerGetDone(iter, &tst);
1736 tst = ADMCLIENTNOMATCHINGSERVER;
1737 goto fail_afsclient_AFSServerGet;
1739 if (!afsclient_AFSServerGetDone(iter, &tst)) {
1740 goto fail_afsclient_AFSServerGet;
1745 fail_afsclient_AFSServerGet:
1754 * The iterator functions and data for the server retrieval functions
1757 typedef struct server_get {
1760 afs_serverEntry_t server[MAXHOSTSPERCELL + BADSERVERID];
1761 afs_serverEntry_t cache[CACHED_ITEMS];
1762 } server_get_t, *server_get_p;
1765 GetServerRPC(void *rpc_specific, int slot, int *last_item,
1766 int *last_item_contains_data, afs_status_p st)
1769 afs_status_t tst = 0;
1770 server_get_p serv = (server_get_p) rpc_specific;
1772 memcpy(&serv->cache[slot], &serv->server[serv->index],
1773 sizeof(afs_serverEntry_t));
1776 if (serv->index == serv->total) {
1778 *last_item_contains_data = 1;
1789 GetServerFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
1792 afs_status_t tst = 0;
1793 server_get_p serv = (server_get_p) rpc_specific;
1795 memcpy(dest, (const void *)&serv->cache[slot], sizeof(afs_serverEntry_t));
1805 * afsclient_AFSServerGetBegin - start the process of iterating over
1806 * every server in the cell.
1810 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1812 * OUT iterationIdP - - upon successful completion contains an iterator
1813 * that can be passed to afsclient_AFSServerGetNext.
1817 * No locks are obtained or released by this function
1825 * Returns != 0 upon successful completion.
1829 afsclient_AFSServerGetBegin(const void *cellHandle, void **iterationIdP,
1833 afs_status_t tst = 0;
1834 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1835 afs_admin_iterator_p iter =
1836 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1837 server_get_p serv = (server_get_p) calloc(1, sizeof(server_get_t));
1838 server_get_p serv_cache = NULL;
1839 const char *cellName = NULL;
1840 void *database_iter;
1841 util_databaseServerEntry_t database_entry;
1842 void *fileserver_iter;
1843 vos_fileServerEntry_t fileserver_entry;
1844 int iserv, iservaddr, ientryaddr, is_dup;
1845 struct hostent *host;
1847 if (!CellHandleIsValid(c_handle, &tst)) {
1848 goto fail_afsclient_AFSServerGetBegin;
1851 if (iterationIdP == NULL) {
1852 tst = ADMITERATIONIDPNULL;
1853 goto fail_afsclient_AFSServerGetBegin;
1856 if ((serv == NULL) || (iter == NULL)) {
1858 goto fail_afsclient_AFSServerGetBegin;
1863 if (c_handle->server_list != NULL && c_handle->server_ttl < time(NULL)) {
1864 serv_cache = c_handle->server_list;
1865 c_handle->server_list = NULL;
1867 UNLOCK_GLOBAL_MUTEX;
1869 if (c_handle->server_list == NULL) {
1870 if (serv_cache == NULL) {
1871 serv_cache = (server_get_p) calloc(1, sizeof(server_get_t));
1873 if (serv_cache == NULL) {
1875 goto fail_afsclient_AFSServerGetBegin;
1880 * Retrieve the list of database servers for this cell.
1883 if (!afsclient_CellNameGet(c_handle, &cellName, &tst)) {
1884 goto fail_afsclient_AFSServerGetBegin;
1887 if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
1888 goto fail_afsclient_AFSServerGetBegin;
1891 while (util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
1892 serv->server[serv->total].serverAddress[0] =
1893 database_entry.serverAddress;
1894 serv->server[serv->total].serverType = DATABASE_SERVER;
1898 if (tst != ADMITERATORDONE) {
1899 util_DatabaseServerGetDone(database_iter, 0);
1900 goto fail_afsclient_AFSServerGetBegin;
1903 if (!util_DatabaseServerGetDone(database_iter, &tst)) {
1904 goto fail_afsclient_AFSServerGetBegin;
1908 * Retrieve the list of file servers for this cell.
1911 if (!vos_FileServerGetBegin(c_handle, 0, &fileserver_iter, &tst)) {
1912 goto fail_afsclient_AFSServerGetBegin;
1915 while (vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
1917 * See if any of the addresses returned in this fileserver_entry
1918 * structure already exist in the list of servers we're building.
1919 * If not, create a new record for this server.
1922 for (iserv = 0; iserv < serv->total; iserv++) {
1923 for (ientryaddr = 0; ientryaddr < fileserver_entry.count; ientryaddr++) {
1924 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS; iservaddr++) {
1925 if (serv->server[iserv].serverAddress[iservaddr] ==
1926 fileserver_entry.serverAddress[ientryaddr]) {
1941 serv->server[iserv].serverType |= FILE_SERVER;
1943 iserv = serv->total++;
1944 serv->server[iserv].serverType = FILE_SERVER;
1948 * Add the addresses from the vldb list to the serv->server[iserv]
1949 * record. Remember that VLDB's list-of-addrs is not guaranteed
1950 * to be unique in a particular entry, or to return only one entry
1951 * per machine--so when we add addresses, always check for
1952 * duplicate entries.
1955 for (ientryaddr = 0; ientryaddr < fileserver_entry.count; ientryaddr++) {
1956 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS; iservaddr++) {
1957 if (serv->server[iserv].serverAddress[iservaddr] ==
1958 fileserver_entry.serverAddress[ientryaddr]) {
1962 if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
1963 for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
1965 if (!serv->server[iserv].serverAddress[iservaddr]) {
1966 serv->server[iserv].serverAddress[iservaddr] =
1967 fileserver_entry.serverAddress[ientryaddr];
1975 if (tst != ADMITERATORDONE) {
1976 vos_FileServerGetDone(fileserver_iter, 0);
1977 goto fail_afsclient_AFSServerGetBegin;
1980 if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
1981 goto fail_afsclient_AFSServerGetBegin;
1985 * Iterate over the list and fill in the hostname of each of the servers
1988 for (iserv = 0; iserv < serv->total; iserv++) {
1989 int addr = htonl(serv->server[iserv].serverAddress[0]);
1991 host = gethostbyaddr((const char *)&addr, sizeof(int), AF_INET);
1993 strncpy(serv->server[iserv].serverName, host->h_name,
1994 AFS_MAX_SERVER_NAME_LEN);
1995 serv->server[iserv].serverName[AFS_MAX_SERVER_NAME_LEN - 1] = '\0';
1997 UNLOCK_GLOBAL_MUTEX;
2000 memcpy(serv_cache, serv, sizeof(server_get_t));
2004 if (c_handle->server_list == NULL)
2007 memcpy(serv, c_handle->server_list, sizeof(server_get_t));
2008 UNLOCK_GLOBAL_MUTEX;
2014 (iter, (void *)serv, GetServerRPC, GetServerFromCache, NULL, NULL,
2016 *iterationIdP = (void *)iter;
2020 fail_afsclient_AFSServerGetBegin:
2027 if (serv_cache != NULL)
2032 /* in case there was a race and we constructed the list twice */
2033 if (c_handle->server_list)
2034 free(c_handle->server_list);
2036 c_handle->server_list = serv_cache;
2037 c_handle->server_ttl = time(NULL) + SERVER_TTL;
2038 UNLOCK_GLOBAL_MUTEX;
2049 * afsclient_AFSServerGetNext - retrieve the next server in the cell.
2053 * IN iterationId - an iterator previously returned by
2054 * afsclient_AFSServerGetBegin.
2056 * OUT serverEntryP - upon successful completion contains the next server.
2060 * No locks are obtained or released by this function
2068 * Returns != 0 upon successful completion.
2072 afsclient_AFSServerGetNext(void *iterationId, afs_serverEntry_p serverEntryP,
2076 afs_status_t tst = 0;
2077 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2079 if (iterationId == NULL) {
2080 tst = ADMITERATORNULL;
2081 goto fail_afsclient_AFSServerGetNext;
2084 if (serverEntryP == NULL) {
2085 tst = ADMUTILSERVERENTRYPNULL;
2086 goto fail_afsclient_AFSServerGetNext;
2089 rc = IteratorNext(iter, (void *)serverEntryP, &tst);
2091 fail_afsclient_AFSServerGetNext:
2100 * afsclient_AFSServerGetDone - finish using a server iterator.
2104 * IN iterationId - an iterator previously returned by
2105 * afsclient_AFSServerGetBegin.
2109 * No locks are obtained or released by this function
2117 * Returns != 0 upon successful completion.
2121 afsclient_AFSServerGetDone(void *iterationId, afs_status_p st)
2124 afs_status_t tst = 0;
2125 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2127 if (iterationId == NULL) {
2128 tst = ADMITERATORNULL;
2129 goto fail_afsclient_AFSServerGetDone;
2132 rc = IteratorDone(iter, &tst);
2134 fail_afsclient_AFSServerGetDone:
2143 * afsclient_RPCStatOpen - open an rx connection to a server to retrieve
2148 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2150 * IN serverName - the host name where the server resides.
2152 * IN type - what type of process to query
2154 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2158 * No locks are obtained or released by this function
2166 * Returns != 0 upon successful completion.
2170 afsclient_RPCStatOpen(const void *cellHandle, const char *serverName,
2171 afs_stat_source_t type,
2172 struct rx_connection **rpcStatHandleP, afs_status_p st)
2175 afs_status_t tst = 0;
2176 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2179 struct rx_securityClass *sc;
2181 if (!CellHandleIsValid(cellHandle, &tst)) {
2182 goto fail_afsclient_RPCStatOpen;
2185 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2186 goto fail_afsclient_RPCStatOpen;
2189 if (rpcStatHandleP == NULL) {
2190 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2191 goto fail_afsclient_RPCStatOpen;
2197 servPort = AFSCONF_NANNYPORT;
2200 case AFS_FILESERVER:
2201 servPort = AFSCONF_FILEPORT;
2205 servPort = AFSCONF_KAUTHPORT;
2209 servPort = AFSCONF_PROTPORT;
2213 servPort = AFSCONF_VOLUMEPORT;
2217 servPort = AFSCONF_VLDBPORT;
2221 servPort = AFSCONF_CALLBACKPORT;
2225 tst = ADMTYPEINVALID;
2226 goto fail_afsclient_RPCStatOpen;
2230 * special processing of tokens by server type
2233 if (type == AFS_KASERVER) {
2234 if (!c_handle->tokens->kas_token_set) {
2235 tst = ADMCLIENTNOKASTOKENS;
2236 goto fail_afsclient_RPCStatOpen;
2238 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2240 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2244 rx_GetCachedConnection(htonl(servAddr), htons(servPort),
2245 RX_STATS_SERVICE_ID, sc,
2246 c_handle->tokens->sc_index);
2248 if (*rpcStatHandleP == NULL) {
2249 tst = ADMCLIENTRPCSTATNOCONNECTION;
2250 goto fail_afsclient_RPCStatOpen;
2254 fail_afsclient_RPCStatOpen:
2263 * afsclient_RPCStatOpenPort - open an rx connection to a server to retrieve
2268 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2270 * IN serverName - the host name where the server resides.
2272 * IN port - the UDP port number where the server resides.
2274 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2278 * No locks are obtained or released by this function
2286 * Returns != 0 upon successful completion.
2290 afsclient_RPCStatOpenPort(const void *cellHandle, const char *serverName,
2291 const int serverPort,
2292 struct rx_connection **rpcStatHandleP,
2296 afs_status_t tst = 0;
2297 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2299 struct rx_securityClass *sc;
2301 if (!CellHandleIsValid(cellHandle, &tst)) {
2302 goto fail_afsclient_RPCStatOpenPort;
2305 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2306 goto fail_afsclient_RPCStatOpenPort;
2309 if (rpcStatHandleP == NULL) {
2310 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2311 goto fail_afsclient_RPCStatOpenPort;
2315 * special processing of tokens by server type
2318 if (serverPort == AFSCONF_KAUTHPORT) {
2319 if (!c_handle->tokens->kas_token_set) {
2320 tst = ADMCLIENTNOKASTOKENS;
2321 goto fail_afsclient_RPCStatOpenPort;
2323 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2325 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2329 rx_GetCachedConnection(htonl(servAddr), htons(serverPort),
2330 RX_STATS_SERVICE_ID, sc,
2331 c_handle->tokens->sc_index);
2333 if (*rpcStatHandleP == NULL) {
2334 tst = ADMCLIENTRPCSTATNOCONNECTION;
2335 goto fail_afsclient_RPCStatOpenPort;
2339 fail_afsclient_RPCStatOpenPort:
2348 * afsclient_RPCStatClose - close a previously opened rx connection.
2352 * IN rpcStatHandle - an rx connection returned by afsclient_RPCStatOpen
2356 * No locks are obtained or released by this function
2364 * Returns != 0 upon successful completion.
2368 afsclient_RPCStatClose(struct rx_connection *rpcStatHandle, afs_status_p st)
2371 afs_status_t tst = 0;
2373 if (rpcStatHandle == NULL) {
2374 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2375 goto fail_afsclient_RPCStatClose;
2378 rx_ReleaseCachedConnection(rpcStatHandle);
2380 fail_afsclient_RPCStatClose:
2389 * afsclient_CMStatOpen - open an rx connection to a server to retrieve
2394 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2396 * IN serverName - the host name where the server resides.
2398 * OUT cmStatHandleP - contains an rx connection to the server of interest
2402 * No locks are obtained or released by this function
2410 * Returns != 0 upon successful completion.
2414 afsclient_CMStatOpen(const void *cellHandle, const char *serverName,
2415 struct rx_connection **cmStatHandleP, afs_status_p st)
2418 afs_status_t tst = 0;
2419 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2421 struct rx_securityClass *sc;
2423 if (!CellHandleIsValid(cellHandle, &tst)) {
2424 goto fail_afsclient_CMStatOpen;
2427 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2428 goto fail_afsclient_CMStatOpen;
2431 if (cmStatHandleP == NULL) {
2432 tst = ADMCLIENTCMSTATHANDLEPNULL;
2433 goto fail_afsclient_CMStatOpen;
2436 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2439 rx_GetCachedConnection(htonl(servAddr), htons(AFSCONF_CALLBACKPORT),
2440 1, sc, c_handle->tokens->sc_index);
2442 if (*cmStatHandleP == NULL) {
2443 tst = ADMCLIENTCMSTATNOCONNECTION;
2444 goto fail_afsclient_CMStatOpen;
2448 fail_afsclient_CMStatOpen:
2457 * afsclient_CMStatOpenPort - open an rx connection to a server to retrieve
2462 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2464 * IN serverName - the host name where the server resides.
2466 * IN port - the UDP port number where the server resides.
2468 * OUT cmStatHandleP - contains an rx connection to the server of interest
2472 * No locks are obtained or released by this function
2480 * Returns != 0 upon successful completion.
2484 afsclient_CMStatOpenPort(const void *cellHandle, const char *serverName,
2485 const int serverPort,
2486 struct rx_connection **cmStatHandleP,
2490 afs_status_t tst = 0;
2491 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2493 struct rx_securityClass *sc;
2495 if (!CellHandleIsValid(cellHandle, &tst)) {
2496 goto fail_afsclient_CMStatOpenPort;
2499 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2500 goto fail_afsclient_CMStatOpenPort;
2503 if (cmStatHandleP == NULL) {
2504 tst = ADMCLIENTCMSTATHANDLEPNULL;
2505 goto fail_afsclient_CMStatOpenPort;
2508 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2511 rx_GetCachedConnection(htonl(servAddr), htons(serverPort), 1, sc,
2512 c_handle->tokens->sc_index);
2514 if (*cmStatHandleP == NULL) {
2515 tst = ADMCLIENTCMSTATNOCONNECTION;
2516 goto fail_afsclient_CMStatOpenPort;
2520 fail_afsclient_CMStatOpenPort:
2529 * afsclient_CMStatClose - close a previously opened rx connection.
2533 * IN cmStatHandle - an rx connection returned by afsclient_CMStatOpen
2537 * No locks are obtained or released by this function
2545 * Returns != 0 upon successful completion.
2549 afsclient_CMStatClose(struct rx_connection *cmStatHandle, afs_status_p st)
2552 afs_status_t tst = 0;
2554 if (cmStatHandle == NULL) {
2555 tst = ADMCLIENTCMSTATHANDLEPNULL;
2556 goto fail_afsclient_CMStatClose;
2559 rx_ReleaseCachedConnection(cmStatHandle);
2561 fail_afsclient_CMStatClose:
2570 * afsclient_RXDebugOpen - open an rxdebug handle to a server.
2574 * IN serverName - the host name where the server resides.
2576 * IN type - what type of process to query
2578 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2582 * No locks are obtained or released by this function
2590 * Returns != 0 upon successful completion.
2594 afsclient_RXDebugOpen(const char *serverName, afs_stat_source_t type,
2595 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2598 afs_status_t tst = 0;
2600 rxdebugHandle_p handle;
2601 rxdebugSocket_t sock;
2602 struct sockaddr_in taddr;
2606 if (rxdebugHandleP == NULL) {
2607 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2608 goto fail_afsclient_RXDebugOpen;
2614 serverPort = AFSCONF_NANNYPORT;
2617 case AFS_FILESERVER:
2618 serverPort = AFSCONF_FILEPORT;
2622 serverPort = AFSCONF_KAUTHPORT;
2626 serverPort = AFSCONF_PROTPORT;
2630 serverPort = AFSCONF_VOLUMEPORT;
2634 serverPort = AFSCONF_VLDBPORT;
2638 serverPort = AFSCONF_CALLBACKPORT;
2642 tst = ADMTYPEINVALID;
2643 goto fail_afsclient_RXDebugOpen;
2646 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2647 goto fail_afsclient_RXDebugOpen;
2650 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2651 if (sock == INVALID_RXDEBUG_SOCKET) {
2653 goto fail_afsclient_RXDebugOpen;
2656 memset(&taddr, 0, sizeof(taddr));
2657 taddr.sin_family = AF_INET;
2659 taddr.sin_addr.s_addr = INADDR_ANY;
2660 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2664 goto fail_afsclient_RXDebugOpen;
2667 handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
2671 goto fail_afsclient_RXDebugOpen;
2674 handle->sock = sock;
2675 handle->ipAddr = serverAddr;
2676 handle->udpPort = serverPort;
2677 handle->firstFlag = 1;
2678 handle->supportedStats = 0;
2679 *rxdebugHandleP = handle;
2682 fail_afsclient_RXDebugOpen:
2691 * afsclient_RXDebugOpenPort - open an rxdebug handle to a server.
2695 * IN serverName - the host name where the server resides.
2697 * IN port - the UDP port number where the server resides.
2699 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2703 * No locks are obtained or released by this function
2711 * Returns != 0 upon successful completion.
2715 afsclient_RXDebugOpenPort(const char *serverName, int serverPort,
2716 rxdebugHandle_p * rxdebugHandleP, afs_status_p st)
2719 afs_status_t tst = 0;
2721 rxdebugHandle_p handle;
2722 rxdebugSocket_t sock;
2723 struct sockaddr_in taddr;
2726 if (rxdebugHandleP == NULL) {
2727 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2728 goto fail_afsclient_RXDebugOpenPort;
2731 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2732 goto fail_afsclient_RXDebugOpenPort;
2735 sock = (rxdebugSocket_t) socket(AF_INET, SOCK_DGRAM, 0);
2736 if (sock == INVALID_RXDEBUG_SOCKET) {
2738 goto fail_afsclient_RXDebugOpenPort;
2741 memset(&taddr, 0, sizeof(taddr));
2742 taddr.sin_family = AF_INET;
2744 taddr.sin_addr.s_addr = INADDR_ANY;
2745 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2749 goto fail_afsclient_RXDebugOpenPort;
2752 handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
2756 goto fail_afsclient_RXDebugOpenPort;
2759 handle->sock = sock;
2760 handle->ipAddr = serverAddr;
2761 handle->udpPort = serverPort;
2762 handle->firstFlag = 1;
2763 handle->supportedStats = 0;
2764 *rxdebugHandleP = handle;
2767 fail_afsclient_RXDebugOpenPort:
2776 * afsclient_RXDebugClose - close a previously opened rxdebug handle.
2780 * IN rxdebugHandle - an rxdebug handle returned by afsclient_RXDebugOpen
2784 * No locks are obtained or released by this function
2792 * Returns != 0 upon successful completion.
2796 afsclient_RXDebugClose(rxdebugHandle_p rxdebugHandle, afs_status_p st)
2799 afs_status_t tst = 0;
2801 if (rxdebugHandle == NULL) {
2802 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2803 goto fail_afsclient_RXDebugClose;
2806 close(rxdebugHandle->sock);
2807 free(rxdebugHandle);
2809 fail_afsclient_RXDebugClose: