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
11 #include "afs_clientAdmin.h"
12 #include "../adminutil/afs_AdminInternal.h"
15 #include <sys/types.h>
16 #include <afs/cellconfig.h>
18 #include <afs/afssyscalls.h>
20 #include <afs/fs_utils.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
26 #include <afs/venus.h>
31 #include <afs/kautils.h>
33 #include <rx/rx_null.h>
35 #include <afs/dirpath.h>
36 #include <afs/afs_AdminErrors.h>
37 #include <afs/afs_vosAdmin.h>
38 #include <afs/afs_utilAdmin.h>
39 #include <afs/ptserver.h>
40 #include <afs/vlserver.h>
41 #include <afs/pthread_glock.h>
44 * AFS client administration functions.
46 * Admin functions that are normally associated with the client.
48 * All of the functions related to authentication are here, plus
49 * some miscellaneous others.
53 static const unsigned long ADMIN_TICKET_LIFETIME = 24*3600;
56 * We need a way to track whether or not the client library has been
57 * initialized. We count on the fact that the other library initialization
58 * functions are protected by their own once mechanism. We only track
59 * our own internal status
62 static int client_init;
63 static pthread_once_t client_init_once = PTHREAD_ONCE_INIT;
65 static void client_once(void) {
70 * IsTokenValid - validate a token handle
74 * IN token - the token to be validated.
78 * No locks are obtained or released by this function
86 * Returns != 0 upon successful completion.
89 static int IsTokenValid(
90 const afs_token_handle_p token,
97 tst = ADMCLIENTTOKENHANDLENULL;
98 goto fail_IsTokenValid;
101 if (token->is_valid == 0) {
102 tst = ADMCLIENTTOKENHANDLEINVALID;
103 goto fail_IsTokenValid;
106 if ((token->begin_magic != BEGIN_MAGIC) ||
107 (token->end_magic != END_MAGIC)) {
108 tst = ADMCLIENTTOKENHANDLEBADMAGIC;
109 goto fail_IsTokenValid;
122 * afsclient_TokenGetExisting - get tokens that already exist and
123 * are held by the cache manager.
127 * IN cellName - the name of the cell where the token originated.
129 * OUT tokenHandle - a handle to the tokens if they were obtained
134 * No locks are obtained or released by this function
138 * The tokenHandle returned by this function cannot be used for kas
139 * related operations, since kas tokens aren't stored in the kernel.
143 * Returns != 0 upon successful completion.
146 int ADMINAPI afsclient_TokenGetExisting(
147 const char *cellName,
152 afs_status_t tst = 0;
153 struct ktc_principal afs_server;
154 afs_token_handle_p t_handle = (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
156 if (client_init == 0) {
157 tst = ADMCLIENTNOINIT;
158 goto fail_afsclient_TokenGetExisting;
161 if (cellName == NULL) {
162 tst = ADMCLIENTCELLNAMENULL;
163 goto fail_afsclient_TokenGetExisting;
166 if (tokenHandle == NULL) {
167 tst = ADMCLIENTTOKENHANDLENULL;
168 goto fail_afsclient_TokenGetExisting;
171 if (t_handle == NULL) {
173 goto fail_afsclient_TokenGetExisting;
176 strcpy(afs_server.name, "afs");
177 afs_server.instance[0] = 0;
178 strcpy(afs_server.cell, cellName);
180 if (!(tst = ktc_GetToken(&afs_server, &t_handle->afs_token,
181 sizeof(t_handle->afs_token),
182 &t_handle->client))) {
184 * The token has been retrieved successfully, initialize
185 * the rest of the token handle structure
187 strcpy(t_handle->cell, cellName);
188 t_handle->afs_token_set = 1;
189 t_handle->from_kernel = 1;
190 t_handle->kas_token_set = 0;
191 t_handle->sc_index = 2;
192 t_handle->afs_sc[t_handle->sc_index] =
193 rxkad_NewClientSecurityObject(rxkad_clear,
194 &t_handle->afs_token.sessionKey,
195 t_handle->afs_token.kvno,
196 t_handle->afs_token.ticketLen,
197 t_handle->afs_token.ticket);
198 t_handle->afs_encrypt_sc[t_handle->sc_index] =
199 rxkad_NewClientSecurityObject(rxkad_crypt,
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 if ((t_handle->afs_sc[t_handle->sc_index] == NULL) ||
205 (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
206 tst = ADMCLIENTTOKENHANDLENOSECURITY;
207 goto fail_afsclient_TokenGetExisting;
209 t_handle->begin_magic = BEGIN_MAGIC;
210 t_handle->is_valid = 1;
211 t_handle->end_magic = END_MAGIC;
212 *tokenHandle = (void *) t_handle;
215 goto fail_afsclient_TokenGetExisting;
219 fail_afsclient_TokenGetExisting:
221 if ((rc == 0) && (t_handle != NULL)) {
231 * afsclient_TokenSet - set the tokens represented by tokenHandle to be
232 * active in the kernel (aka ka_SetToken).
236 * IN cellName - the name of the cell where the token originated.
238 * OUT tokenHandle - a handle to the tokens if they were obtained
243 * No locks are obtained or released by this function
247 * The tokenHandle returned by this function cannot be used for kas
248 * related operations, since kas tokens aren't stored in the kernel.
252 * Returns != 0 upon successful completion.
255 int ADMINAPI afsclient_TokenSet(
256 const void *tokenHandle,
260 afs_status_t tst = 0;
261 struct ktc_principal afs_server;
262 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
264 if (!IsTokenValid(t_handle, &tst)) {
265 goto fail_afsclient_TokenSet;
268 strcpy(afs_server.name, "afs");
269 afs_server.instance[0] = 0;
270 strcpy(afs_server.cell, t_handle->cell);
272 tst = ktc_SetToken(&afs_server, &t_handle->afs_token, &t_handle->client, 0);
278 fail_afsclient_TokenSet:
287 * GetKASToken - get a KAS token and store it in the tokenHandle.
291 * IN cellName - the name of the cell where the token should be obtained.
293 * IN principal - the name of the user of the token.
295 * IN password - the password for the principal.
297 * OUT tokenHandle - a handle to the tokens if they were obtained
302 * No locks are obtained or released by this function
310 * Returns != 0 upon successful completion.
313 static int GetKASToken(
314 const char *cellName,
315 const char *principal,
316 const char *password,
317 afs_token_handle_p tokenHandle,
321 afs_status_t tst = 0;
322 struct ubik_client *unauth_conn;
324 struct ktc_encryptionKey key;
325 struct ktc_token *token;
326 unsigned long now = time(0);
327 char name[MAXKTCNAMELEN];
328 char inst[MAXKTCNAMELEN];
329 int have_server_conn = 0;
331 token = &tokenHandle->kas_token;
333 ka_StringToKey((char *)password, (char *)cellName, &key);
336 * Get an unauthenticated connection in the right cell to use for
337 * retrieving the token.
340 tst = ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
343 goto fail_GetKASToken;
345 have_server_conn = 1;
347 tst = ka_ParseLoginName((char *)principal, name, inst, (char *) 0);
349 goto fail_GetKASToken;
352 tst = ka_Authenticate(name, inst, (char *)cellName, unauth_conn,
353 KA_MAINTENANCE_SERVICE, &key, now,
354 now+ADMIN_TICKET_LIFETIME, token, &expire);
356 goto fail_GetKASToken;
362 if (have_server_conn) {
363 ubik_ClientDestroy(unauth_conn);
373 * GetAFSToken - get a AFS token and store it in the tokenHandle.
377 * IN cellName - the name of the cell where the token should be obtained.
379 * IN principal - the name of the user of the token.
381 * IN password - the password for the principal.
383 * OUT tokenHandle - a handle to the tokens if they were obtained
388 * No locks are obtained or released by this function
396 * Returns != 0 upon successful completion.
399 static int GetAFSToken(
400 const char *cellName,
401 const char *principal,
402 const char *password,
403 afs_token_handle_p tokenHandle,
407 afs_status_t tst = 0;
408 struct ubik_client *unauth_conn = NULL, *auth_conn = NULL;
410 struct ktc_encryptionKey key;
411 struct ktc_token auth_token;
412 struct ktc_token *token;
413 unsigned long now = time(0);
415 token = &tokenHandle->afs_token;
417 ka_StringToKey((char *)password, (char *)cellName, &key);
420 * Get an unauthenticated connection in the right cell to use for
421 * retrieving the token.
424 tst = ka_AuthServerConn((char *)cellName, KA_AUTHENTICATION_SERVICE, 0,
427 goto fail_GetAFSToken;
430 tst = ka_ParseLoginName((char *)principal, tokenHandle->client.name,
431 tokenHandle->client.instance, (char *) 0);
433 goto fail_GetAFSToken;
436 tst = ka_Authenticate(tokenHandle->client.name,
437 tokenHandle->client.instance, (char *)cellName,
438 unauth_conn, KA_TICKET_GRANTING_SERVICE,
439 &key, now, now+ADMIN_TICKET_LIFETIME,
440 &auth_token, &expire);
442 goto fail_GetAFSToken;
445 tst = ka_AuthServerConn((char *)cellName, KA_TICKET_GRANTING_SERVICE,
448 goto fail_GetAFSToken;
451 tst = ka_CellToRealm((char *)cellName, tokenHandle->client.cell, (int *) 0);
453 goto fail_GetAFSToken;
456 tst = ka_GetToken("afs", "", (char *)cellName,
457 tokenHandle->client.name,
458 tokenHandle->client.instance,
460 now+ADMIN_TICKET_LIFETIME,
461 &auth_token, tokenHandle->client.cell,
464 goto fail_GetAFSToken;
471 ubik_ClientDestroy(auth_conn);
475 ubik_ClientDestroy(unauth_conn);
486 * afsclient_TokenGetNew - get new tokens for a user and store them
487 * in the tokenHandle.
491 * IN cellName - the name of the cell where the tokens should be obtained.
493 * IN principal - the name of the user of the tokens.
495 * IN password - the password for the principal.
497 * OUT tokenHandle - a handle to the tokens if they were obtained
502 * No locks are obtained or released by this function
510 * Returns != 0 upon successful completion.
513 int ADMINAPI afsclient_TokenGetNew(
514 const char *cellName,
515 const char *principal,
516 const char *password,
521 afs_status_t tst = 0;
522 afs_token_handle_p t_handle = (afs_token_handle_p) calloc(1, sizeof(afs_token_handle_t));
524 if (client_init == 0) {
525 tst = ADMCLIENTNOINIT;
526 goto fail_afsclient_TokenGetNew;
529 if (t_handle == NULL) {
531 goto fail_afsclient_TokenGetNew;
535 * Check to see if the principal or password is missing. If it is,
536 * get unauthenticated tokens for the cell
539 if ((principal == NULL) || (*principal == 0) ||
540 (password == NULL) || (*password == 0)) {
541 t_handle->from_kernel = 0;
542 t_handle->afs_token_set = 1;
543 t_handle->kas_token_set = 1;
544 t_handle->sc_index = 0;
545 t_handle->afs_sc[t_handle->sc_index] =
546 rxnull_NewClientSecurityObject();
547 t_handle->afs_encrypt_sc[t_handle->sc_index] =
548 rxnull_NewClientSecurityObject();
549 t_handle->kas_sc[t_handle->sc_index] =
550 rxnull_NewClientSecurityObject();
551 t_handle->begin_magic = BEGIN_MAGIC;
552 t_handle->is_valid = 1;
553 t_handle->afs_token.endTime = 0;
554 t_handle->end_magic = END_MAGIC;
555 *tokenHandle = (void *) t_handle;
560 * create an authenticated token
563 if ((GetAFSToken(cellName, principal, password, t_handle, &tst)) &&
564 (GetKASToken(cellName, principal, password, t_handle, &tst))) {
565 strcpy(t_handle->cell, cellName);
566 t_handle->from_kernel = 0;
567 t_handle->afs_token_set = 1;
568 t_handle->kas_token_set = 1;
569 t_handle->sc_index = 2;
570 t_handle->afs_sc[t_handle->sc_index] =
571 rxkad_NewClientSecurityObject(rxkad_clear,
572 &t_handle->afs_token.sessionKey,
573 t_handle->afs_token.kvno,
574 t_handle->afs_token.ticketLen,
575 t_handle->afs_token.ticket);
576 t_handle->afs_encrypt_sc[t_handle->sc_index] =
577 rxkad_NewClientSecurityObject(rxkad_crypt,
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->kas_sc[t_handle->sc_index] =
583 rxkad_NewClientSecurityObject(rxkad_crypt,
584 &t_handle->kas_token.sessionKey,
585 t_handle->kas_token.kvno,
586 t_handle->kas_token.ticketLen,
587 t_handle->kas_token.ticket);
588 if ((t_handle->afs_sc[t_handle->sc_index] != NULL) &&
589 (t_handle->afs_encrypt_sc[t_handle->sc_index] != NULL) &&
590 (t_handle->kas_sc[t_handle->sc_index] != NULL)) {
591 t_handle->begin_magic = BEGIN_MAGIC;
592 t_handle->is_valid = 1;
593 t_handle->end_magic = END_MAGIC;
594 *tokenHandle = (void *) t_handle;
596 tst = ADMCLIENTTOKENHANDLENOSECURITY;
597 goto fail_afsclient_TokenGetNew;
600 goto fail_afsclient_TokenGetNew;
605 fail_afsclient_TokenGetNew:
607 if ((rc == 0) && (t_handle != NULL)) {
618 * afsclient_TokenQuery - get the expiration time of the tokens.
622 * IN tokenHandle - a previously obtained valid token.
624 * OUT expirationDateP - the time at which the tokens expire.
626 * OUT principal - the owning principal
628 * OUT instance - principal instance if it exists.
630 * OUT cell - the principal's cell
632 * OUT hasKasTokens - set to 1 if the token handle contains kas tokens.
636 * No locks are obtained or released by this function
640 * We only check the AFS tokens since we always get these. The
641 * KAS tokens may expirer later than the AFS tokens, but this
642 * difference is minor and reporting an earlier time won't cause
647 * Returns != 0 upon successful completion.
650 int ADMINAPI afsclient_TokenQuery(
652 unsigned long *expirationDateP,
660 afs_status_t tst = 0;
661 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
663 if (client_init == 0) {
664 tst = ADMCLIENTNOINIT;
666 goto fail_afsclient_TokenQuery;
669 if (IsTokenValid(t_handle, &tst)) {
670 if (principal != NULL) {
671 strcpy(principal, t_handle->client.name);
673 if (instance != NULL) {
674 strcpy(instance, t_handle->client.instance);
677 strcpy(cell, t_handle->client.cell);
679 if (hasKasTokens != NULL) {
680 *hasKasTokens = t_handle->kas_token_set;
682 if (expirationDateP != NULL) {
683 *expirationDateP = t_handle->afs_token.endTime;
688 fail_afsclient_TokenQuery:
697 * afsclient_TokenClose - close an existing token.
701 * IN token - the token to be closed.
705 * No locks are obtained or released by this function
713 * Returns != 0 upon successful completion.
716 int ADMINAPI afsclient_TokenClose(
717 const void *tokenHandle,
721 afs_status_t tst = 0;
722 afs_token_handle_p t_handle = (afs_token_handle_p) tokenHandle;
724 if (client_init == 0) {
725 tst = ADMCLIENTNOINIT;
726 goto fail_afsclient_TokenClose;
729 if (IsTokenValid(t_handle, &tst)) {
730 t_handle->is_valid = 0;
735 fail_afsclient_TokenClose:
743 #define NUM_SERVER_TYPES 3
745 /* must match NUM_SERVER_TYPES */
746 typedef enum {KAS, PTS, VOS} afs_server_list_t;
748 typedef struct afs_server {
751 struct ubik_client **ubik;
752 struct rx_securityClass *sc;
754 } afs_server_t, *afs_server_p;
756 static afs_server_t servers[NUM_SERVER_TYPES]
757 = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
758 {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
759 {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}};
762 * afsclient_CellOpen - Open a particular cell for work as a particular
767 * IN cellName - the cell where future admin calls will be made.
769 * IN tokenHandle - the tokens work will be done under.
771 * OUT cellHandleP - an opaque pointer that is the first parameter to
772 * almost all subsequent admin api calls.
776 * No locks are obtained or released by this function
784 * Returns != 0 upon successful completion.
787 int ADMINAPI afsclient_CellOpen(
788 const char *cellName,
789 const void *tokenHandle,
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 if (client_init == 0) {
807 tst = ADMCLIENTNOINIT;
808 goto fail_afsclient_CellOpen;
811 if (c_handle == NULL) {
813 goto fail_afsclient_CellOpen;
816 if (t_handle == NULL) {
817 tst = ADMCLIENTTOKENHANDLENULL;
818 goto fail_afsclient_CellOpen;
821 if ((cellName == NULL) || (*cellName == 0)) {
822 tst = ADMCLIENTCELLNAMENULL;
823 goto fail_afsclient_CellOpen;
826 if (cellHandleP == NULL) {
827 tst = ADMCLIENTCELLHANDLEPNULL;
828 goto fail_afsclient_CellOpen;
832 * Check that the token handle contains valid data and the calloc
835 if (!t_handle->afs_token_set) {
836 tst = ADMCLIENTCELLOPENBADTOKEN;
837 goto fail_afsclient_CellOpen;
841 * Use a table to initialize the cell handle structure, since
842 * most of the steps are the same for all the servers.
844 * Start by creating rx_securityClass objects for each of the
845 * servers. A potential optimization is to do this in
846 * afsclient_TokenGetNew and just keep the expiration time of
848 * Also, initialize the ubik client pointers in the table
850 servers[KAS].sc = t_handle->kas_sc[t_handle->sc_index];
851 servers[PTS].sc = t_handle->afs_sc[t_handle->sc_index];
852 servers[VOS].sc = servers[PTS].sc;
853 servers[KAS].ubik = &c_handle->kas;
854 servers[PTS].ubik = &c_handle->pts;
855 servers[VOS].ubik = &c_handle->vos;
856 servers[KAS].valid = &c_handle->kas_valid;
857 servers[PTS].valid = &c_handle->pts_valid;
858 servers[VOS].valid = &c_handle->vos_valid;
859 c_handle->vos_new = 1;
861 if ((servers[PTS].sc == NULL) || (servers[VOS].sc == NULL)) {
862 tst = ADMCLIENTBADTOKENHANDLE;
863 goto fail_afsclient_CellOpen;
867 * If the initialization has succeeded so far, get the address
868 * information for each server in the cell
871 strcpy(c_handle->working_cell, cellName);
872 if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
873 tst = ADMCLIENTBADCLIENTCONFIG;
874 goto fail_afsclient_CellOpen;
878 * We must copy the cellName here because afsconf_GetCellInfo
879 * actually writes over the cell name it is passed.
881 strncpy(copyCell, cellName, MAXCELLCHARS - 1);
882 for(i=0;(i<NUM_SERVER_TYPES);i++) {
884 tst = ka_AuthServerConn((char *)cellName,servers[i].serviceId,
885 ((t_handle->sc_index == 0) ||
886 (!t_handle->kas_token_set)) ?
887 0 : &t_handle->kas_token,
890 goto fail_afsclient_CellOpen;
893 tst = afsconf_GetCellInfo(tdir, copyCell,
894 servers[i].serv, &info);
896 /* create ubik client handles for each server */
897 scIndex = t_handle->sc_index;
898 sc[scIndex] = servers[i].sc;
899 for(j=0;(j<info.numServers);j++) {
901 rx_GetCachedConnection(
902 info.hostAddr[j].sin_addr.s_addr,
903 info.hostAddr[j].sin_port,
904 servers[i].serviceId,
905 sc[scIndex], scIndex);
908 tst = ubik_ClientInit(serverconns,servers[i].ubik);
910 goto fail_afsclient_CellOpen;
913 goto fail_afsclient_CellOpen;
916 /* initialization complete, mark handle valid */
917 *servers[i].valid = 1;
919 c_handle->tokens = t_handle;
922 fail_afsclient_CellOpen:
929 * Upon error, free any obtained resources.
932 if (c_handle != NULL) {
933 if (c_handle->kas_valid) ubik_ClientDestroy(c_handle->kas);
934 if (c_handle->pts_valid) ubik_ClientDestroy(c_handle->pts);
935 if (c_handle->vos_valid) ubik_ClientDestroy(c_handle->vos);
939 c_handle->begin_magic = BEGIN_MAGIC;
940 c_handle->is_valid = 1;
941 c_handle->is_null = 0;
942 c_handle->end_magic = END_MAGIC;
943 *cellHandleP = (void *) c_handle;
953 * afsclient_NullCellOpen - open a null cell handle for access.
957 * OUT cellHandleP - an opaque pointer that is the first parameter to
958 * almost all subsequent admin api calls.
962 * No locks are obtained or released by this function
970 * Returns != 0 upon successful completion.
973 int ADMINAPI afsclient_NullCellOpen(
978 afs_status_t tst = 0;
979 afs_cell_handle_p c_handle = (afs_cell_handle_p)
980 calloc(1, sizeof(afs_cell_handle_t));
984 * Validate parameters
987 if (cellHandleP == NULL) {
988 tst = ADMCLIENTCELLHANDLEPNULL;
989 goto fail_afsclient_NullCellOpen;
992 if (client_init == 0) {
993 tst = ADMCLIENTNOINIT;
994 goto fail_afsclient_NullCellOpen;
997 if (c_handle == NULL) {
999 goto fail_afsclient_NullCellOpen;
1003 * Get unauthenticated tokens for any cell
1006 if (!afsclient_TokenGetNew(0, 0, 0, (void *) &c_handle->tokens, &tst)) {
1007 goto fail_afsclient_NullCellOpen;
1010 c_handle->begin_magic = BEGIN_MAGIC;
1011 c_handle->is_valid = 1;
1012 c_handle->is_null = 1;
1013 c_handle->end_magic = END_MAGIC;
1014 c_handle->kas_valid = 0;
1015 c_handle->pts_valid = 0;
1016 c_handle->vos_valid = 0;
1020 *cellHandleP = (void *) c_handle;
1023 fail_afsclient_NullCellOpen:
1032 * afsclient_CellClose - close a previously opened cellHandle.
1036 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
1040 * No locks are obtained or released by this function
1048 * Returns != 0 upon successful completion.
1051 int ADMINAPI afsclient_CellClose(
1052 const void *cellHandle,
1056 afs_status_t tst = 0;
1057 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1059 if (client_init == 0) {
1060 tst = ADMCLIENTNOINIT;
1061 goto fail_afsclient_CellClose;
1064 if (c_handle == NULL) {
1065 tst = ADMCLIENTCELLHANDLENULL;
1066 goto fail_afsclient_CellClose;
1069 if (c_handle->kas_valid) ubik_ClientDestroy(c_handle->kas);
1070 if (c_handle->pts_valid) ubik_ClientDestroy(c_handle->pts);
1071 if (c_handle->vos_valid) ubik_ClientDestroy(c_handle->vos);
1072 if (c_handle->is_null) afsclient_TokenClose(c_handle->tokens, 0);
1073 c_handle->kas_valid = 0;
1074 c_handle->pts_valid = 0;
1075 c_handle->vos_valid = 0;
1076 c_handle->is_valid = 0;
1080 fail_afsclient_CellClose:
1090 * afsclient_CellNameGet() -- get a pointer to the cell name in a cell handle
1094 * IN cellHandle - a valid cell handle
1095 * OUT cellNameP - a pointer to the cell name in the cell handle.
1099 * No locks are obtained or released by this function
1103 * If cellHandle is closed then the pointer returned by this function
1104 * is no longer valid.
1108 * Returns != 0 upon successful completion.
1110 int ADMINAPI afsclient_CellNameGet(
1111 const void *cellHandle,
1112 const char **cellNameP,
1116 afs_status_t tst = 0;
1117 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1119 if (!CellHandleIsValid(cellHandle, &tst)) {
1120 goto fail_afsclient_CellNameGet;
1123 *cellNameP = c_handle->working_cell;
1126 fail_afsclient_CellNameGet:
1136 * afsclient_LocalCellGet - get the name of the cell the machine
1137 * belongs to where this process is running.
1141 * OUT cellName - an array of characters that must be MAXCELLCHARS
1146 * No locks are obtained or released by this function
1150 * If cellName is smaller than MAXCELLCHARS chars, this function won't
1155 * Returns != 0 upon successful completion.
1158 int ADMINAPI afsclient_LocalCellGet(
1163 afs_status_t tst = 0;
1164 struct afsconf_dir *tdir = NULL;
1166 if (client_init == 0) {
1167 tst = ADMCLIENTNOINIT;
1168 goto fail_afsclient_LocalCellGet;
1171 if (cellName == NULL) {
1172 tst = ADMCLIENTCELLNAMENULL;
1173 goto fail_afsclient_LocalCellGet;
1176 tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
1179 tst = ADMCLIENTBADCLIENTCONFIG;
1180 goto fail_afsclient_LocalCellGet;
1183 if (tst = afsconf_GetLocalCell(tdir, cellName, MAXCELLCHARS)) {
1184 goto fail_afsclient_LocalCellGet;
1189 fail_afsclient_LocalCellGet:
1192 afsconf_Close(tdir);
1204 static int client_ExtractDriveLetter(
1209 if (path[0] != 0 && path[1] == ':') {
1218 * Determine the parent directory of a give directory
1223 char *parentDirectory)
1228 strcpy(parentDirectory, directory);
1229 tp = strrchr(parentDirectory, '\\');
1231 /* lv trailing slash so Parent("k:\foo") is "k:\" not "k :" */
1236 if (client_ExtractDriveLetter(parentDirectory)) {
1237 strcat(parentDirectory, ".");
1247 * Determine the parent directory of a give directory
1250 const char *directory,
1251 char *parentDirectory)
1256 strcpy(parentDirectory, directory);
1257 tp = rindex(parentDirectory, '/');
1263 strcpy(parentDirectory, ".");
1272 * afsclient_MountPointCreate - create a mount point for a volume.
1276 * IN cellHandle - a handle to the cell where volumeName resides.
1278 * IN directory - the directory where the mountpoint should be created.
1280 * IN volumeName - the name of the volume to mount.
1282 * IN volType - the type of mount point to create.
1284 * IN volCheck - indicates whether or not to check the VLDB to see if
1285 * volumeName exists.
1289 * No locks are obtained or released by this function
1293 * Returns != 0 upon successful completion.
1296 #define TMP_DATA_SIZE 2048
1298 int ADMINAPI afsclient_MountPointCreate(
1299 const void *cellHandle,
1300 const char *directory,
1301 const char *volumeName,
1303 vol_check_t volCheck,
1307 afs_status_t tst = 0;
1308 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1309 char parent_dir[TMP_DATA_SIZE];
1310 char space[TMP_DATA_SIZE];
1311 char directoryCell[MAXCELLCHARS];
1312 struct ViceIoctl idata;
1314 vos_vldbEntry_t vldbEntry;
1317 * Validate arguments
1320 if (client_init == 0) {
1321 tst = ADMCLIENTNOINIT;
1322 goto fail_afsclient_MountPointCreate;
1325 if ((directory == NULL) || (*directory == 0)) {
1326 tst = ADMCLIENTDIRECTORYNULL;
1327 goto fail_afsclient_MountPointCreate;
1330 if ((volumeName == NULL) || (*volumeName == 0)) {
1331 tst = ADMCLIENTVOLUMENAME;
1332 goto fail_afsclient_MountPointCreate;
1336 * Extract the parent directory and make sure it is in AFS.
1339 if (!Parent(directory, parent_dir)) {
1340 tst = ADMCLIENTBADDIRECTORY;
1341 goto fail_afsclient_MountPointCreate;
1345 idata.out_size = TMP_DATA_SIZE;
1347 i = pioctl(parent_dir, VIOC_FILE_CELL_NAME, &idata, 1);
1349 if ((errno == EINVAL) || (errno == ENOENT)) {
1350 tst = ADMCLIENTNOAFSDIRECTORY;
1351 goto fail_afsclient_MountPointCreate;
1354 strcpy(directoryCell, space);
1357 * If the user requested, check that the volume exists
1360 if (volCheck == CHECK_VOLUME) {
1361 if (!vos_VLDBGet(cellHandle, 0, 0, volumeName, &vldbEntry, &tst)) {
1362 goto fail_afsclient_MountPointCreate;
1367 * Begin constructing the pioctl buffer
1370 if (volType == READ_WRITE) {
1377 * Append the cell to the mount point if the volume is in a different
1378 * cell than the directory
1381 if (strcmp(c_handle->working_cell, directoryCell)) {
1382 strcat(space, c_handle->working_cell);
1385 strcat(space, volumeName);
1392 idata.in_size = 1 + strlen(space);
1394 if (tst = pioctl(directory, VIOC_AFS_CREATE_MT_PT, &idata, 0)) {
1395 goto fail_afsclient_MountPointCreate;
1398 if (tst = symlink(space, directory)) {
1399 goto fail_afsclient_MountPointCreate;
1405 fail_afsclient_MountPointCreate:
1413 typedef struct Acl {
1420 int ADMINAPI afsclient_ACLEntryAdd(
1421 const char *directory,
1427 afs_status_t tst = 0;
1428 struct ViceIoctl idata;
1429 char old_acl_string[2048];
1430 char new_acl_string[2048];
1440 if (client_init == 0) {
1441 tst = ADMCLIENTNOINIT;
1442 goto fail_afsclient_ACLEntryAdd;
1445 if ((directory == NULL) || (*directory == 0)) {
1446 tst = ADMMISCDIRECTORYNULL;
1447 goto fail_afsclient_ACLEntryAdd;
1450 if ((user == NULL) || (*user == 0)) {
1451 tst = ADMMISCUSERNULL;
1452 goto fail_afsclient_ACLEntryAdd;
1456 tst = ADMMISCACLNULL;
1457 goto fail_afsclient_ACLEntryAdd;
1460 if (acl->read == READ) {
1464 if (acl->write == WRITE) {
1468 if (acl->insert == INSERT) {
1472 if (acl->lookup == LOOKUP) {
1476 if (acl->del == DELETE) {
1480 if (acl->lock == LOCK) {
1484 if (acl->admin == ADMIN) {
1489 * Get the current acl for the directory
1492 idata.out_size = 2048;
1494 idata.in = idata.out = old_acl_string;
1495 tst = pioctl(directory, VIOCGETAL, &idata, 1);
1498 goto fail_afsclient_ACLEntryAdd;
1502 * The acl is presented to us in string format. The format of the
1505 * A header which contains the number of positive and negative entries
1506 * and a string indicating whether or not this is a dfs acl:
1508 * num_pos "\n" dfs_string "\n" num_neg
1510 * An entry for each acl that's of the form:
1514 * There are no blanks in the string between fields, but I use them here
1515 * to make the reading easier.
1517 * Since we are only going to add another entry to the acl, our approach
1518 * is simple. Get the num_pos dfs_string and num_neg from the current acl,
1519 * increment num_pos by one and create a new string. Concatenate the new
1520 * user and rights to the new string, and then concatenate the remaining
1521 * contents of the old acl to the new string.
1523 * Unfortunately, this approach doesn't work since the format the kernel
1524 * hands the acl back to us in, is NOT WHAT IT WANTS BACK!!!!
1525 * So instead we need to parse the entire freaking acl and put a space
1526 * between each user and their acl.
1528 * This is really ugly.
1532 * Parse the first few fields of the acl and see if this is a DFS
1536 is_dfs = sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs, &cur_acl.cell);
1537 ptr = strchr(old_acl_string, '\n');
1539 sscanf(ptr, "%d", &cur_acl.nminus);
1540 ptr = strchr(ptr, '\n');
1543 tst = ADMMISCNODFSACL;
1544 goto fail_afsclient_ACLEntryAdd;
1547 * It isn't a DFS file, so create the beginning of the string
1548 * we will hand back to the kernel
1550 sprintf(new_acl_string, "%d\n%d\n%s %d\n", (cur_acl.nplus + 1),
1551 cur_acl.nminus, user, newacl);
1555 * Finish scanning the old acl, parsing each user/acl pair and
1556 * adding a space in the new acl.
1559 for(i=0;i<(cur_acl.nplus + cur_acl.nminus);i++) {
1560 sscanf(ptr, "%s%d\n", &cur_user, &cur_user_acl);
1562 * Skip the entry for the user we are replacing/adding
1565 if (strcmp(cur_user, user)) {
1566 ptr = strchr(ptr, '\n');
1568 sprintf(tmp, "%s %d\n", cur_user, cur_user_acl);
1569 strcat(new_acl_string, tmp);
1573 strcat(new_acl_string, ptr);
1580 idata.in_size = strlen(new_acl_string) + 1;
1581 idata.in = idata.out = new_acl_string;
1582 tst = pioctl(directory, VIOCSETAL, &idata, 1);
1585 goto fail_afsclient_ACLEntryAdd;
1589 fail_afsclient_ACLEntryAdd:
1598 * afsclient_Init - initialize AFS components before use.
1604 * No locks are obtained or released by this function
1612 * Returns != 0 upon successful completion.
1615 int ADMINAPI afsclient_Init(
1619 afs_status_t tst = 0;
1621 (client_init || pthread_once(&client_init_once, client_once));
1624 if (afs_winsockInit() < 0) {
1625 tst = ADMCLIENTCANTINITWINSOCK;
1626 goto fail_afsclient_Init;
1630 if (!(initAFSDirPath() & AFSDIR_CLIENT_PATHS_OK)) {
1631 tst = ADMCLIENTCANTINITAFSLOCATION;
1632 goto fail_afsclient_Init;
1635 if (rx_Init(0) < 0) {
1636 tst = ADMCLIENTCANTINITRX;
1637 goto fail_afsclient_Init;
1640 if (tst = ka_CellConfig((char *)AFSDIR_CLIENT_ETC_DIRPATH)) {
1641 goto fail_afsclient_Init;
1646 fail_afsclient_Init:
1655 * afsclient_AFSServerGet - determine what kind of server serverName
1656 * is and fill in serverEntryP accordingly.
1660 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1662 * IN serverName - the hostname of the server of interest.
1664 * OUT serverEntryP - upon successful completion contains a description of
1669 * No locks are obtained or released by this function
1677 * Returns != 0 upon successful completion.
1680 int ADMINAPI afsclient_AFSServerGet(
1681 const void *cellHandle,
1682 const char *serverName,
1683 afs_serverEntry_p serverEntryP,
1687 afs_status_t tst = 0;
1689 int found_match = 0;
1691 if ((serverName == NULL) || (*serverName == 0)) {
1692 tst = ADMUTILSERVERNAMENULL;
1693 goto fail_afsclient_AFSServerGet;
1696 if (serverEntryP == NULL) {
1697 tst = ADMUTILSERVERENTRYPNULL;
1698 goto fail_afsclient_AFSServerGet;
1702 * Iterate over server entries and try to find a match for serverName
1705 if (!afsclient_AFSServerGetBegin(cellHandle, &iter, &tst)) {
1706 goto fail_afsclient_AFSServerGet;
1709 while(afsclient_AFSServerGetNext(iter, serverEntryP, &tst)) {
1710 if (!strcmp(serverName, serverEntryP->serverName)) {
1717 * If we didn't find a match, the iterator should have terminated
1718 * normally. If it didn't, return the error
1722 if (tst != ADMITERATORDONE) {
1723 afsclient_AFSServerGetDone(iter, 0);
1725 afsclient_AFSServerGetDone(iter, &tst);
1727 tst = ADMCLIENTNOMATCHINGSERVER;
1728 goto fail_afsclient_AFSServerGet;
1730 if (!afsclient_AFSServerGetDone(iter, &tst)) {
1731 goto fail_afsclient_AFSServerGet;
1736 fail_afsclient_AFSServerGet:
1745 * The iterator functions and data for the server retrieval functions
1748 typedef struct server_get {
1751 afs_serverEntry_t server[MAXHOSTSPERCELL + BADSERVERID];
1752 afs_serverEntry_t cache[CACHED_ITEMS];
1753 } server_get_t, *server_get_p;
1755 static int GetServerRPC(
1759 int *last_item_contains_data,
1763 afs_status_t tst = 0;
1764 server_get_p serv = (server_get_p) rpc_specific;
1766 memcpy(&serv->cache[slot], &serv->server[serv->index],
1767 sizeof(afs_serverEntry_t));
1770 if (serv->index == serv->total) {
1772 *last_item_contains_data = 1;
1784 static int GetServerFromCache(
1791 afs_status_t tst = 0;
1792 server_get_p serv = (server_get_p) rpc_specific;
1794 memcpy(dest, (const void *) &serv->cache[slot], sizeof(afs_serverEntry_t));
1804 * afsclient_AFSServerGetBegin - start the process of iterating over
1805 * every server in the cell.
1809 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1811 * OUT iterationIdP - - upon successful completion contains an iterator
1812 * that can be passed to afsclient_AFSServerGetNext.
1816 * No locks are obtained or released by this function
1824 * Returns != 0 upon successful completion.
1827 int ADMINAPI afsclient_AFSServerGetBegin(
1828 const void *cellHandle,
1829 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 = (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
1836 server_get_p serv = (server_get_p) calloc(1, sizeof(server_get_t));
1837 const char *cellName;
1838 void *database_iter;
1839 util_databaseServerEntry_t database_entry;
1840 void *fileserver_iter;
1841 vos_fileServerEntry_t fileserver_entry;
1842 int iserv,iservaddr,ientryaddr, is_dup;
1843 struct hostent *host;
1845 if (!CellHandleIsValid(c_handle, &tst)) {
1846 goto fail_afsclient_AFSServerGetBegin;
1849 if (iterationIdP == NULL) {
1850 tst = ADMITERATIONIDPNULL;
1851 goto fail_afsclient_AFSServerGetBegin;
1854 if ((serv == NULL) || (iter == NULL)) {
1856 goto fail_afsclient_AFSServerGetBegin;
1860 * Retrieve the list of database servers for this cell.
1863 if (!afsclient_CellNameGet(cellHandle, &cellName, &tst)) {
1864 goto fail_afsclient_AFSServerGetBegin;
1867 if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
1868 goto fail_afsclient_AFSServerGetBegin;
1871 while(util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
1872 serv->server[serv->total].serverAddress[0] = database_entry.serverAddress;
1873 serv->server[serv->total].serverType = DATABASE_SERVER;
1877 if (tst != ADMITERATORDONE) {
1878 util_DatabaseServerGetDone(database_iter, 0);
1879 goto fail_afsclient_AFSServerGetBegin;
1882 if (!util_DatabaseServerGetDone(database_iter, &tst)) {
1883 goto fail_afsclient_AFSServerGetBegin;
1887 * Retrieve the list of file servers for this cell.
1890 if (!vos_FileServerGetBegin(cellHandle, 0, &fileserver_iter, &tst)) {
1891 goto fail_afsclient_AFSServerGetBegin;
1894 while(vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
1896 * See if any of the addresses returned in this fileserver_entry
1897 * structure already exist in the list of servers we're building.
1898 * If not, create a new record for this server.
1901 for(iserv=0;iserv<serv->total;iserv++) {
1902 for(ientryaddr=0; ientryaddr<fileserver_entry.count; ientryaddr++) {
1903 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1904 if (serv->server[iserv].serverAddress[iservaddr] ==
1905 fileserver_entry.serverAddress[ientryaddr]) {
1920 serv->server[iserv].serverType |= FILE_SERVER;
1922 iserv = serv->total++;
1923 serv->server[iserv].serverType = FILE_SERVER;
1927 * Add the addresses from the vldb list to the serv->server[iserv]
1928 * record. Remember that VLDB's list-of-addrs is not guaranteed
1929 * to be unique in a particular entry, or to return only one entry
1930 * per machine--so when we add addresses, always check for
1931 * duplicate entries.
1934 for(ientryaddr=0;ientryaddr<fileserver_entry.count;ientryaddr++) {
1935 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1936 if (serv->server[iserv].serverAddress[iservaddr] ==
1937 fileserver_entry.serverAddress[ientryaddr]) {
1941 if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
1942 for(iservaddr=0;iservaddr<AFS_MAX_SERVER_ADDRESS;iservaddr++) {
1943 if (!serv->server[iserv].serverAddress[iservaddr]) {
1944 serv->server[iserv].serverAddress[iservaddr] =
1945 fileserver_entry.serverAddress[ientryaddr];
1953 if (tst != ADMITERATORDONE) {
1954 vos_FileServerGetDone(fileserver_iter, 0);
1955 goto fail_afsclient_AFSServerGetBegin;
1958 if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
1959 goto fail_afsclient_AFSServerGetBegin;
1963 * Iterate over the list and fill in the hostname of each of the servers
1967 for(iserv=0;iserv<serv->total;iserv++) {
1968 int addr = htonl(serv->server[iserv].serverAddress[0]);
1969 host = gethostbyaddr((const char *) &addr, sizeof(int), AF_INET);
1971 strncpy(serv->server[iserv].serverName, host->h_name,
1972 AFS_MAX_SERVER_NAME_LEN);
1977 if (IteratorInit(iter, (void *) serv, GetServerRPC, GetServerFromCache,
1978 NULL, NULL, &tst)) {
1979 *iterationIdP = (void *) iter;
1983 fail_afsclient_AFSServerGetBegin:
2001 * afsclient_AFSServerGetNext - retrieve the next server in the cell.
2005 * IN iterationId - an iterator previously returned by
2006 * afsclient_AFSServerGetBegin.
2008 * OUT serverEntryP - upon successful completion contains the next server.
2012 * No locks are obtained or released by this function
2020 * Returns != 0 upon successful completion.
2023 int ADMINAPI afsclient_AFSServerGetNext(
2025 afs_serverEntry_p serverEntryP,
2029 afs_status_t tst = 0;
2030 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2032 if (iterationId == NULL) {
2033 tst = ADMITERATORNULL;
2034 goto fail_afsclient_AFSServerGetNext;
2037 if (serverEntryP == NULL) {
2038 tst = ADMUTILSERVERENTRYPNULL;
2039 goto fail_afsclient_AFSServerGetNext;
2042 rc = IteratorNext(iter, (void *) serverEntryP, &tst);
2044 fail_afsclient_AFSServerGetNext:
2053 * afsclient_AFSServerGetDone - finish using a server iterator.
2057 * IN iterationId - an iterator previously returned by
2058 * afsclient_AFSServerGetBegin.
2062 * No locks are obtained or released by this function
2070 * Returns != 0 upon successful completion.
2073 int ADMINAPI afsclient_AFSServerGetDone(
2078 afs_status_t tst = 0;
2079 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2081 if (iterationId == NULL) {
2082 tst = ADMITERATORNULL;
2083 goto fail_afsclient_AFSServerGetDone;
2086 rc = IteratorDone(iter, &tst);
2088 fail_afsclient_AFSServerGetDone:
2097 * afsclient_RPCStatOpen - open an rx connection to a server to retrieve
2102 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2104 * IN serverName - the host name where the server resides.
2106 * IN type - what type of process to query
2108 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2112 * No locks are obtained or released by this function
2120 * Returns != 0 upon successful completion.
2123 int ADMINAPI afsclient_RPCStatOpen(
2124 const void *cellHandle,
2125 const char *serverName,
2126 afs_stat_source_t type,
2127 struct rx_connection **rpcStatHandleP,
2131 afs_status_t tst = 0;
2132 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2135 struct rx_securityClass *sc;
2137 if (!CellHandleIsValid(cellHandle, &tst)) {
2138 goto fail_afsclient_RPCStatOpen;
2141 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2142 goto fail_afsclient_RPCStatOpen;
2145 if (rpcStatHandleP == NULL) {
2146 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2147 goto fail_afsclient_RPCStatOpen;
2153 servPort = AFSCONF_NANNYPORT;
2156 case AFS_FILESERVER:
2157 servPort = AFSCONF_FILEPORT;
2161 servPort = AFSCONF_KAUTHPORT;
2165 servPort = AFSCONF_PROTPORT;
2169 servPort = AFSCONF_VOLUMEPORT;
2173 servPort = AFSCONF_VLDBPORT;
2177 servPort = AFSCONF_CALLBACKPORT;
2181 tst = ADMTYPEINVALID;
2182 goto fail_afsclient_RPCStatOpen;
2186 * special processing of tokens by server type
2189 if (type == AFS_KASERVER) {
2190 if (!c_handle->tokens->kas_token_set) {
2191 tst = ADMCLIENTNOKASTOKENS;
2192 goto fail_afsclient_RPCStatOpen;
2194 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2196 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2199 *rpcStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2201 RX_STATS_SERVICE_ID,
2203 c_handle->tokens->sc_index);
2205 if (*rpcStatHandleP == NULL) {
2206 tst = ADMCLIENTRPCSTATNOCONNECTION;
2207 goto fail_afsclient_RPCStatOpen;
2211 fail_afsclient_RPCStatOpen:
2220 * afsclient_RPCStatOpenPort - open an rx connection to a server to retrieve
2225 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2227 * IN serverName - the host name where the server resides.
2229 * IN port - the UDP port number where the server resides.
2231 * OUT rpcStatHandleP - contains an rx connection to the server of interest
2235 * No locks are obtained or released by this function
2243 * Returns != 0 upon successful completion.
2246 int ADMINAPI afsclient_RPCStatOpenPort(
2247 const void *cellHandle,
2248 const char *serverName,
2249 const int serverPort,
2250 struct rx_connection **rpcStatHandleP,
2254 afs_status_t tst = 0;
2255 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2257 struct rx_securityClass *sc;
2259 if (!CellHandleIsValid(cellHandle, &tst)) {
2260 goto fail_afsclient_RPCStatOpenPort;
2263 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2264 goto fail_afsclient_RPCStatOpenPort;
2267 if (rpcStatHandleP == NULL) {
2268 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2269 goto fail_afsclient_RPCStatOpenPort;
2273 * special processing of tokens by server type
2276 if (serverPort == AFSCONF_KAUTHPORT) {
2277 if (!c_handle->tokens->kas_token_set) {
2278 tst = ADMCLIENTNOKASTOKENS;
2279 goto fail_afsclient_RPCStatOpenPort;
2281 sc = c_handle->tokens->kas_sc[c_handle->tokens->sc_index];
2283 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2286 *rpcStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2288 RX_STATS_SERVICE_ID,
2290 c_handle->tokens->sc_index);
2292 if (*rpcStatHandleP == NULL) {
2293 tst = ADMCLIENTRPCSTATNOCONNECTION;
2294 goto fail_afsclient_RPCStatOpenPort;
2298 fail_afsclient_RPCStatOpenPort:
2307 * afsclient_RPCStatClose - close a previously opened rx connection.
2311 * IN rpcStatHandle - an rx connection returned by afsclient_RPCStatOpen
2315 * No locks are obtained or released by this function
2323 * Returns != 0 upon successful completion.
2326 int ADMINAPI afsclient_RPCStatClose(
2327 struct rx_connection *rpcStatHandle,
2331 afs_status_t tst = 0;
2333 if (rpcStatHandle == NULL) {
2334 tst = ADMCLIENTRPCSTATHANDLEPNULL;
2335 goto fail_afsclient_RPCStatClose;
2338 rx_ReleaseCachedConnection(rpcStatHandle);
2340 fail_afsclient_RPCStatClose:
2349 * afsclient_CMStatOpen - open an rx connection to a server to retrieve
2354 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2356 * IN serverName - the host name where the server resides.
2358 * OUT cmStatHandleP - contains an rx connection to the server of interest
2362 * No locks are obtained or released by this function
2370 * Returns != 0 upon successful completion.
2373 int ADMINAPI afsclient_CMStatOpen(
2374 const void *cellHandle,
2375 const char *serverName,
2376 struct rx_connection **cmStatHandleP,
2380 afs_status_t tst = 0;
2381 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2383 struct rx_securityClass *sc;
2385 if (!CellHandleIsValid(cellHandle, &tst)) {
2386 goto fail_afsclient_CMStatOpen;
2389 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2390 goto fail_afsclient_CMStatOpen;
2393 if (cmStatHandleP == NULL) {
2394 tst = ADMCLIENTCMSTATHANDLEPNULL;
2395 goto fail_afsclient_CMStatOpen;
2398 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2400 *cmStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2401 htons(AFSCONF_CALLBACKPORT),
2404 c_handle->tokens->sc_index);
2406 if (*cmStatHandleP == NULL) {
2407 tst = ADMCLIENTCMSTATNOCONNECTION;
2408 goto fail_afsclient_CMStatOpen;
2412 fail_afsclient_CMStatOpen:
2421 * afsclient_CMStatOpenPort - open an rx connection to a server to retrieve
2426 * IN cellHandle - a cellHandle created by afsclient_CellOpen.
2428 * IN serverName - the host name where the server resides.
2430 * IN port - the UDP port number where the server resides.
2432 * OUT cmStatHandleP - contains an rx connection to the server of interest
2436 * No locks are obtained or released by this function
2444 * Returns != 0 upon successful completion.
2447 int ADMINAPI afsclient_CMStatOpenPort(
2448 const void *cellHandle,
2449 const char *serverName,
2450 const int serverPort,
2451 struct rx_connection **cmStatHandleP,
2455 afs_status_t tst = 0;
2456 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2458 struct rx_securityClass *sc;
2460 if (!CellHandleIsValid(cellHandle, &tst)) {
2461 goto fail_afsclient_CMStatOpenPort;
2464 if (!util_AdminServerAddressGetFromName(serverName, &servAddr, &tst)) {
2465 goto fail_afsclient_CMStatOpenPort;
2468 if (cmStatHandleP == NULL) {
2469 tst = ADMCLIENTCMSTATHANDLEPNULL;
2470 goto fail_afsclient_CMStatOpenPort;
2473 sc = c_handle->tokens->afs_sc[c_handle->tokens->sc_index];
2475 *cmStatHandleP = rx_GetCachedConnection(htonl(servAddr),
2479 c_handle->tokens->sc_index);
2481 if (*cmStatHandleP == NULL) {
2482 tst = ADMCLIENTCMSTATNOCONNECTION;
2483 goto fail_afsclient_CMStatOpenPort;
2487 fail_afsclient_CMStatOpenPort:
2496 * afsclient_CMStatClose - close a previously opened rx connection.
2500 * IN cmStatHandle - an rx connection returned by afsclient_CMStatOpen
2504 * No locks are obtained or released by this function
2512 * Returns != 0 upon successful completion.
2515 int ADMINAPI afsclient_CMStatClose(
2516 struct rx_connection *cmStatHandle,
2520 afs_status_t tst = 0;
2522 if (cmStatHandle == NULL) {
2523 tst = ADMCLIENTCMSTATHANDLEPNULL;
2524 goto fail_afsclient_CMStatClose;
2527 rx_ReleaseCachedConnection(cmStatHandle);
2529 fail_afsclient_CMStatClose:
2538 * afsclient_RXDebugOpen - open an rxdebug handle to a server.
2542 * IN serverName - the host name where the server resides.
2544 * IN type - what type of process to query
2546 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2550 * No locks are obtained or released by this function
2558 * Returns != 0 upon successful completion.
2561 int ADMINAPI afsclient_RXDebugOpen(
2562 const char *serverName,
2563 afs_stat_source_t type,
2564 rxdebugHandle_p *rxdebugHandleP,
2568 afs_status_t tst = 0;
2570 rxdebugHandle_p handle;
2571 rxdebugSocket_t sock;
2572 struct sockaddr_in taddr;
2576 if (rxdebugHandleP == NULL) {
2577 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2578 goto fail_afsclient_RXDebugOpen;
2584 serverPort = AFSCONF_NANNYPORT;
2587 case AFS_FILESERVER:
2588 serverPort = AFSCONF_FILEPORT;
2592 serverPort = AFSCONF_KAUTHPORT;
2596 serverPort = AFSCONF_PROTPORT;
2600 serverPort = AFSCONF_VOLUMEPORT;
2604 serverPort = AFSCONF_VLDBPORT;
2608 serverPort = AFSCONF_CALLBACKPORT;
2612 tst = ADMTYPEINVALID;
2613 goto fail_afsclient_RXDebugOpen;
2616 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2617 goto fail_afsclient_RXDebugOpen;
2620 sock = (rxdebugSocket_t)socket(AF_INET, SOCK_DGRAM, 0);
2621 if (sock == INVALID_RXDEBUG_SOCKET) {
2623 goto fail_afsclient_RXDebugOpen;
2626 memset(&taddr, 0, sizeof(taddr));
2627 taddr.sin_family = AF_INET;
2629 taddr.sin_addr.s_addr = INADDR_ANY;
2630 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2634 goto fail_afsclient_RXDebugOpen;
2637 handle = (rxdebugHandle_p)malloc(sizeof(rxdebugHandle_t));
2641 goto fail_afsclient_RXDebugOpen;
2644 handle->sock = sock;
2645 handle->ipAddr = serverAddr;
2646 handle->udpPort = serverPort;
2647 handle->firstFlag = 1;
2648 handle->supportedStats = 0;
2649 *rxdebugHandleP = handle;
2652 fail_afsclient_RXDebugOpen:
2661 * afsclient_RXDebugOpenPort - open an rxdebug handle to a server.
2665 * IN serverName - the host name where the server resides.
2667 * IN port - the UDP port number where the server resides.
2669 * OUT rxdebugHandle_p - contains an rxdebug handle for the server of interest
2673 * No locks are obtained or released by this function
2681 * Returns != 0 upon successful completion.
2684 int ADMINAPI afsclient_RXDebugOpenPort(
2685 const char *serverName,
2687 rxdebugHandle_p *rxdebugHandleP,
2691 afs_status_t tst = 0;
2693 rxdebugHandle_p handle;
2694 rxdebugSocket_t sock;
2695 struct sockaddr_in taddr;
2698 if (rxdebugHandleP == NULL) {
2699 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2700 goto fail_afsclient_RXDebugOpenPort;
2703 if (!util_AdminServerAddressGetFromName(serverName, &serverAddr, &tst)) {
2704 goto fail_afsclient_RXDebugOpenPort;
2707 sock = (rxdebugSocket_t)socket(AF_INET, SOCK_DGRAM, 0);
2708 if (sock == INVALID_RXDEBUG_SOCKET) {
2710 goto fail_afsclient_RXDebugOpenPort;
2713 memset(&taddr, 0, sizeof(taddr));
2714 taddr.sin_family = AF_INET;
2716 taddr.sin_addr.s_addr = INADDR_ANY;
2717 code = bind(sock, (struct sockaddr *)&taddr, sizeof(taddr));
2721 goto fail_afsclient_RXDebugOpenPort;
2724 handle = (rxdebugHandle_p)malloc(sizeof(rxdebugHandle_t));
2728 goto fail_afsclient_RXDebugOpenPort;
2731 handle->sock = sock;
2732 handle->ipAddr = serverAddr;
2733 handle->udpPort = serverPort;
2734 handle->firstFlag = 1;
2735 handle->supportedStats = 0;
2736 *rxdebugHandleP = handle;
2739 fail_afsclient_RXDebugOpenPort:
2748 * afsclient_RXDebugClose - close a previously opened rxdebug handle.
2752 * IN rxdebugHandle - an rxdebug handle returned by afsclient_RXDebugOpen
2756 * No locks are obtained or released by this function
2764 * Returns != 0 upon successful completion.
2767 int ADMINAPI afsclient_RXDebugClose(
2768 rxdebugHandle_p rxdebugHandle,
2772 afs_status_t tst = 0;
2774 if (rxdebugHandle == NULL) {
2775 tst = ADMCLIENTRXDEBUGHANDLEPNULL;
2776 goto fail_afsclient_RXDebugClose;
2779 close(rxdebugHandle->sock);
2780 free(rxdebugHandle);
2782 fail_afsclient_RXDebugClose: