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