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>
16 #include "afs_clientAdmin.h"
17 #include "../adminutil/afs_AdminInternal.h"
20 #include <sys/types.h>
21 #include <afs/cellconfig.h>
23 #include <afs/afssyscalls.h>
25 #include <afs/fs_utils.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <arpa/inet.h>
31 #include <afs/venus.h>
37 #include <afs/kautils.h>
39 #include <rx/rx_null.h>
41 #include <afs/dirpath.h>
42 #include <afs/afs_AdminErrors.h>
43 #include <afs/afs_vosAdmin.h>
44 #include <afs/afs_utilAdmin.h>
45 #include <afs/ptserver.h>
46 #include <afs/vlserver.h>
47 #include <afs/pthread_glock.h>
50 * AFS client administration functions.
52 * Admin functions that are normally associated with the client.
54 * All of the functions related to authentication are here, plus
55 * some miscellaneous others.
59 static const unsigned long ADMIN_TICKET_LIFETIME = 24*3600;
62 * We need a way to track whether or not the client library has been
63 * initialized. We count on the fact that the other library initialization
64 * functions are protected by their own once mechanism. We only track
65 * our own internal status
68 static int client_init;
69 static pthread_once_t client_init_once = PTHREAD_ONCE_INIT;
71 static void client_once(void) {
76 * IsTokenValid - validate a token handle
80 * IN token - the token to be validated.
84 * No locks are obtained or released by this function
92 * Returns != 0 upon successful completion.
95 static int IsTokenValid(
96 const afs_token_handle_p token,
100 afs_status_t tst = 0;
103 tst = ADMCLIENTTOKENHANDLENULL;
104 goto fail_IsTokenValid;
107 if (token->is_valid == 0) {
108 tst = ADMCLIENTTOKENHANDLEINVALID;
109 goto fail_IsTokenValid;
112 if ((token->begin_magic != BEGIN_MAGIC) ||
113 (token->end_magic != END_MAGIC)) {
114 tst = ADMCLIENTTOKENHANDLEBADMAGIC;
115 goto fail_IsTokenValid;
128 * afsclient_TokenGetExisting - get tokens that already exist and
129 * are held by the cache manager.
133 * IN cellName - the name of the cell where the token originated.
135 * OUT tokenHandle - a handle to the tokens if they were obtained
140 * No locks are obtained or released by this function
144 * The tokenHandle returned by this function cannot be used for kas
145 * related operations, since kas tokens aren't stored in the kernel.
149 * Returns != 0 upon successful completion.
152 int ADMINAPI afsclient_TokenGetExisting(
153 const char *cellName,
158 afs_status_t tst = 0;
159 struct ktc_principal afs_server;
160 afs_token_handle_p t_handle = (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
162 if (client_init == 0) {
163 tst = ADMCLIENTNOINIT;
164 goto fail_afsclient_TokenGetExisting;
167 if (cellName == NULL) {
168 tst = ADMCLIENTCELLNAMENULL;
169 goto fail_afsclient_TokenGetExisting;
172 if (tokenHandle == NULL) {
173 tst = ADMCLIENTTOKENHANDLENULL;
174 goto fail_afsclient_TokenGetExisting;
177 if (t_handle == NULL) {
179 goto fail_afsclient_TokenGetExisting;
182 strcpy(afs_server.name, "afs");
183 afs_server.instance[0] = 0;
184 strcpy(afs_server.cell, cellName);
186 if (!(tst = ktc_GetToken(&afs_server, &t_handle->afs_token,
187 sizeof(t_handle->afs_token),
188 &t_handle->client))) {
190 * The token has been retrieved successfully, initialize
191 * the rest of the token handle structure
193 strcpy(t_handle->cell, cellName);
194 t_handle->afs_token_set = 1;
195 t_handle->from_kernel = 1;
196 t_handle->kas_token_set = 0;
197 t_handle->sc_index = 2;
198 t_handle->afs_sc[t_handle->sc_index] =
199 rxkad_NewClientSecurityObject(rxkad_clear,
200 &t_handle->afs_token.sessionKey,
201 t_handle->afs_token.kvno,
202 t_handle->afs_token.ticketLen,
203 t_handle->afs_token.ticket);
204 t_handle->afs_encrypt_sc[t_handle->sc_index] =
205 rxkad_NewClientSecurityObject(rxkad_crypt,
206 &t_handle->afs_token.sessionKey,
207 t_handle->afs_token.kvno,
208 t_handle->afs_token.ticketLen,
209 t_handle->afs_token.ticket);
210 if ((t_handle->afs_sc[t_handle->sc_index] == NULL) ||
211 (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
212 tst = ADMCLIENTTOKENHANDLENOSECURITY;
213 goto fail_afsclient_TokenGetExisting;
215 t_handle->begin_magic = BEGIN_MAGIC;
216 t_handle->is_valid = 1;
217 t_handle->end_magic = END_MAGIC;
218 *tokenHandle = (void *) t_handle;
221 goto fail_afsclient_TokenGetExisting;
225 fail_afsclient_TokenGetExisting:
227 if ((rc == 0) && (t_handle != NULL)) {
237 * afsclient_TokenSet - set the tokens represented by tokenHandle to be
238 * active in the kernel (aka ka_SetToken).
242 * IN cellName - the name of the cell where the token originated.
244 * OUT tokenHandle - a handle to the tokens if they were obtained
249 * No locks are obtained or released by this function
253 * The tokenHandle returned by this function cannot be used for kas
254 * related operations, since kas tokens aren't stored in the kernel.
258 * Returns != 0 upon successful completion.
261 int ADMINAPI afsclient_TokenSet(
262 const void *tokenHandle,
266 afs_status_t tst = 0;
267 struct ktc_principal afs_server;
268 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
270 if (!IsTokenValid(t_handle, &tst)) {
271 goto fail_afsclient_TokenSet;
274 strcpy(afs_server.name, "afs");
275 afs_server.instance[0] = 0;
276 strcpy(afs_server.cell, t_handle->cell);
278 tst = ktc_SetToken(&afs_server, &t_handle->afs_token, &t_handle->client, 0);
284 fail_afsclient_TokenSet:
293 * GetKASToken - get a KAS token and store it in the tokenHandle.
297 * IN cellName - the name of the cell where the token should be obtained.
299 * IN principal - the name of the user of the token.
301 * IN password - the password for the principal.
303 * OUT tokenHandle - a handle to the tokens if they were obtained
308 * No locks are obtained or released by this function
316 * Returns != 0 upon successful completion.
319 static int GetKASToken(
320 const char *cellName,
321 const char *principal,
322 const char *password,
323 afs_token_handle_p tokenHandle,
327 afs_status_t tst = 0;
328 struct ubik_client *unauth_conn;
330 struct ktc_encryptionKey key;
331 struct ktc_token *token;
332 unsigned long now = time(0);
333 char name[MAXKTCNAMELEN];
334 char inst[MAXKTCNAMELEN];
335 int have_server_conn = 0;
337 token = &tokenHandle->kas_token;
339 ka_StringToKey((char *)password, (char *)cellName, &key);
342 * Get an unauthenticated connection in the right cell to use for
343 * retrieving the token.
346 tst = ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
349 goto fail_GetKASToken;
351 have_server_conn = 1;
353 tst = ka_ParseLoginName((char *)principal, name, inst, NULL);
355 goto fail_GetKASToken;
358 tst = ka_Authenticate(name, inst, (char *)cellName, unauth_conn,
359 KA_MAINTENANCE_SERVICE, &key, now,
360 now+ADMIN_TICKET_LIFETIME, token, &expire);
362 goto fail_GetKASToken;
368 if (have_server_conn) {
369 ubik_ClientDestroy(unauth_conn);
379 * GetAFSToken - get a AFS token and store it in the tokenHandle.
383 * IN cellName - the name of the cell where the token should be obtained.
385 * IN principal - the name of the user of the token.
387 * IN password - the password for the principal.
389 * OUT tokenHandle - a handle to the tokens if they were obtained
394 * No locks are obtained or released by this function
402 * Returns != 0 upon successful completion.
405 static int GetAFSToken(
406 const char *cellName,
407 const char *principal,
408 const char *password,
409 afs_token_handle_p tokenHandle,
413 afs_status_t tst = 0;
414 struct ubik_client *unauth_conn = NULL, *auth_conn = NULL;
416 struct ktc_encryptionKey key;
417 struct ktc_token auth_token;
418 struct ktc_token *token;
419 unsigned long now = time(0);
421 token = &tokenHandle->afs_token;
423 ka_StringToKey((char *)password, (char *)cellName, &key);
426 * Get an unauthenticated connection in the right cell to use for
427 * retrieving the token.
430 tst = ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
433 goto fail_GetAFSToken;
436 tst = ka_ParseLoginName((char *)principal, tokenHandle->client.name,
437 tokenHandle->client.instance, NULL);
439 goto fail_GetAFSToken;
442 tst = ka_Authenticate(tokenHandle->client.name,
443 tokenHandle->client.instance, (char *)cellName,
444 unauth_conn, KA_TICKET_GRANTING_SERVICE,
445 &key, now, now+ADMIN_TICKET_LIFETIME,
446 &auth_token, &expire);
448 goto fail_GetAFSToken;
451 tst = ka_AuthServerConn((char *)cellName, KA_TICKET_GRANTING_SERVICE,
454 goto fail_GetAFSToken;
457 tst = ka_CellToRealm((char *)cellName, tokenHandle->client.cell, (int *) 0);
459 goto fail_GetAFSToken;
462 tst = ka_GetToken("afs", "", (char *)cellName,
463 tokenHandle->client.name,
464 tokenHandle->client.instance,
466 now+ADMIN_TICKET_LIFETIME,
467 &auth_token, tokenHandle->client.cell,
470 goto fail_GetAFSToken;
477 ubik_ClientDestroy(auth_conn);
481 ubik_ClientDestroy(unauth_conn);
492 * afsclient_TokenGetNew - get new tokens for a user and store them
493 * in the tokenHandle.
497 * IN cellName - the name of the cell where the tokens should be obtained.
499 * IN principal - the name of the user of the tokens.
501 * IN password - the password for the principal.
503 * OUT tokenHandle - a handle to the tokens if they were obtained
508 * No locks are obtained or released by this function
516 * Returns != 0 upon successful completion.
519 int ADMINAPI afsclient_TokenGetNew(
520 const char *cellName,
521 const char *principal,
522 const char *password,
527 afs_status_t tst = 0;
528 afs_token_handle_p t_handle = (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
530 if (client_init == 0) {
531 tst = ADMCLIENTNOINIT;
532 goto fail_afsclient_TokenGetNew;
535 if (t_handle == NULL) {
537 goto fail_afsclient_TokenGetNew;
541 * Check to see if the principal or password is missing. If it is,
542 * get unauthenticated tokens for the cell
545 if ((principal == NULL) || (*principal == 0) ||
546 (password == NULL) || (*password == 0)) {
547 t_handle->from_kernel = 0;
548 t_handle->afs_token_set = 1;
549 t_handle->kas_token_set = 1;
550 t_handle->sc_index = 0;
551 t_handle->afs_sc[t_handle->sc_index] =
552 rxnull_NewClientSecurityObject();
553 t_handle->afs_encrypt_sc[t_handle->sc_index] =
554 rxnull_NewClientSecurityObject();
555 t_handle->kas_sc[t_handle->sc_index] =
556 rxnull_NewClientSecurityObject();
557 t_handle->begin_magic = BEGIN_MAGIC;
558 t_handle->is_valid = 1;
559 t_handle->afs_token.endTime = 0;
560 t_handle->end_magic = END_MAGIC;
561 *tokenHandle = (void *) t_handle;
566 * create an authenticated token
569 if ((GetAFSToken(cellName, principal, password, t_handle, &tst)) &&
570 (GetKASToken(cellName, principal, password, t_handle, &tst))) {
571 strcpy(t_handle->cell, cellName);
572 t_handle->from_kernel = 0;
573 t_handle->afs_token_set = 1;
574 t_handle->kas_token_set = 1;
575 t_handle->sc_index = 2;
576 t_handle->afs_sc[t_handle->sc_index] =
577 rxkad_NewClientSecurityObject(rxkad_clear,
578 &t_handle->afs_token.sessionKey,
579 t_handle->afs_token.kvno,
580 t_handle->afs_token.ticketLen,
581 t_handle->afs_token.ticket);
582 t_handle->afs_encrypt_sc[t_handle->sc_index] =
583 rxkad_NewClientSecurityObject(rxkad_crypt,
584 &t_handle->afs_token.sessionKey,
585 t_handle->afs_token.kvno,
586 t_handle->afs_token.ticketLen,
587 t_handle->afs_token.ticket);
588 t_handle->kas_sc[t_handle->sc_index] =
589 rxkad_NewClientSecurityObject(rxkad_crypt,
590 &t_handle->kas_token.sessionKey,
591 t_handle->kas_token.kvno,
592 t_handle->kas_token.ticketLen,
593 t_handle->kas_token.ticket);
594 if ((t_handle->afs_sc[t_handle->sc_index] != NULL) &&
595 (t_handle->afs_encrypt_sc[t_handle->sc_index] != NULL) &&
596 (t_handle->kas_sc[t_handle->sc_index] != NULL)) {
597 t_handle->begin_magic = BEGIN_MAGIC;
598 t_handle->is_valid = 1;
599 t_handle->end_magic = END_MAGIC;
600 *tokenHandle = (void *) t_handle;
602 tst = ADMCLIENTTOKENHANDLENOSECURITY;
603 goto fail_afsclient_TokenGetNew;
606 goto fail_afsclient_TokenGetNew;
611 fail_afsclient_TokenGetNew:
613 if ((rc == 0) && (t_handle != NULL)) {
624 * afsclient_TokenQuery - get the expiration time of the tokens.
628 * IN tokenHandle - a previously obtained valid token.
630 * OUT expirationDateP - the time at which the tokens expire.
632 * OUT principal - the owning principal
634 * OUT instance - principal instance if it exists.
636 * OUT cell - the principal's cell
638 * OUT hasKasTokens - set to 1 if the token handle contains kas tokens.
642 * No locks are obtained or released by this function
646 * We only check the AFS tokens since we always get these. The
647 * KAS tokens may expirer later than the AFS tokens, but this
648 * difference is minor and reporting an earlier time won't cause
653 * Returns != 0 upon successful completion.
656 int ADMINAPI afsclient_TokenQuery(
658 unsigned long *expirationDateP,
666 afs_status_t tst = 0;
667 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
669 if (client_init == 0) {
670 tst = ADMCLIENTNOINIT;
672 goto fail_afsclient_TokenQuery;
675 if (IsTokenValid(t_handle, &tst)) {
676 if (principal != NULL) {
677 strcpy(principal, t_handle->client.name);
679 if (instance != NULL) {
680 strcpy(instance, t_handle->client.instance);
683 strcpy(cell, t_handle->client.cell);
685 if (hasKasTokens != NULL) {
686 *hasKasTokens = t_handle->kas_token_set;
688 if (expirationDateP != NULL) {
689 *expirationDateP = t_handle->afs_token.endTime;
694 fail_afsclient_TokenQuery:
703 * afsclient_TokenClose - close an existing token.
707 * IN token - the token to be closed.
711 * No locks are obtained or released by this function
719 * Returns != 0 upon successful completion.
722 int ADMINAPI afsclient_TokenClose(
723 const void *tokenHandle,
727 afs_status_t tst = 0;
728 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
730 if (client_init == 0) {
731 tst = ADMCLIENTNOINIT;
732 goto fail_afsclient_TokenClose;
735 if (IsTokenValid(t_handle, &tst)) {
736 t_handle->is_valid = 0;
741 fail_afsclient_TokenClose:
749 #define NUM_SERVER_TYPES 3
751 /* must match NUM_SERVER_TYPES */
752 typedef enum {KAS, PTS, VOS} afs_server_list_t;
754 typedef struct afs_server {
757 struct ubik_client **ubik;
758 struct rx_securityClass *sc;
760 } afs_server_t, *afs_server_p;
762 static afs_server_t servers[NUM_SERVER_TYPES]
763 = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
764 {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
765 {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}};
768 * afsclient_CellOpen - Open a particular cell for work as a particular
773 * IN cellName - the cell where future admin calls will be made.
775 * IN tokenHandle - the tokens work will be done under.
777 * OUT cellHandleP - an opaque pointer that is the first parameter to
778 * almost all subsequent admin api calls.
782 * No locks are obtained or released by this function
790 * Returns != 0 upon successful completion.
793 int ADMINAPI afsclient_CellOpen(
794 const char *cellName,
795 const void *tokenHandle,
800 afs_status_t tst = 0;
801 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
802 afs_cell_handle_p c_handle = (afs_cell_handle_p)
803 calloc(1, sizeof(afs_cell_handle_t));
804 struct afsconf_dir *tdir = NULL;
805 struct afsconf_cell info;
806 struct rx_connection *serverconns[MAXSERVERS];
808 struct rx_securityClass *sc[3];
810 char copyCell[MAXCELLCHARS];
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 strcpy(c_handle->working_cell, cellName);
878 if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
879 tst = ADMCLIENTBADCLIENTCONFIG;
880 goto fail_afsclient_CellOpen;
884 * We must copy the cellName here because afsconf_GetCellInfo
885 * actually writes over the cell name it is passed.
887 strncpy(copyCell, cellName, MAXCELLCHARS - 1);
888 for(i=0;(i<NUM_SERVER_TYPES);i++) {
890 tst = ka_AuthServerConn((char *)cellName,servers[i].serviceId,
891 ((t_handle->sc_index == 0) ||
892 (!t_handle->kas_token_set)) ?
893 0 : &t_handle->kas_token,
896 goto fail_afsclient_CellOpen;
899 tst = afsconf_GetCellInfo(tdir, copyCell,
900 servers[i].serv, &info);
902 /* create ubik client handles for each server */
903 scIndex = t_handle->sc_index;
904 sc[scIndex] = servers[i].sc;
905 for(j=0;(j<info.numServers);j++) {
907 rx_GetCachedConnection(
908 info.hostAddr[j].sin_addr.s_addr,
909 info.hostAddr[j].sin_port,
910 servers[i].serviceId,
911 sc[scIndex], scIndex);
914 tst = ubik_ClientInit(serverconns,servers[i].ubik);
916 goto fail_afsclient_CellOpen;
919 goto fail_afsclient_CellOpen;
922 /* initialization complete, mark handle valid */
923 *servers[i].valid = 1;
925 c_handle->tokens = t_handle;
928 fail_afsclient_CellOpen:
935 * Upon error, free any obtained resources.
938 if (c_handle != NULL) {
939 if (c_handle->kas_valid) ubik_ClientDestroy(c_handle->kas);
940 if (c_handle->pts_valid) ubik_ClientDestroy(c_handle->pts);
941 if (c_handle->vos_valid) ubik_ClientDestroy(c_handle->vos);
945 c_handle->begin_magic = BEGIN_MAGIC;
946 c_handle->is_valid = 1;
947 c_handle->is_null = 0;
948 c_handle->end_magic = END_MAGIC;
949 *cellHandleP = (void *) c_handle;
959 * afsclient_NullCellOpen - open a null cell handle for access.
963 * OUT cellHandleP - an opaque pointer that is the first parameter to
964 * almost all subsequent admin api calls.
968 * No locks are obtained or released by this function
976 * Returns != 0 upon successful completion.
979 int ADMINAPI afsclient_NullCellOpen(
984 afs_status_t tst = 0;
985 afs_cell_handle_p c_handle = (afs_cell_handle_p)
986 calloc(1, sizeof(afs_cell_handle_t));
990 * Validate parameters
993 if (cellHandleP == NULL) {
994 tst = ADMCLIENTCELLHANDLEPNULL;
995 goto fail_afsclient_NullCellOpen;
998 if (client_init == 0) {
999 tst = ADMCLIENTNOINIT;
1000 goto fail_afsclient_NullCellOpen;
1003 if (c_handle == NULL) {
1005 goto fail_afsclient_NullCellOpen;
1009 * Get unauthenticated tokens for any cell
1012 if (!afsclient_TokenGetNew(0, 0, 0, (void *) &c_handle->tokens, &tst)) {
1013 goto fail_afsclient_NullCellOpen;
1016 c_handle->begin_magic = BEGIN_MAGIC;
1017 c_handle->is_valid = 1;
1018 c_handle->is_null = 1;
1019 c_handle->end_magic = END_MAGIC;
1020 c_handle->kas_valid = 0;
1021 c_handle->pts_valid = 0;
1022 c_handle->vos_valid = 0;
1026 *cellHandleP = (void *) c_handle;
1029 fail_afsclient_NullCellOpen:
1038 * afsclient_CellClose - close a previously opened cellHandle.
1042 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
1046 * No locks are obtained or released by this function
1054 * Returns != 0 upon successful completion.
1057 int ADMINAPI afsclient_CellClose(
1058 const void *cellHandle,
1062 afs_status_t tst = 0;
1063 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1065 if (client_init == 0) {
1066 tst = ADMCLIENTNOINIT;
1067 goto fail_afsclient_CellClose;
1070 if (c_handle == NULL) {
1071 tst = ADMCLIENTCELLHANDLENULL;
1072 goto fail_afsclient_CellClose;
1075 if (c_handle->kas_valid) ubik_ClientDestroy(c_handle->kas);
1076 if (c_handle->pts_valid) ubik_ClientDestroy(c_handle->pts);
1077 if (c_handle->vos_valid) ubik_ClientDestroy(c_handle->vos);
1078 if (c_handle->is_null) afsclient_TokenClose(c_handle->tokens, 0);
1079 c_handle->kas_valid = 0;
1080 c_handle->pts_valid = 0;
1081 c_handle->vos_valid = 0;
1082 c_handle->is_valid = 0;
1086 fail_afsclient_CellClose:
1096 * afsclient_CellNameGet() -- get a pointer to the cell name in a cell handle
1100 * IN cellHandle - a valid cell handle
1101 * OUT cellNameP - a pointer to the cell name in the cell handle.
1105 * No locks are obtained or released by this function
1109 * If cellHandle is closed then the pointer returned by this function
1110 * is no longer valid.
1114 * Returns != 0 upon successful completion.
1116 int ADMINAPI afsclient_CellNameGet(
1117 const void *cellHandle,
1118 const char **cellNameP,
1122 afs_status_t tst = 0;
1123 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1125 if (!CellHandleIsValid(cellHandle, &tst)) {
1126 goto fail_afsclient_CellNameGet;
1129 *cellNameP = c_handle->working_cell;
1132 fail_afsclient_CellNameGet:
1142 * afsclient_LocalCellGet - get the name of the cell the machine
1143 * belongs to where this process is running.
1147 * OUT cellName - an array of characters that must be MAXCELLCHARS
1152 * No locks are obtained or released by this function
1156 * If cellName is smaller than MAXCELLCHARS chars, this function won't
1161 * Returns != 0 upon successful completion.
1164 int ADMINAPI afsclient_LocalCellGet(
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);
1210 static int client_ExtractDriveLetter(
1215 if (path[0] != 0 && path[1] == ':') {
1224 * Determine the parent directory of a give directory
1229 char *parentDirectory)
1234 strcpy(parentDirectory, directory);
1235 tp = strrchr(parentDirectory, '\\');
1237 /* lv trailing slash so Parent("k:\foo") is "k:\" not "k :" */
1242 if (client_ExtractDriveLetter(parentDirectory)) {
1243 strcat(parentDirectory, ".");
1253 * Determine the parent directory of a give directory
1256 const char *directory,
1257 char *parentDirectory)
1262 strcpy(parentDirectory, directory);
1263 tp = strrchr(parentDirectory, '/');
1269 strcpy(parentDirectory, ".");
1278 * afsclient_MountPointCreate - create a mount point for a volume.
1282 * IN cellHandle - a handle to the cell where volumeName resides.
1284 * IN directory - the directory where the mountpoint should be created.
1286 * IN volumeName - the name of the volume to mount.
1288 * IN volType - the type of mount point to create.
1290 * IN volCheck - indicates whether or not to check the VLDB to see if
1291 * volumeName exists.
1295 * No locks are obtained or released by this function
1299 * Returns != 0 upon successful completion.
1302 #define TMP_DATA_SIZE 2048
1304 int ADMINAPI afsclient_MountPointCreate(
1305 const void *cellHandle,
1306 const char *directory,
1307 const char *volumeName,
1309 vol_check_t volCheck,
1313 afs_status_t tst = 0;
1314 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1315 char parent_dir[TMP_DATA_SIZE];
1316 char space[TMP_DATA_SIZE];
1317 char directoryCell[MAXCELLCHARS];
1318 struct ViceIoctl idata;
1320 vos_vldbEntry_t vldbEntry;
1323 * Validate arguments
1326 if (client_init == 0) {
1327 tst = ADMCLIENTNOINIT;
1328 goto fail_afsclient_MountPointCreate;
1331 if ((directory == NULL) || (*directory == 0)) {
1332 tst = ADMCLIENTDIRECTORYNULL;
1333 goto fail_afsclient_MountPointCreate;
1336 if ((volumeName == NULL) || (*volumeName == 0)) {
1337 tst = ADMCLIENTVOLUMENAME;
1338 goto fail_afsclient_MountPointCreate;
1342 * Extract the parent directory and make sure it is in AFS.
1345 if (!Parent(directory, parent_dir)) {
1346 tst = ADMCLIENTBADDIRECTORY;
1347 goto fail_afsclient_MountPointCreate;
1351 idata.out_size = TMP_DATA_SIZE;
1353 i = pioctl(parent_dir, VIOC_FILE_CELL_NAME, &idata, 1);
1355 if ((errno == EINVAL) || (errno == ENOENT)) {
1356 tst = ADMCLIENTNOAFSDIRECTORY;
1357 goto fail_afsclient_MountPointCreate;
1360 strcpy(directoryCell, space);
1363 * If the user requested, check that the volume exists
1366 if (volCheck == CHECK_VOLUME) {
1367 if (!vos_VLDBGet(cellHandle, 0, 0, volumeName, &vldbEntry, &tst)) {
1368 goto fail_afsclient_MountPointCreate;
1373 * Begin constructing the pioctl buffer
1376 if (volType == READ_WRITE) {
1383 * Append the cell to the mount point if the volume is in a different
1384 * cell than the directory
1387 if (strcmp(c_handle->working_cell, directoryCell)) {
1388 strcat(space, c_handle->working_cell);
1391 strcat(space, volumeName);
1398 idata.in_size = 1 + strlen(space);
1400 if (tst = pioctl(directory, VIOC_AFS_CREATE_MT_PT, &idata, 0)) {
1401 goto fail_afsclient_MountPointCreate;
1404 if ((tst = symlink(space, directory))) {
1405 goto fail_afsclient_MountPointCreate;
1411 fail_afsclient_MountPointCreate:
1419 typedef struct Acl {
1426 int ADMINAPI afsclient_ACLEntryAdd(
1427 const char *directory,
1433 afs_status_t tst = 0;
1434 struct ViceIoctl idata;
1435 char old_acl_string[2048];
1436 char new_acl_string[2048];
1441 int cur_user_acl = 0;
1446 if (client_init == 0) {
1447 tst = ADMCLIENTNOINIT;
1448 goto fail_afsclient_ACLEntryAdd;
1451 if ((directory == NULL) || (*directory == 0)) {
1452 tst = ADMMISCDIRECTORYNULL;
1453 goto fail_afsclient_ACLEntryAdd;
1456 if ((user == NULL) || (*user == 0)) {
1457 tst = ADMMISCUSERNULL;
1458 goto fail_afsclient_ACLEntryAdd;
1462 tst = ADMMISCACLNULL;
1463 goto fail_afsclient_ACLEntryAdd;
1466 if (acl->read == READ) {
1470 if (acl->write == WRITE) {
1474 if (acl->insert == INSERT) {
1478 if (acl->lookup == LOOKUP) {
1482 if (acl->del == DELETE) {
1486 if (acl->lock == LOCK) {
1490 if (acl->admin == ADMIN) {
1495 * Get the current acl for the directory
1498 idata.out_size = 2048;
1500 idata.in = idata.out = old_acl_string;
1501 tst = pioctl(directory, VIOCGETAL, &idata, 1);
1504 goto fail_afsclient_ACLEntryAdd;
1508 * The acl is presented to us in string format. The format of the
1511 * A header which contains the number of positive and negative entries
1512 * and a string indicating whether or not this is a dfs acl:
1514 * num_pos "\n" dfs_string "\n" num_neg
1516 * An entry for each acl that's of the form:
1520 * There are no blanks in the string between fields, but I use them here
1521 * to make the reading easier.
1523 * Since we are only going to add another entry to the acl, our approach
1524 * is simple. Get the num_pos dfs_string and num_neg from the current acl,
1525 * increment num_pos by one and create a new string. Concatenate the new
1526 * user and rights to the new string, and then concatenate the remaining
1527 * contents of the old acl to the new string.
1529 * Unfortunately, this approach doesn't work since the format the kernel
1530 * hands the acl back to us in, is NOT WHAT IT WANTS BACK!!!!
1531 * So instead we need to parse the entire freaking acl and put a space
1532 * between each user and their acl.
1534 * This is really ugly.
1538 * Parse the first few fields of the acl and see if this is a DFS
1542 is_dfs = sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs, cur_acl.cell);
1543 ptr = strchr(old_acl_string, '\n');
1545 sscanf(ptr, "%d", &cur_acl.nminus);
1546 ptr = strchr(ptr, '\n');
1549 tst = ADMMISCNODFSACL;
1550 goto fail_afsclient_ACLEntryAdd;
1553 * It isn't a DFS file, so create the beginning of the string
1554 * we will hand back to the kernel
1556 sprintf(new_acl_string, "%d\n%d\n%s %d\n", (cur_acl.nplus + 1),
1557 cur_acl.nminus, user, newacl);
1561 * Finish scanning the old acl, parsing each user/acl pair and
1562 * adding a space in the new acl.
1565 for(i=0;i<(cur_acl.nplus + cur_acl.nminus);i++) {
1566 sscanf(ptr, "%s%d\n", cur_user, &cur_user_acl);
1568 * Skip the entry for the user we are replacing/adding
1571 if (strcmp(cur_user, user)) {
1572 ptr = strchr(ptr, '\n');
1574 sprintf(tmp, "%s %d\n", cur_user, cur_user_acl);
1575 strcat(new_acl_string, tmp);
1579 strcat(new_acl_string, ptr);
1586 idata.in_size = strlen(new_acl_string) + 1;
1587 idata.in = idata.out = new_acl_string;
1588 tst = pioctl(directory, VIOCSETAL, &idata, 1);
1591 goto fail_afsclient_ACLEntryAdd;
1595 fail_afsclient_ACLEntryAdd:
1604 * afsclient_Init - initialize AFS components before use.
1610 * No locks are obtained or released by this function
1618 * Returns != 0 upon successful completion.
1621 int ADMINAPI afsclient_Init(
1625 afs_status_t tst = 0;
1628 pthread_once(&client_init_once, client_once);
1631 if (afs_winsockInit() < 0) {
1632 tst = ADMCLIENTCANTINITWINSOCK;
1633 goto fail_afsclient_Init;
1637 if (!(initAFSDirPath() & AFSDIR_CLIENT_PATHS_OK)) {
1638 tst = ADMCLIENTCANTINITAFSLOCATION;
1639 goto fail_afsclient_Init;
1642 if (rx_Init(0) < 0) {
1643 tst = ADMCLIENTCANTINITRX;
1644 goto fail_afsclient_Init;
1647 if ((tst = ka_CellConfig((char *)AFSDIR_CLIENT_ETC_DIRPATH))) {
1648 goto fail_afsclient_Init;
1653 fail_afsclient_Init:
1662 * afsclient_AFSServerGet - determine what kind of server serverName
1663 * is and fill in serverEntryP accordingly.
1667 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1669 * IN serverName - the hostname of the server of interest.
1671 * OUT serverEntryP - upon successful completion contains a description of
1676 * No locks are obtained or released by this function
1684 * Returns != 0 upon successful completion.
1687 int ADMINAPI afsclient_AFSServerGet(
1688 const void *cellHandle,
1689 const char *serverName,
1690 afs_serverEntry_p serverEntryP,
1694 afs_status_t tst = 0;
1696 int found_match = 0;
1698 if ((serverName == NULL) || (*serverName == 0)) {
1699 tst = ADMUTILSERVERNAMENULL;
1700 goto fail_afsclient_AFSServerGet;
1703 if (serverEntryP == NULL) {
1704 tst = ADMUTILSERVERENTRYPNULL;
1705 goto fail_afsclient_AFSServerGet;
1709 * Iterate over server entries and try to find a match for serverName
1712 if (!afsclient_AFSServerGetBegin(cellHandle, &iter, &tst)) {
1713 goto fail_afsclient_AFSServerGet;
1716 while(afsclient_AFSServerGetNext(iter, serverEntryP, &tst)) {
1717 if (!strcmp(serverName, serverEntryP->serverName)) {
1724 * If we didn't find a match, the iterator should have terminated
1725 * normally. If it didn't, return the error
1729 if (tst != ADMITERATORDONE) {
1730 afsclient_AFSServerGetDone(iter, 0);
1732 afsclient_AFSServerGetDone(iter, &tst);
1734 tst = ADMCLIENTNOMATCHINGSERVER;
1735 goto fail_afsclient_AFSServerGet;
1737 if (!afsclient_AFSServerGetDone(iter, &tst)) {
1738 goto fail_afsclient_AFSServerGet;
1743 fail_afsclient_AFSServerGet:
1752 * The iterator functions and data for the server retrieval functions
1755 typedef struct server_get {
1758 afs_serverEntry_t server[MAXHOSTSPERCELL + BADSERVERID];
1759 afs_serverEntry_t cache[CACHED_ITEMS];
1760 } server_get_t, *server_get_p;
1762 static int GetServerRPC(
1766 int *last_item_contains_data,
1770 afs_status_t tst = 0;
1771 server_get_p serv = (server_get_p) rpc_specific;
1773 memcpy(&serv->cache[slot], &serv->server[serv->index],
1774 sizeof(afs_serverEntry_t));
1777 if (serv->index == serv->total) {
1779 *last_item_contains_data = 1;
1789 static int GetServerFromCache(
1796 afs_status_t tst = 0;
1797 server_get_p serv = (server_get_p) rpc_specific;
1799 memcpy(dest, (const void *) &serv->cache[slot], sizeof(afs_serverEntry_t));
1809 * afsclient_AFSServerGetBegin - start the process of iterating over
1810 * every server in the cell.
1814 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1816 * OUT iterationIdP - - upon successful completion contains an iterator
1817 * that can be passed to afsclient_AFSServerGetNext.
1821 * No locks are obtained or released by this function
1829 * Returns != 0 upon successful completion.
1832 int ADMINAPI afsclient_AFSServerGetBegin(
1833 const void *cellHandle,
1834 void **iterationIdP,
1838 afs_status_t tst = 0;
1839 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1840 afs_admin_iterator_p iter = (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1841 server_get_p serv = (server_get_p) calloc(1, sizeof(server_get_t));
1842 const char *cellName;
1843 void *database_iter;
1844 util_databaseServerEntry_t database_entry;
1845 void *fileserver_iter;
1846 vos_fileServerEntry_t fileserver_entry;
1847 int iserv,iservaddr,ientryaddr, is_dup;
1848 struct hostent *host;
1850 if (!CellHandleIsValid(c_handle, &tst)) {
1851 goto fail_afsclient_AFSServerGetBegin;
1854 if (iterationIdP == NULL) {
1855 tst = ADMITERATIONIDPNULL;
1856 goto fail_afsclient_AFSServerGetBegin;
1859 if ((serv == NULL) || (iter == NULL)) {
1861 goto fail_afsclient_AFSServerGetBegin;
1865 * Retrieve the list of database servers for this cell.
1868 if (!afsclient_CellNameGet(cellHandle, &cellName, &tst)) {
1869 goto fail_afsclient_AFSServerGetBegin;
1872 if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
1873 goto fail_afsclient_AFSServerGetBegin;
1876 while(util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
1877 serv->server[serv->total].serverAddress[0] = database_entry.serverAddress;
1878 serv->server[serv->total].serverType = DATABASE_SERVER;
1882 if (tst != ADMITERATORDONE) {
1883 util_DatabaseServerGetDone(database_iter, 0);
1884 goto fail_afsclient_AFSServerGetBegin;
1887 if (!util_DatabaseServerGetDone(database_iter, &tst)) {
1888 goto fail_afsclient_AFSServerGetBegin;
1892 * Retrieve the list of file servers for this cell.
1895 if (!vos_FileServerGetBegin(cellHandle, 0, &fileserver_iter, &tst)) {
1896 goto fail_afsclient_AFSServerGetBegin;
1899 while(vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
1901 * See if any of the addresses returned in this fileserver_entry
1902 * structure already exist in the list of servers we're building.
1903 * If not, create a new record for this server.
1906 for(iserv=0;iserv<serv->total;iserv++) {
1907 for(ientryaddr=0; ientryaddr<fileserver_entry.count; ientryaddr++) {
1908 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1909 if (serv->server[iserv].serverAddress[iservaddr] ==
1910 fileserver_entry.serverAddress[ientryaddr]) {
1925 serv->server[iserv].serverType |= FILE_SERVER;
1927 iserv = serv->total++;
1928 serv->server[iserv].serverType = FILE_SERVER;
1932 * Add the addresses from the vldb list to the serv->server[iserv]
1933 * record. Remember that VLDB's list-of-addrs is not guaranteed
1934 * to be unique in a particular entry, or to return only one entry
1935 * per machine--so when we add addresses, always check for
1936 * duplicate entries.
1939 for(ientryaddr=0;ientryaddr<fileserver_entry.count;ientryaddr++) {
1940 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1941 if (serv->server[iserv].serverAddress[iservaddr] ==
1942 fileserver_entry.serverAddress[ientryaddr]) {
1946 if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
1947 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1948 if (!serv->server[iserv].serverAddress[iservaddr]) {
1949 serv->server[iserv].serverAddress[iservaddr] =
1950 fileserver_entry.serverAddress[ientryaddr];
1958 if (tst != ADMITERATORDONE) {
1959 vos_FileServerGetDone(fileserver_iter, 0);
1960 goto fail_afsclient_AFSServerGetBegin;
1963 if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
1964 goto fail_afsclient_AFSServerGetBegin;
1968 * Iterate over the list and fill in the hostname of each of the servers
1972 for(iserv=0;iserv<serv->total;iserv++) {
1973 int addr = htonl(serv->server[iserv].serverAddress[0]);
1974 host = gethostbyaddr((const char *) &addr, sizeof(int), AF_INET);
1976 strncpy(serv->server[iserv].serverName, host->h_name,
1977 AFS_MAX_SERVER_NAME_LEN);
1982 if (IteratorInit(iter, (void *) serv, GetServerRPC, GetServerFromCache,
1983 NULL, NULL, &tst)) {
1984 *iterationIdP = (void *) iter;
1988 fail_afsclient_AFSServerGetBegin:
2006 * afsclient_AFSServerGetNext - retrieve the next server in the cell.
2010 * IN iterationId - an iterator previously returned by
2011 * afsclient_AFSServerGetBegin.
2013 * OUT serverEntryP - upon successful completion contains the next server.
2017 * No locks are obtained or released by this function
2025 * Returns != 0 upon successful completion.
2028 int ADMINAPI afsclient_AFSServerGetNext(
2030 afs_serverEntry_p serverEntryP,
2034 afs_status_t tst = 0;
2035 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2037 if (iterationId == NULL) {
2038 tst = ADMITERATORNULL;
2039 goto fail_afsclient_AFSServerGetNext;
2042 if (serverEntryP == NULL) {
2043 tst = ADMUTILSERVERENTRYPNULL;
2044 goto fail_afsclient_AFSServerGetNext;
2047 rc = IteratorNext(iter, (void *) serverEntryP, &tst);
2049 fail_afsclient_AFSServerGetNext:
2058 * afsclient_AFSServerGetDone - finish using a server iterator.
2062 * IN iterationId - an iterator previously returned by
2063 * afsclient_AFSServerGetBegin.
2067 * No locks are obtained or released by this function
2075 * Returns != 0 upon successful completion.
2078 int ADMINAPI afsclient_AFSServerGetDone(
2083 afs_status_t tst = 0;
2084 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2086 if (iterationId == NULL) {
2087 tst = ADMITERATORNULL;
2088 goto fail_afsclient_AFSServerGetDone;
2091 rc = IteratorDone(iter, &tst);
2093 fail_afsclient_AFSServerGetDone:
2102 * afsclient_RPCStatOpen - open an rx connection to a server to retrieve
2107 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2109 * IN serverName - the host name where the server resides.
2111 * IN type - what type of process to query
2113 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2117 * No locks are obtained or released by this function
2125 * Returns != 0 upon successful completion.
2128 int ADMINAPI afsclient_RPCStatOpen(
2129 const void *cellHandle,
2130 const char *serverName,
2131 afs_stat_source_t type,
2132 struct rx_connection **rpcStatHandleP,
2136 afs_status_t tst = 0;
2137 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2140 struct rx_securityClass *sc;
2142 if (!CellHandleIsValid(cellHandle, &tst)) {
2143 goto fail_afsclient_RPCStatOpen;
2146 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2147 goto fail_afsclient_RPCStatOpen;
2150 if (rpcStatHandleP == NULL) {
2151 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2152 goto fail_afsclient_RPCStatOpen;
2158 servPort = AFSCONF_NANNYPORT;
2161 case AFS_FILESERVER:
2162 servPort = AFSCONF_FILEPORT;
2166 servPort = AFSCONF_KAUTHPORT;
2170 servPort = AFSCONF_PROTPORT;
2174 servPort = AFSCONF_VOLUMEPORT;
2178 servPort = AFSCONF_VLDBPORT;
2182 servPort = AFSCONF_CALLBACKPORT;
2186 tst = ADMTYPEINVALID;
2187 goto fail_afsclient_RPCStatOpen;
2191 * special processing of tokens by server type
2194 if (type == AFS_KASERVER) {
2195 if (!c_handle->tokens->kas_token_set) {
2196 tst = ADMCLIENTNOKASTOKENS;
2197 goto fail_afsclient_RPCStatOpen;
2199 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2201 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2204 *rpcStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2206 RX_STATS_SERVICE_ID,
2208 c_handle->tokens->sc_index);
2210 if (*rpcStatHandleP == NULL) {
2211 tst = ADMCLIENTRPCSTATNOCONNECTION;
2212 goto fail_afsclient_RPCStatOpen;
2216 fail_afsclient_RPCStatOpen:
2225 * afsclient_RPCStatOpenPort - open an rx connection to a server to retrieve
2230 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2232 * IN serverName - the host name where the server resides.
2234 * IN port - the UDP port number where the server resides.
2236 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2240 * No locks are obtained or released by this function
2248 * Returns != 0 upon successful completion.
2251 int ADMINAPI afsclient_RPCStatOpenPort(
2252 const void *cellHandle,
2253 const char *serverName,
2254 const int serverPort,
2255 struct rx_connection **rpcStatHandleP,
2259 afs_status_t tst = 0;
2260 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2262 struct rx_securityClass *sc;
2264 if (!CellHandleIsValid(cellHandle, &tst)) {
2265 goto fail_afsclient_RPCStatOpenPort;
2268 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2269 goto fail_afsclient_RPCStatOpenPort;
2272 if (rpcStatHandleP == NULL) {
2273 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2274 goto fail_afsclient_RPCStatOpenPort;
2278 * special processing of tokens by server type
2281 if (serverPort == AFSCONF_KAUTHPORT) {
2282 if (!c_handle->tokens->kas_token_set) {
2283 tst = ADMCLIENTNOKASTOKENS;
2284 goto fail_afsclient_RPCStatOpenPort;
2286 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2288 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2291 *rpcStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2293 RX_STATS_SERVICE_ID,
2295 c_handle->tokens->sc_index);
2297 if (*rpcStatHandleP == NULL) {
2298 tst = ADMCLIENTRPCSTATNOCONNECTION;
2299 goto fail_afsclient_RPCStatOpenPort;
2303 fail_afsclient_RPCStatOpenPort:
2312 * afsclient_RPCStatClose - close a previously opened rx connection.
2316 * IN rpcStatHandle - an rx connection returned by afsclient_RPCStatOpen
2320 * No locks are obtained or released by this function
2328 * Returns != 0 upon successful completion.
2331 int ADMINAPI afsclient_RPCStatClose(
2332 struct rx_connection *rpcStatHandle,
2336 afs_status_t tst = 0;
2338 if (rpcStatHandle == NULL) {
2339 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2340 goto fail_afsclient_RPCStatClose;
2343 rx_ReleaseCachedConnection(rpcStatHandle);
2345 fail_afsclient_RPCStatClose:
2354 * afsclient_CMStatOpen - open an rx connection to a server to retrieve
2359 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2361 * IN serverName - the host name where the server resides.
2363 * OUT cmStatHandleP - contains an rx connection to the server of interest
2367 * No locks are obtained or released by this function
2375 * Returns != 0 upon successful completion.
2378 int ADMINAPI afsclient_CMStatOpen(
2379 const void *cellHandle,
2380 const char *serverName,
2381 struct rx_connection **cmStatHandleP,
2385 afs_status_t tst = 0;
2386 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2388 struct rx_securityClass *sc;
2390 if (!CellHandleIsValid(cellHandle, &tst)) {
2391 goto fail_afsclient_CMStatOpen;
2394 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2395 goto fail_afsclient_CMStatOpen;
2398 if (cmStatHandleP == NULL) {
2399 tst = ADMCLIENTCMSTATHANDLEPNULL;
2400 goto fail_afsclient_CMStatOpen;
2403 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2405 *cmStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2406 htons(AFSCONF_CALLBACKPORT),
2409 c_handle->tokens->sc_index);
2411 if (*cmStatHandleP == NULL) {
2412 tst = ADMCLIENTCMSTATNOCONNECTION;
2413 goto fail_afsclient_CMStatOpen;
2417 fail_afsclient_CMStatOpen:
2426 * afsclient_CMStatOpenPort - open an rx connection to a server to retrieve
2431 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2433 * IN serverName - the host name where the server resides.
2435 * IN port - the UDP port number where the server resides.
2437 * OUT cmStatHandleP - contains an rx connection to the server of interest
2441 * No locks are obtained or released by this function
2449 * Returns != 0 upon successful completion.
2452 int ADMINAPI afsclient_CMStatOpenPort(
2453 const void *cellHandle,
2454 const char *serverName,
2455 const int serverPort,
2456 struct rx_connection **cmStatHandleP,
2460 afs_status_t tst = 0;
2461 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2463 struct rx_securityClass *sc;
2465 if (!CellHandleIsValid(cellHandle, &tst)) {
2466 goto fail_afsclient_CMStatOpenPort;
2469 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2470 goto fail_afsclient_CMStatOpenPort;
2473 if (cmStatHandleP == NULL) {
2474 tst = ADMCLIENTCMSTATHANDLEPNULL;
2475 goto fail_afsclient_CMStatOpenPort;
2478 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2480 *cmStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2484 c_handle->tokens->sc_index);
2486 if (*cmStatHandleP == NULL) {
2487 tst = ADMCLIENTCMSTATNOCONNECTION;
2488 goto fail_afsclient_CMStatOpenPort;
2492 fail_afsclient_CMStatOpenPort:
2501 * afsclient_CMStatClose - close a previously opened rx connection.
2505 * IN cmStatHandle - an rx connection returned by afsclient_CMStatOpen
2509 * No locks are obtained or released by this function
2517 * Returns != 0 upon successful completion.
2520 int ADMINAPI afsclient_CMStatClose(
2521 struct rx_connection *cmStatHandle,
2525 afs_status_t tst = 0;
2527 if (cmStatHandle == NULL) {
2528 tst = ADMCLIENTCMSTATHANDLEPNULL;
2529 goto fail_afsclient_CMStatClose;
2532 rx_ReleaseCachedConnection(cmStatHandle);
2534 fail_afsclient_CMStatClose:
2543 * afsclient_RXDebugOpen - open an rxdebug handle to a server.
2547 * IN serverName - the host name where the server resides.
2549 * IN type - what type of process to query
2551 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2555 * No locks are obtained or released by this function
2563 * Returns != 0 upon successful completion.
2566 int ADMINAPI afsclient_RXDebugOpen(
2567 const char *serverName,
2568 afs_stat_source_t type,
2569 rxdebugHandle_p *rxdebugHandleP,
2573 afs_status_t tst = 0;
2575 rxdebugHandle_p handle;
2576 rxdebugSocket_t sock;
2577 struct sockaddr_in taddr;
2581 if (rxdebugHandleP == NULL) {
2582 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2583 goto fail_afsclient_RXDebugOpen;
2589 serverPort = AFSCONF_NANNYPORT;
2592 case AFS_FILESERVER:
2593 serverPort = AFSCONF_FILEPORT;
2597 serverPort = AFSCONF_KAUTHPORT;
2601 serverPort = AFSCONF_PROTPORT;
2605 serverPort = AFSCONF_VOLUMEPORT;
2609 serverPort = AFSCONF_VLDBPORT;
2613 serverPort = AFSCONF_CALLBACKPORT;
2617 tst = ADMTYPEINVALID;
2618 goto fail_afsclient_RXDebugOpen;
2621 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2622 goto fail_afsclient_RXDebugOpen;
2625 sock = (rxdebugSocket_t)socket(AF_INET, SOCK_DGRAM, 0);
2626 if (sock == INVALID_RXDEBUG_SOCKET) {
2628 goto fail_afsclient_RXDebugOpen;
2631 memset(&taddr, 0, sizeof(taddr));
2632 taddr.sin_family = AF_INET;
2634 taddr.sin_addr.s_addr = INADDR_ANY;
2635 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2639 goto fail_afsclient_RXDebugOpen;
2642 handle = (rxdebugHandle_p)malloc(sizeof(rxdebugHandle_t));
2646 goto fail_afsclient_RXDebugOpen;
2649 handle->sock = sock;
2650 handle->ipAddr = serverAddr;
2651 handle->udpPort = serverPort;
2652 handle->firstFlag = 1;
2653 handle->supportedStats = 0;
2654 *rxdebugHandleP = handle;
2657 fail_afsclient_RXDebugOpen:
2666 * afsclient_RXDebugOpenPort - open an rxdebug handle to a server.
2670 * IN serverName - the host name where the server resides.
2672 * IN port - the UDP port number where the server resides.
2674 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2678 * No locks are obtained or released by this function
2686 * Returns != 0 upon successful completion.
2689 int ADMINAPI afsclient_RXDebugOpenPort(
2690 const char *serverName,
2692 rxdebugHandle_p *rxdebugHandleP,
2696 afs_status_t tst = 0;
2698 rxdebugHandle_p handle;
2699 rxdebugSocket_t sock;
2700 struct sockaddr_in taddr;
2703 if (rxdebugHandleP == NULL) {
2704 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2705 goto fail_afsclient_RXDebugOpenPort;
2708 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2709 goto fail_afsclient_RXDebugOpenPort;
2712 sock = (rxdebugSocket_t)socket(AF_INET, SOCK_DGRAM, 0);
2713 if (sock == INVALID_RXDEBUG_SOCKET) {
2715 goto fail_afsclient_RXDebugOpenPort;
2718 memset(&taddr, 0, sizeof(taddr));
2719 taddr.sin_family = AF_INET;
2721 taddr.sin_addr.s_addr = INADDR_ANY;
2722 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2726 goto fail_afsclient_RXDebugOpenPort;
2729 handle = (rxdebugHandle_p)malloc(sizeof(rxdebugHandle_t));
2733 goto fail_afsclient_RXDebugOpenPort;
2736 handle->sock = sock;
2737 handle->ipAddr = serverAddr;
2738 handle->udpPort = serverPort;
2739 handle->firstFlag = 1;
2740 handle->supportedStats = 0;
2741 *rxdebugHandleP = handle;
2744 fail_afsclient_RXDebugOpenPort:
2753 * afsclient_RXDebugClose - close a previously opened rxdebug handle.
2757 * IN rxdebugHandle - an rxdebug handle returned by afsclient_RXDebugOpen
2761 * No locks are obtained or released by this function
2769 * Returns != 0 upon successful completion.
2772 int ADMINAPI afsclient_RXDebugClose(
2773 rxdebugHandle_p rxdebugHandle,
2777 afs_status_t tst = 0;
2779 if (rxdebugHandle == NULL) {
2780 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2781 goto fail_afsclient_RXDebugClose;
2784 close(rxdebugHandle->sock);
2785 free(rxdebugHandle);
2787 fail_afsclient_RXDebugClose: