#include <afsconfig.h>
#include <afs/param.h>
+#include <afs/stds.h>
-RCSID
- ("$Header$");
+#include <roken.h>
-#include <afs/stds.h>
-#include "afs_clientAdmin.h"
-#include "../adminutil/afs_AdminInternal.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <afs/cellconfig.h>
#ifdef AFS_NT40_ENV
#include <afs/afssyscalls.h>
-#include <winsock2.h>
#include <afs/fs_utils.h>
+#define close(x) closesocket(x)
#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
#include <afs/venus.h>
-#include <errno.h>
-#include <strings.h>
-#include <unistd.h>
#endif
-#include <string.h>
-#include <afs/kautils.h>
#include <rx/rx.h>
+#include <rx/rxstat.h>
#include <rx/rx_null.h>
#include <rx/rxkad.h>
+
+#include <afs/kautils.h>
#include <afs/dirpath.h>
#include <afs/afs_AdminErrors.h>
#include <afs/afs_vosAdmin.h>
#include <afs/ptserver.h>
#include <afs/vlserver.h>
#include <afs/pthread_glock.h>
+#include <afs/sys_prototypes.h>
+
+#include "afs_clientAdmin.h"
+#include "../adminutil/afs_AdminInternal.h"
/*
* AFS client administration functions.
static const unsigned long ADMIN_TICKET_LIFETIME = 24 * 3600;
+static const unsigned long SERVER_TTL = 10 * 60;
+
/*
* We need a way to track whether or not the client library has been
* initialized. We count on the fact that the other library initialization
* The token has been retrieved successfully, initialize
* the rest of the token handle structure
*/
- strcpy(t_handle->cell, cellName);
+ strncpy(t_handle->cell, cellName, MAXCELLCHARS);
+ t_handle->cell[MAXCELLCHARS - 1] = '\0';
t_handle->afs_token_set = 1;
t_handle->from_kernel = 1;
t_handle->kas_token_set = 0;
t_handle->afs_token.ticketLen,
t_handle->afs_token.ticket);
if ((t_handle->afs_sc[t_handle->sc_index] == NULL)
- || (t_handle->afs_sc[t_handle->sc_index] == NULL)) {
+ || (t_handle->afs_encrypt_sc[t_handle->sc_index] == NULL)) {
tst = ADMCLIENTTOKENHANDLENOSECURITY;
goto fail_afsclient_TokenGetExisting;
} else {
if ((GetAFSToken(cellName, principal, password, t_handle, &tst))
&& (GetKASToken(cellName, principal, password, t_handle, &tst))) {
- strcpy(t_handle->cell, cellName);
+ strncpy(t_handle->cell, cellName, MAXCELLCHARS);
+ t_handle->cell[MAXCELLCHARS - 1] = '\0';
t_handle->from_kernel = 0;
t_handle->afs_token_set = 1;
t_handle->kas_token_set = 1;
int *valid;
} afs_server_t, *afs_server_p;
-static afs_server_t servers[NUM_SERVER_TYPES]
-= { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
-{AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
-{AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}
-};
-
/*
* afsclient_CellOpen - Open a particular cell for work as a particular
* user.
int scIndex;
char copyCell[MAXCELLCHARS];
+ afs_server_t servers[NUM_SERVER_TYPES]
+ = { {AFSCONF_KAUTHSERVICE, KA_MAINTENANCE_SERVICE, 0, 0, 0},
+ {AFSCONF_PROTSERVICE, PRSRV, 0, 0, 0},
+ {AFSCONF_VLDBSERVICE, USER_SERVICE_ID, 0, 0, 0}
+ };
+
if (client_init == 0) {
tst = ADMCLIENTNOINIT;
goto fail_afsclient_CellOpen;
* information for each server in the cell
*/
- strcpy(c_handle->working_cell, cellName);
+ strncpy(c_handle->working_cell, cellName, MAXCELLCHARS);
+ c_handle->working_cell[MAXCELLCHARS - 1] = '\0';
if (!(tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH))) {
tst = ADMCLIENTBADCLIENTCONFIG;
goto fail_afsclient_CellOpen;
* We must copy the cellName here because afsconf_GetCellInfo
* actually writes over the cell name it is passed.
*/
- strncpy(copyCell, cellName, MAXCELLCHARS - 1);
+ strncpy(copyCell, cellName, MAXCELLCHARS);
+ copyCell[MAXCELLCHARS - 1] ='\0';
for (i = 0; (i < NUM_SERVER_TYPES); i++) {
if (i == KAS) {
tst =
c_handle->begin_magic = BEGIN_MAGIC;
c_handle->is_valid = 1;
c_handle->is_null = 0;
+ c_handle->server_list = NULL;
+ c_handle->server_ttl = 0;
c_handle->end_magic = END_MAGIC;
*cellHandleP = (void *)c_handle;
}
c_handle->kas_valid = 0;
c_handle->pts_valid = 0;
c_handle->vos_valid = 0;
- c_handle->kas = 0;
- c_handle->pts = 0;
- c_handle->vos = 0;
+ c_handle->kas = NULL;
+ c_handle->pts = NULL;
+ c_handle->vos = NULL;
+ c_handle->server_list = NULL;
+ c_handle->server_ttl = 0;
*cellHandleP = (void *)c_handle;
rc = 1;
goto fail_afsclient_CellClose;
}
+ if (c_handle->server_list)
+ free(c_handle->server_list);
if (c_handle->kas_valid)
ubik_ClientDestroy(c_handle->kas);
if (c_handle->pts_valid)
static int
Parent(char *directory, char *parentDirectory)
{
- register char *tp;
+ char *tp;
int rc = 0;
strcpy(parentDirectory, directory);
*/
if (volCheck == CHECK_VOLUME) {
- if (!vos_VLDBGet(cellHandle, 0, 0, volumeName, &vldbEntry, &tst)) {
+ if (!vos_VLDBGet(cellHandle, 0, 0, (char *)volumeName, &vldbEntry,
+ &tst)) {
goto fail_afsclient_MountPointCreate;
}
}
idata.out_size = 2048;
idata.in_size = 0;
idata.in = idata.out = old_acl_string;
- tst = pioctl(directory, VIOCGETAL, &idata, 1);
+ tst = pioctl((char *)directory, VIOCGETAL, &idata, 1);
if (tst != 0) {
goto fail_afsclient_ACLEntryAdd;
*/
is_dfs =
- sscanf(old_acl_string, "%d dfs:%d %s", &cur_acl.nplus, &cur_acl.dfs,
+ sscanf(old_acl_string, "%d dfs:%d %1024s", &cur_acl.nplus, &cur_acl.dfs,
cur_acl.cell);
ptr = strchr(old_acl_string, '\n');
ptr++;
*/
for (i = 0; i < (cur_acl.nplus + cur_acl.nminus); i++) {
- sscanf(ptr, "%s%d\n", cur_user, &cur_user_acl);
+ sscanf(ptr, "%63s%d\n", cur_user, &cur_user_acl);
/*
* Skip the entry for the user we are replacing/adding
*/
idata.out_size = 0;
idata.in_size = strlen(new_acl_string) + 1;
idata.in = idata.out = new_acl_string;
- tst = pioctl(directory, VIOCSETAL, &idata, 1);
+ tst = pioctl((char *) directory, VIOCSETAL, &idata, 1);
if (tst != 0) {
goto fail_afsclient_ACLEntryAdd;
int rc = 0;
afs_status_t tst = 0;
afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
- afs_admin_iterator_p iter =
- (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
- server_get_p serv = (server_get_p) calloc(1, sizeof(server_get_t));
- const char *cellName;
+ afs_admin_iterator_p iter = malloc(sizeof(afs_admin_iterator_t));
+ server_get_p serv = calloc(1, sizeof(server_get_t));
+ server_get_p serv_cache = NULL;
+ const char *cellName = NULL;
void *database_iter;
util_databaseServerEntry_t database_entry;
void *fileserver_iter;
goto fail_afsclient_AFSServerGetBegin;
}
- /*
- * Retrieve the list of database servers for this cell.
- */
-
- if (!afsclient_CellNameGet(cellHandle, &cellName, &tst)) {
- goto fail_afsclient_AFSServerGetBegin;
+ restart:
+ LOCK_GLOBAL_MUTEX;
+ if (c_handle->server_list != NULL && c_handle->server_ttl < time(NULL)) {
+ serv_cache = c_handle->server_list;
+ c_handle->server_list = NULL;
}
+ UNLOCK_GLOBAL_MUTEX;
- if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
- goto fail_afsclient_AFSServerGetBegin;
- }
+ if (c_handle->server_list == NULL) {
+ if (serv_cache == NULL) {
+ serv_cache = (server_get_p) calloc(1, sizeof(server_get_t));
- while (util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
- serv->server[serv->total].serverAddress[0] =
- database_entry.serverAddress;
- serv->server[serv->total].serverType = DATABASE_SERVER;
- serv->total++;
- }
+ if (serv_cache == NULL) {
+ tst = ADMNOMEM;
+ goto fail_afsclient_AFSServerGetBegin;
+ }
+ }
- if (tst != ADMITERATORDONE) {
- util_DatabaseServerGetDone(database_iter, 0);
- goto fail_afsclient_AFSServerGetBegin;
- }
+ /*
+ * Retrieve the list of database servers for this cell.
+ */
- if (!util_DatabaseServerGetDone(database_iter, &tst)) {
- goto fail_afsclient_AFSServerGetBegin;
- }
+ if (!afsclient_CellNameGet(c_handle, &cellName, &tst)) {
+ goto fail_afsclient_AFSServerGetBegin;
+ }
- /*
- * Retrieve the list of file servers for this cell.
- */
+ if (!util_DatabaseServerGetBegin(cellName, &database_iter, &tst)) {
+ goto fail_afsclient_AFSServerGetBegin;
+ }
- if (!vos_FileServerGetBegin(cellHandle, 0, &fileserver_iter, &tst)) {
- goto fail_afsclient_AFSServerGetBegin;
- }
+ while (util_DatabaseServerGetNext(database_iter, &database_entry, &tst)) {
+ serv->server[serv->total].serverAddress[0] =
+ database_entry.serverAddress;
+ serv->server[serv->total].serverType = DATABASE_SERVER;
+ serv->total++;
+ }
+
+ if (tst != ADMITERATORDONE) {
+ util_DatabaseServerGetDone(database_iter, 0);
+ goto fail_afsclient_AFSServerGetBegin;
+ }
+
+ if (!util_DatabaseServerGetDone(database_iter, &tst)) {
+ goto fail_afsclient_AFSServerGetBegin;
+ }
- while (vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
/*
- * See if any of the addresses returned in this fileserver_entry
- * structure already exist in the list of servers we're building.
- * If not, create a new record for this server.
+ * Retrieve the list of file servers for this cell.
*/
- is_dup = 0;
- for (iserv = 0; iserv < serv->total; iserv++) {
- for (ientryaddr = 0; ientryaddr < fileserver_entry.count;
- ientryaddr++) {
- for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
- iservaddr++) {
- if (serv->server[iserv].serverAddress[iservaddr] ==
- fileserver_entry.serverAddress[ientryaddr]) {
- is_dup = 1;
+
+ if (!vos_FileServerGetBegin(c_handle, 0, &fileserver_iter, &tst)) {
+ goto fail_afsclient_AFSServerGetBegin;
+ }
+
+ while (vos_FileServerGetNext(fileserver_iter, &fileserver_entry, &tst)) {
+ /*
+ * See if any of the addresses returned in this fileserver_entry
+ * structure already exist in the list of servers we're building.
+ * If not, create a new record for this server.
+ */
+ is_dup = 0;
+ for (iserv = 0; iserv < serv->total; iserv++) {
+ for (ientryaddr = 0; ientryaddr < fileserver_entry.count; ientryaddr++) {
+ for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS; iservaddr++) {
+ if (serv->server[iserv].serverAddress[iservaddr] ==
+ fileserver_entry.serverAddress[ientryaddr]) {
+ is_dup = 1;
+ break;
+ }
+ }
+ if (is_dup) {
break;
}
}
break;
}
}
+
if (is_dup) {
- break;
+ serv->server[iserv].serverType |= FILE_SERVER;
+ } else {
+ iserv = serv->total++;
+ serv->server[iserv].serverType = FILE_SERVER;
}
- }
- if (is_dup) {
- serv->server[iserv].serverType |= FILE_SERVER;
- } else {
- iserv = serv->total++;
- serv->server[iserv].serverType = FILE_SERVER;
- }
+ /*
+ * Add the addresses from the vldb list to the serv->server[iserv]
+ * record. Remember that VLDB's list-of-addrs is not guaranteed
+ * to be unique in a particular entry, or to return only one entry
+ * per machine--so when we add addresses, always check for
+ * duplicate entries.
+ */
- /*
- * Add the addresses from the vldb list to the serv->server[iserv]
- * record. Remember that VLDB's list-of-addrs is not guaranteed
- * to be unique in a particular entry, or to return only one entry
- * per machine--so when we add addresses, always check for
- * duplicate entries.
- */
-
- for (ientryaddr = 0; ientryaddr < fileserver_entry.count;
- ientryaddr++) {
- for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
- iservaddr++) {
- if (serv->server[iserv].serverAddress[iservaddr] ==
- fileserver_entry.serverAddress[ientryaddr]) {
- break;
- }
- }
- if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
- for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
- iservaddr++) {
- if (!serv->server[iserv].serverAddress[iservaddr]) {
- serv->server[iserv].serverAddress[iservaddr] =
- fileserver_entry.serverAddress[ientryaddr];
+ for (ientryaddr = 0; ientryaddr < fileserver_entry.count; ientryaddr++) {
+ for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS; iservaddr++) {
+ if (serv->server[iserv].serverAddress[iservaddr] ==
+ fileserver_entry.serverAddress[ientryaddr]) {
break;
}
}
+ if (iservaddr == AFS_MAX_SERVER_ADDRESS) {
+ for (iservaddr = 0; iservaddr < AFS_MAX_SERVER_ADDRESS;
+ iservaddr++) {
+ if (!serv->server[iserv].serverAddress[iservaddr]) {
+ serv->server[iserv].serverAddress[iservaddr] =
+ fileserver_entry.serverAddress[ientryaddr];
+ break;
+ }
+ }
+ }
}
}
- }
- if (tst != ADMITERATORDONE) {
- vos_FileServerGetDone(fileserver_iter, 0);
- goto fail_afsclient_AFSServerGetBegin;
- }
+ if (tst != ADMITERATORDONE) {
+ vos_FileServerGetDone(fileserver_iter, 0);
+ goto fail_afsclient_AFSServerGetBegin;
+ }
- if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
- goto fail_afsclient_AFSServerGetBegin;
- }
+ if (!vos_FileServerGetDone(fileserver_iter, &tst)) {
+ goto fail_afsclient_AFSServerGetBegin;
+ }
- /*
- * Iterate over the list and fill in the hostname of each of the servers
- */
+ /*
+ * Iterate over the list and fill in the hostname of each of the servers
+ */
- LOCK_GLOBAL_MUTEX;
- for (iserv = 0; iserv < serv->total; iserv++) {
- int addr = htonl(serv->server[iserv].serverAddress[0]);
- host = gethostbyaddr((const char *)&addr, sizeof(int), AF_INET);
- if (host != NULL) {
- strncpy(serv->server[iserv].serverName, host->h_name,
- AFS_MAX_SERVER_NAME_LEN);
+ for (iserv = 0; iserv < serv->total; iserv++) {
+ int addr = htonl(serv->server[iserv].serverAddress[0]);
+ LOCK_GLOBAL_MUTEX;
+ host = gethostbyaddr((const char *)&addr, sizeof(int), AF_INET);
+ if (host != NULL) {
+ strncpy(serv->server[iserv].serverName, host->h_name,
+ AFS_MAX_SERVER_NAME_LEN);
+ serv->server[iserv].serverName[AFS_MAX_SERVER_NAME_LEN - 1] = '\0';
+ }
+ UNLOCK_GLOBAL_MUTEX;
}
+
+ memcpy(serv_cache, serv, sizeof(server_get_t));
+ } else {
+ int race = 0;
+ LOCK_GLOBAL_MUTEX;
+ if (c_handle->server_list == NULL)
+ race = 1;
+ else
+ memcpy(serv, c_handle->server_list, sizeof(server_get_t));
+ UNLOCK_GLOBAL_MUTEX;
+ if (race)
+ goto restart;
}
- UNLOCK_GLOBAL_MUTEX;
+
if (IteratorInit
(iter, (void *)serv, GetServerRPC, GetServerFromCache, NULL, NULL,
&tst)) {
fail_afsclient_AFSServerGetBegin:
if (rc == 0) {
- if (iter != NULL) {
+ if (iter != NULL)
free(iter);
- }
- if (serv != NULL) {
+ if (serv != NULL)
free(serv);
+ if (serv_cache != NULL)
+ free(serv_cache);
+ } else {
+ if (serv_cache) {
+ LOCK_GLOBAL_MUTEX;
+ /* in case there was a race and we constructed the list twice */
+ if (c_handle->server_list)
+ free(c_handle->server_list);
+
+ c_handle->server_list = serv_cache;
+ c_handle->server_ttl = time(NULL) + SERVER_TTL;
+ UNLOCK_GLOBAL_MUTEX;
}
}
- if (st != NULL) {
+ if (st != NULL)
*st = tst;
- }
+
return rc;
}
goto fail_afsclient_RXDebugOpen;
}
- handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
+ handle = malloc(sizeof(rxdebugHandle_t));
if (!handle) {
close(sock);
tst = ADMNOMEM;
goto fail_afsclient_RXDebugOpenPort;
}
- handle = (rxdebugHandle_p) malloc(sizeof(rxdebugHandle_t));
+ handle = malloc(sizeof(rxdebugHandle_t));
if (!handle) {
close(sock);
tst = ADMNOMEM;