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 #define UBIK_LEGACY_CALLITER 1
12 #include <afsconfig.h>
13 #include <afs/param.h>
19 #include <rx/rxstat.h>
20 #include "afs_kasAdmin.h"
21 #include "../adminutil/afs_AdminInternal.h"
22 #include <afs/afs_AdminErrors.h>
23 #include <afs/afs_utilAdmin.h>
24 #include <afs/kauth.h>
25 #include <afs/kautils.h>
26 #include <afs/kaport.h>
34 struct ubik_client *servers;
37 } kas_server_t, *kas_server_p;
40 * IsValidServerHandle - verify the validity of a kas_server_t handle.
44 * IN serverHandle - the handle to be verified.
48 * No locks are obtained or released by this function
52 * Returns != 0 upon successful completion.
56 IsValidServerHandle(const kas_server_p serverHandle, afs_status_p st)
62 * Validate input parameters
65 if (serverHandle == NULL) {
66 tst = ADMKASSERVERHANDLENULL;
67 goto fail_IsValidServerHandle;
70 if ((serverHandle->begin_magic != BEGIN_MAGIC)
71 || (serverHandle->end_magic != END_MAGIC)) {
72 tst = ADMKASSERVERHANDLEBADMAGIC;
73 goto fail_IsValidServerHandle;
76 if (!serverHandle->is_valid) {
77 tst = ADMKASSERVERHANDLENOTVALID;
78 goto fail_IsValidServerHandle;
81 if (serverHandle->servers == NULL) {
82 tst = ADMKASSERVERHANDLENOSERVERS;
83 goto fail_IsValidServerHandle;
87 fail_IsValidServerHandle:
96 * IsValidCellHandle - verify the validity of a afs_cell_handle_t handle
97 * for doing kas related functions.
101 * IN cellHandle - the handle to be verified.
105 * No locks are obtained or released by this function
109 * Returns != 0 upon successful completion.
113 IsValidCellHandle(const afs_cell_handle_p cellHandle, afs_status_p st)
116 afs_status_t tst = 0;
119 * Validate input parameters
122 if (!CellHandleIsValid((void *)cellHandle, &tst)) {
123 goto fail_IsValidCellHandle;
126 if (!cellHandle->kas_valid) {
127 tst = ADMCLIENTCELLKASINVALID;
128 goto fail_IsValidCellHandle;
131 if (cellHandle->kas == NULL) {
132 tst = ADMCLIENTCELLKASNULL;
133 goto fail_IsValidCellHandle;
137 fail_IsValidCellHandle:
146 * For all kas admin functions that take a cellHandle and a serverHandle,
147 * the intention is that is the cellHandle is not NULL, we should use
148 * it. Otherwise, we use the serverHandle. It is an error for both
149 * of these parameters to be non-NULL.
153 * ChooseValidServer - given a serverHandle and a cellHandle, choose the
154 * one that is non-NULL, validate it, and return a ubik_client structure
159 * IN cellHandle - the cell where kas calls are to be made
161 * IN serverHandle - the group of server(s) that should be used to satisfy
166 * No locks are obtained or released by this function
170 * Returns != 0 upon successful completion.
174 ChooseValidServer(const afs_cell_handle_p cellHandle,
175 const kas_server_p serverHandle, kas_server_p kasHandle,
179 afs_status_t tst = 0;
182 * Validate input parameters
185 if (kasHandle == NULL) {
186 tst = ADMKASKASHANDLENULL;
187 goto fail_ChooseValidServer;
191 * Only one of the input handle parameters to this function should
194 if ((cellHandle == NULL) && (serverHandle == NULL)) {
195 tst = ADMKASCELLHANDLEANDSERVERHANDLENULL;
196 goto fail_ChooseValidServer;
199 if ((cellHandle != NULL) && (serverHandle != NULL)) {
200 tst = ADMKASCELLHANDLEANDSERVERHANDLENOTNULL;
201 goto fail_ChooseValidServer;
205 * Validate the non-NULL handle
208 if (cellHandle != NULL) {
209 if (IsValidCellHandle(cellHandle, &tst)) {
210 kasHandle->servers = cellHandle->kas;
211 kasHandle->cell = cellHandle->working_cell;
213 goto fail_ChooseValidServer;
216 if (IsValidServerHandle(serverHandle, &tst)) {
217 kasHandle->servers = serverHandle->servers;
218 kasHandle->cell = serverHandle->cell;
220 goto fail_ChooseValidServer;
224 kasHandle->begin_magic = BEGIN_MAGIC;
225 kasHandle->end_magic = END_MAGIC;
226 kasHandle->is_valid = 1;
229 fail_ChooseValidServer:
239 kaentryinfo_to_kas_principalEntry_t(struct kaentryinfo *from,
240 kas_principalEntry_p to, afs_status_p st)
243 afs_status_t tst = 0;
245 unsigned char misc_stuff[4];
248 tst = ADMKASFROMNULL;
249 goto fail_kaentryinfo_to_kas_principalEntry_t;
254 goto fail_kaentryinfo_to_kas_principalEntry_t;
257 if (from->flags & KAFADMIN) {
258 to->adminSetting = KAS_ADMIN;
260 to->adminSetting = NO_KAS_ADMIN;
263 if (from->flags & KAFNOTGS) {
264 to->tgsSetting = NO_TGS;
266 to->tgsSetting = TGS;
269 if (from->flags & KAFNOSEAL) {
270 to->encSetting = NO_ENCRYPT;
272 to->encSetting = ENCRYPT;
275 if (from->flags & KAFNOCPW) {
276 to->cpwSetting = NO_CHANGE_PASSWORD;
278 to->cpwSetting = CHANGE_PASSWORD;
281 reuse = (short)from->reserved3;
283 to->rpwSetting = REUSE_PASSWORD;
285 to->rpwSetting = NO_REUSE_PASSWORD;
289 if (from->user_expiration == NEVERDATE) {
290 to->userExpiration = 0;
292 to->userExpiration = from->user_expiration;
295 to->lastModTime = from->modification_time;
296 strcpy(to->lastModPrincipal.principal, from->modification_user.name);
297 strcpy(to->lastModPrincipal.instance, from->modification_user.instance);
298 to->lastChangePasswordTime = from->change_password_time;
299 to->maxTicketLifetime = from->max_ticket_lifetime;
300 to->keyVersion = from->key_version;
301 memcpy(&to->key, &from->key, sizeof(to->key));
302 to->keyCheckSum = from->keyCheckSum;
304 unpack_long(from->misc_auth_bytes, misc_stuff);
305 to->daysToPasswordExpire = misc_stuff[0];
306 to->failLoginCount = misc_stuff[2];
307 to->lockTime = misc_stuff[3] << 9;
310 fail_kaentryinfo_to_kas_principalEntry_t:
319 * kas_ServerOpen - open a handle to a set of kaserver's.
323 * IN cellHandle - a previously opened cellHandle that corresponds
324 * to the cell where the server(s) live.
326 * IN serverList - a NULL terminated list (a la argv) of server's that
329 * OUT serverHandleP - a pointer to a void pointer that upon successful
330 * completion contains serverHandle that can be used in other kas functions.
334 * No locks are obtained or released by this function
338 * Returns != 0 upon successful completion.
342 * This function make some assumptions about the afsconf_cell used by
343 * ka_AuthSpecificServersConn (since I just wrote ka_AuthSpecificServersConn).
344 * It only fills in the fields that are required.
346 * Also we assume that the servers listed are members of the cell in
347 * cellHandle without verifying that this is in fact the case. kas itself
348 * always assumes that the -servers parameter lists servers in the current
349 * cell without verifying, so I am no worse than the current
350 * implementation. In fact I'm actually a little more flexible since you
351 * can actually use my serverList to play with servers in another cell.
352 * You can't do that with kas. For certain functions in kas the same
353 * cell assumption can cause things to fail (the ka_StringToKey function in
358 kas_ServerOpen(const void *cellHandle, const char **serverList,
359 void **serverHandleP, afs_status_p st)
362 afs_status_t tst = 0;
363 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
364 int server_count = 0, server_addr;
365 struct afsconf_cell server_info;
366 kas_server_p k_handle = malloc(sizeof(kas_server_t));
369 * Validate input parameters
372 if (c_handle == NULL) {
373 tst = ADMCLIENTCELLHANDLENULL;
374 goto fail_kas_ServerOpen;
377 if (c_handle->kas_valid == 0) {
378 tst = ADMCLIENTCELLKASINVALID;
379 goto fail_kas_ServerOpen;
382 if (serverList == NULL) {
383 tst = ADMKASSERVERLISTNULL;
384 goto fail_kas_ServerOpen;
387 if (serverHandleP == NULL) {
388 tst = ADMKASSERVERHANDLEPNULL;
389 goto fail_kas_ServerOpen;
392 if (k_handle == NULL) {
394 goto fail_kas_ServerOpen;
397 k_handle->begin_magic = BEGIN_MAGIC;
398 k_handle->end_magic = END_MAGIC;
399 k_handle->is_valid = 0;
400 k_handle->servers = NULL;
403 * Convert serverList to numeric addresses
406 for (server_count = 0; serverList[server_count] != NULL; server_count++) {
407 if (server_count >= MAXHOSTSPERCELL) {
408 tst = ADMKASSERVERLISTTOOLONG;
409 goto fail_kas_ServerOpen;
411 if (util_AdminServerAddressGetFromName
412 (serverList[server_count], &server_addr, &tst)) {
413 server_info.hostAddr[server_count].sin_addr.s_addr =
415 server_info.hostAddr[server_count].sin_port =
416 htons(AFSCONF_KAUTHPORT);
418 goto fail_kas_ServerOpen;
422 if (server_count == 0) {
423 tst = ADMKASSERVERLISTEMPTY;
424 goto fail_kas_ServerOpen;
428 * Get a ubik_client handle for the specified servers
430 server_info.numServers = server_count;
433 ka_AuthSpecificServersConn(KA_MAINTENANCE_SERVICE,
434 &c_handle->tokens->kas_token,
435 &server_info, &k_handle->servers))) {
436 k_handle->is_valid = 1;
437 k_handle->cell = c_handle->working_cell;
438 *serverHandleP = (void *)k_handle;
440 goto fail_kas_ServerOpen;
446 if ((rc == 0) && (k_handle != NULL)) {
457 * kas_ServerClose - close a serverHandle.
461 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
465 * No locks are obtained or released by this function
469 * Returns != 0 upon successful completion.
473 kas_ServerClose(const void *serverHandle, afs_status_p st)
476 afs_status_t tst = 0;
477 kas_server_p k_handle = (kas_server_p) serverHandle;
479 if (!IsValidServerHandle(k_handle, &tst)) {
480 goto fail_kas_ServerClose;
483 tst = ubik_ClientDestroy(k_handle->servers);
485 goto fail_kas_ServerClose;
488 k_handle->is_valid = 0;
492 fail_kas_ServerClose:
501 * kas_PrincipalCreate - create a new principal.
505 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
507 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
509 * IN who - a kas_identity_p containing the identity of the new principal
512 * IN password - the new principal's initial password.
516 * No locks are obtained or released by this function
520 * Returns != 0 upon successful completion.
524 kas_PrincipalCreate(const void *cellHandle, const void *serverHandle,
525 const kas_identity_p who, const char *password,
529 afs_status_t tst = 0;
530 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
531 kas_server_p k_handle = (kas_server_p) serverHandle;
532 kas_server_t kaserver;
534 struct kas_encryptionKey kas_key;
537 * Validate input arguments and make rpc.
542 goto fail_kas_PrincipalCreate;
545 if (password == NULL) {
546 tst = ADMKASPASSWORDNULL;
547 goto fail_kas_PrincipalCreate;
550 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
551 goto fail_kas_PrincipalCreate;
554 if (!kas_StringToKey(kaserver.cell, password, &kas_key, &tst)) {
555 goto fail_kas_PrincipalCreate;
558 memcpy(&key, &kas_key, sizeof(key));
561 ubik_KAM_CreateUser(kaserver.servers, 0, who->principal,
564 goto fail_kas_PrincipalCreate;
569 fail_kas_PrincipalCreate:
578 * kas_PrincipalDelete - delete an existing principal.
582 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
584 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
586 * IN who - a kas_identity_p containing the identity of the principal
591 * No locks are obtained or released by this function
595 * Returns != 0 upon successful completion.
599 kas_PrincipalDelete(const void *cellHandle, const void *serverHandle,
600 const kas_identity_p who, afs_status_p st)
603 afs_status_t tst = 0;
604 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
605 kas_server_p k_handle = (kas_server_p) serverHandle;
606 kas_server_t kaserver;
609 * Validate input arguments and make rpc.
614 goto fail_kas_PrincipalDelete;
617 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
618 goto fail_kas_PrincipalDelete;
621 ubik_KAM_DeleteUser(kaserver.servers, 0, who->principal,
624 goto fail_kas_PrincipalDelete;
628 fail_kas_PrincipalDelete:
637 * GetPrincipalLockStatus - get the lock status of a principal.
641 * IN kaserver - a valid kaserver handle previously returned by
644 * IN who - a kas_identity_p containing the identity of the principal
647 * OUT lockedUntil - the remaining number of seconds the principal is locked.
651 * No locks are obtained or released by this function
655 * Returns != 0 upon successful completion.
659 GetPrincipalLockStatus(const kas_server_p kaserver, const kas_identity_p who,
660 unsigned int *lockedUntil, afs_status_p st)
663 afs_status_t tst = 0;
669 * Validate input arguments and make rpc.
672 if (kaserver == NULL) {
673 tst = ADMKASKASERVERNULL;
674 goto fail_GetPrincipalLockStatus;
679 goto fail_GetPrincipalLockStatus;
682 if (lockedUntil == NULL) {
683 tst = ADMKASLOCKEDUNTILNULL;
684 goto fail_GetPrincipalLockStatus;
688 * Unlike every other kas rpc we make here, the lock/unlock rpc's
689 * aren't ubik based. So instead of calling ubik_Call, we use
690 * ubik_CallIter. ubik_CallIter steps through the list of hosts
691 * in the ubik_client and calls them one at a time. Since there's
692 * no synchronization of this data across the servers we have to
693 * manually keep track of the shortest time to unlock the user ourselves.
695 * The original inspiration for this function is ka_islocked
696 * in admin_tools.c. I think that function is totally bogus so I'm
699 * This function should contact all the kaservers and request the lock
700 * status of the principal. If any of the servers say the principal is
701 * unlocked, we report it as unlocked. If all the servers say the
702 * principal is locked, we find the server with the shortest lock time
703 * remaining on the principal and return that time.
705 * This is different than kas, but I think kas is buggy.
712 ubik_CallIter(KAM_LockStatus, kaserver->servers, UPUBIKONLY,
713 &count, (long)who->principal, (long)who->instance, (long)&locked, 0,
714 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
717 if ((locked < *lockedUntil) || !once) {
718 *lockedUntil = locked;
723 } while ((tst != UNOSERVERS) && (locked != 0));
726 * Check to see if any server reported this principal unlocked.
729 if ((tst == 0) && (locked == 0)) {
732 if ((tst == 0) || (tst == UNOSERVERS)) {
736 fail_GetPrincipalLockStatus:
745 * kas_PrincipalGet - retrieve information about a single principal.
749 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
751 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
753 * IN who - a kas_identity_p containing the identity of the principal
756 * OUT principal - upon successful completion contains information
761 * No locks are obtained or released by this function
765 * Returns != 0 upon successful completion.
769 kas_PrincipalGet(const void *cellHandle, const void *serverHandle,
770 const kas_identity_p who, kas_principalEntry_p principal,
774 afs_status_t tst = 0;
775 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
776 kas_server_p k_handle = (kas_server_p) serverHandle;
777 kas_server_t kaserver;
778 struct kaentryinfo entry;
781 * Validate input arguments and make rpc.
786 goto fail_kas_PrincipalGet;
789 if (principal == NULL) {
790 tst = ADMKASPRINCIPALNULL;
791 goto fail_kas_PrincipalGet;
794 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
795 goto fail_kas_PrincipalGet;
799 ubik_KAM_GetEntry(kaserver.servers, 0, who->principal,
800 who->instance, KAMAJORVERSION, &entry);
802 goto fail_kas_PrincipalGet;
806 * copy the kaentryinfo structure to our kas_principalEntry_t
809 if (!kaentryinfo_to_kas_principalEntry_t(&entry, principal, &tst)) {
810 goto fail_kas_PrincipalGet;
814 fail_kas_PrincipalGet:
822 typedef struct principal_get {
826 kas_server_t kaserver;
827 kas_identity_t principal[CACHED_ITEMS];
828 } principal_get_t, *principal_get_p;
831 DeletePrincipalSpecificData(void *rpc_specific, afs_status_p st)
834 afs_status_t tst = 0;
835 principal_get_p prin = (principal_get_p) rpc_specific;
837 prin->kaserver.is_valid = 0;
847 GetPrincipalRPC(void *rpc_specific, int slot, int *last_item,
848 int *last_item_contains_data, afs_status_p st)
851 afs_status_t tst = 0;
852 principal_get_p prin = (principal_get_p) rpc_specific;
855 ubik_KAM_ListEntry(prin->kaserver.servers, 0, prin->current,
856 &prin->next, &prin->count, (kaident *)&prin->principal[slot]);
858 prin->current = prin->next;
859 if (prin->next == 0) {
861 *last_item_contains_data = 0;
873 GetPrincipalFromCache(void *rpc_specific, int slot, void *dest,
877 afs_status_t tst = 0;
878 principal_get_p prin = (principal_get_p) rpc_specific;
880 memcpy(dest, &prin->principal[slot], sizeof(kas_identity_t));
890 * kas_PrincipalGetBegin - start the process of iterating over the entire
895 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
897 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
899 * OUT iterationIdP - upon successful completion contains a iterator that
900 * can be passed to kas_PrincipalGetNext.
904 * No locks are obtained or released by this function
908 * Returns != 0 upon successful completion.
914 kas_PrincipalGetBegin(const void *cellHandle, const void *serverHandle,
915 void **iterationIdP, afs_status_p st)
918 afs_status_t tst = 0;
919 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
920 kas_server_p k_handle = (kas_server_p) serverHandle;
921 afs_admin_iterator_p iter = malloc(sizeof(afs_admin_iterator_t));
922 principal_get_p principal = malloc(sizeof(principal_get_t));
930 goto fail_kas_PrincipalGetBegin;
933 if (principal == NULL) {
935 goto fail_kas_PrincipalGetBegin;
938 if (iterationIdP == NULL) {
939 tst = ADMITERATIONIDPNULL;
940 goto fail_kas_PrincipalGetBegin;
943 if (!ChooseValidServer(c_handle, k_handle, &principal->kaserver, &tst)) {
944 goto fail_kas_PrincipalGetBegin;
948 * Initialize the iterator structure
951 principal->current = 0;
953 principal->count = 0;
955 (iter, (void *)principal, GetPrincipalRPC, GetPrincipalFromCache,
956 NULL, DeletePrincipalSpecificData, &tst)) {
957 *iterationIdP = (void *)iter;
961 fail_kas_PrincipalGetBegin:
967 if (principal != NULL) {
979 * kas_PrincipalGetNext - retrieve the next principal from the kaserver.
983 * IN iterationId - an iterator previously returned by kas_PrincipalGetBegin
985 * OUT who - upon successful completion contains the next principal from the
990 * Hold the iterator mutex across the call to the kaserver.
994 * Returns != 0 upon successful completion.
995 * Returns 0 and st == ADMITERATORDONE when the last entry is returned.
999 kas_PrincipalGetNext(const void *iterationId, kas_identity_p who,
1003 afs_status_t tst = 0;
1004 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
1007 * Validate arguments
1011 tst = ADMKASWHONULL;
1012 goto fail_kas_PrincipalGetNext;
1016 tst = ADMITERATORNULL;
1017 goto fail_kas_PrincipalGetNext;
1020 rc = IteratorNext(iter, (void *)who, &tst);
1022 fail_kas_PrincipalGetNext:
1031 * kas_PrincipalGetDone - finish using a principal iterator
1035 * IN iterationId - an iterator previously returned by kas_PrincipalGetBegin
1039 * No locks are held by this function.
1043 * Returns != 0 upon successful completion.
1047 * It is the user's responsibility to make sure kas_PrincipalGetDone
1048 * is called only once for each iterator.
1052 kas_PrincipalGetDone(const void *iterationIdP, afs_status_p st)
1055 afs_status_t tst = 0;
1056 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationIdP;
1063 tst = ADMITERATORNULL;
1064 goto fail_kas_PrincipalGetDone;
1067 rc = IteratorDone(iter, &tst);
1069 fail_kas_PrincipalGetDone:
1078 * kas_PrincipalKeySet - set a principal's password to a known value.
1082 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1084 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1086 * IN who - the principal for whom the password is being set.
1088 * IN keyVersion - the version number of the new key.
1090 * IN key - the new password.
1094 * No locks are held by this function.
1098 * Returns != 0 upon successful completion.
1102 kas_PrincipalKeySet(const void *cellHandle, const void *serverHandle,
1103 const kas_identity_p who, int keyVersion,
1104 const kas_encryptionKey_p kas_keyp, afs_status_p st)
1107 afs_status_t tst = 0;
1108 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1109 kas_server_p k_handle = (kas_server_p) serverHandle;
1110 kas_server_t kaserver;
1114 * Validate input arguments and make rpc.
1118 tst = ADMKASWHONULL;
1119 goto fail_kas_PrincipalKeySet;
1122 if (kas_keyp == NULL) {
1123 tst = ADMKASKEYNULL;
1124 goto fail_kas_PrincipalKeySet;
1127 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
1128 goto fail_kas_PrincipalKeySet;
1131 memcpy(&key, kas_keyp, sizeof(key));
1134 ubik_KAM_SetPassword(kaserver.servers, 0, who->principal,
1135 who->instance, keyVersion, key);
1136 memset(&key, 0, sizeof(key));
1138 goto fail_kas_PrincipalKeySet;
1141 /* If we failed to fail we must have succeeded */
1144 fail_kas_PrincipalKeySet:
1153 * kas_PrincipalLockStatusGet - determine a principal's lock status.
1157 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1159 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1161 * IN who - the principal whose lock status is being checked.
1163 * OUT lock_end_timeP - the number of seconds until the principal is unlocked.
1164 * If 0 => user is unlocked.
1168 * No locks are held by this function.
1172 * Returns != 0 upon successful completion.
1176 * See the comments in GetPrincipalLockStatus regarding how the locking data
1177 * is kept INconsistently between servers.
1181 kas_PrincipalLockStatusGet(const void *cellHandle, const void *serverHandle,
1182 const kas_identity_p who,
1183 unsigned int *lock_end_timeP, afs_status_p st)
1186 afs_status_t tst = 0;
1187 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1188 kas_server_p k_handle = (kas_server_p) serverHandle;
1189 kas_server_t kaserver;
1192 * Validate input arguments and make rpc.
1196 tst = ADMKASWHONULL;
1197 goto fail_kas_PrincipalLockStatusGet;
1200 if (lock_end_timeP == NULL) {
1201 tst = ADMKASLOCKENDTIMEPNULL;
1202 goto fail_kas_PrincipalLockStatusGet;
1205 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
1206 goto fail_kas_PrincipalLockStatusGet;
1209 rc = GetPrincipalLockStatus(&kaserver, who, lock_end_timeP, &tst);
1211 fail_kas_PrincipalLockStatusGet:
1220 * kas_PrincipalUnlock - unlock a principal.
1224 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1226 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1228 * IN who - the principal who is being unlocked.
1232 * No locks are held by this function.
1236 * Returns != 0 upon successful completion.
1240 * See the comments in GetPrincipalLockStatus regarding how the locking data
1241 * is kept INconsistently between servers.
1245 kas_PrincipalUnlock(const void *cellHandle, const void *serverHandle,
1246 const kas_identity_p who, afs_status_p st)
1249 afs_status_t tst = 0;
1250 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1251 kas_server_p k_handle = (kas_server_p) serverHandle;
1252 kas_server_t kaserver;
1254 afs_status_t save_tst = 0;
1257 * Validate input arguments and make rpc.
1261 tst = ADMKASWHONULL;
1262 goto fail_kas_PrincipalUnlock;
1265 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
1266 goto fail_kas_PrincipalUnlock;
1271 ubik_CallIter(KAM_Unlock, kaserver.servers, 0, &count,
1272 (long)who->principal, (long)who->instance, 0, 0, 0,
1273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1274 if (tst && (tst != UNOSERVERS)) {
1275 if (save_tst == 0) {
1276 save_tst = tst; /* save the first failure */
1279 } while (tst != UNOSERVERS);
1281 if ((tst == 0) || (tst == UNOSERVERS)) {
1285 fail_kas_PrincipalUnlock:
1294 getPrincipalFlags(const void *cellHandle, const void *serverHandle,
1295 const kas_identity_p who, afs_int32 * cur_flags,
1299 afs_status_t tst = 0;
1300 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1301 kas_server_p k_handle = (kas_server_p) serverHandle;
1302 kas_server_t kaserver;
1303 struct kaentryinfo tentry;
1305 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
1306 goto fail_getPrincipalFlags;
1310 ubik_KAM_GetEntry(kaserver.servers, 0, who->principal,
1311 who->instance, KAMAJORVERSION, &tentry);
1313 *cur_flags = tentry.flags;
1317 fail_getPrincipalFlags:
1326 * kas_PrincipalFieldsSet - modify an existing principal.
1330 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1332 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1334 * IN who - the principal who is being modified.
1336 * IN isAdmin - the admin status of the principal.
1338 * IN grantTickets - should the TGS issue tickets for the principal.
1340 * IN canEncrypt - should the TGS allow the use of encryption via the
1343 * IN canChangePassword - should the principal be allowed to change their
1346 * IN expirationDate - the date when the principal will expire.
1348 * IN maxTicketLifetime - the maximum lifetime of a ticket issued for
1351 * IN passwordExpires - the maximum number of days a particular
1352 * password can be used. The limit is 255, 0 => no expiration.
1354 * IN passwordReuse - can a password be reused by this principal.
1356 * IN failedPasswordAttempts - number of failed login attempts before
1357 * a principal is locked. The limit is 255, 0 => no limit.
1359 * IN failedPasswordLockTime - the number of seconds a principal is
1360 * locked once failedPasswordAttempts is reached. Some bizarre rounding
1361 * occurs for this value, see kas for more details.
1365 * No locks are held by this function.
1369 * Returns != 0 upon successful completion.
1373 * See the comments in GetPrincipalLockStatus regarding how the locking data
1374 * is kept INconsistently between servers.
1378 kas_PrincipalFieldsSet(const void *cellHandle, const void *serverHandle,
1379 const kas_identity_p who, const kas_admin_p isAdmin,
1380 const kas_tgs_p grantTickets,
1381 const kas_enc_p canEncrypt,
1382 const kas_cpw_p canChangePassword,
1383 const unsigned int *expirationDate,
1384 const unsigned int *maxTicketLifetime,
1385 const unsigned int *passwordExpires,
1386 const kas_rpw_p passwordReuse,
1387 const unsigned int *failedPasswordAttempts,
1388 const unsigned int *failedPasswordLockTime,
1392 afs_status_t tst = 0;
1393 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1394 kas_server_p k_handle = (kas_server_p) serverHandle;
1395 kas_server_t kaserver;
1396 afs_int32 flags = 0;
1397 Date expiration = 0;
1398 afs_int32 lifetime = 0;
1400 char spare_bytes[4] = { 0, 0, 0, 0 };
1401 int somethings_changing = 0;
1404 * Validate input arguments.
1408 tst = ADMKASWHONULL;
1409 goto fail_kas_PrincipalFieldsSet;
1413 * set flags based upon input
1415 * If we're changing the flags, we need to get the current value of
1416 * the flags first and then make the changes
1419 if ((isAdmin != NULL) || (grantTickets != NULL) || (canEncrypt != NULL)
1420 || (canChangePassword != NULL)) {
1421 if (!getPrincipalFlags(cellHandle, serverHandle, who, &flags, &tst)) {
1422 goto fail_kas_PrincipalFieldsSet;
1426 if (isAdmin != NULL) {
1427 somethings_changing = 1;
1428 if (*isAdmin == KAS_ADMIN) {
1435 if (grantTickets != NULL) {
1436 somethings_changing = 1;
1437 if (*grantTickets == NO_TGS) {
1444 if (canEncrypt != NULL) {
1445 somethings_changing = 1;
1446 if (*canEncrypt == NO_ENCRYPT) {
1449 flags &= ~KAFNOSEAL;
1453 if (canChangePassword != NULL) {
1454 somethings_changing = 1;
1455 if (*canChangePassword == NO_CHANGE_PASSWORD) {
1462 flags = (flags & KAF_SETTABLE_FLAGS) | KAFNORMAL;
1464 if (expirationDate != NULL) {
1465 somethings_changing = 1;
1466 expiration = *expirationDate;
1469 if (maxTicketLifetime != NULL) {
1470 somethings_changing = 1;
1471 lifetime = *maxTicketLifetime;
1474 if (passwordExpires != NULL) {
1475 if (*passwordExpires > 255) {
1476 tst = ADMKASPASSWORDEXPIRESTOOBIG;
1477 goto fail_kas_PrincipalFieldsSet;
1479 somethings_changing = 1;
1480 spare_bytes[0] = *passwordExpires + 1;
1483 if (passwordReuse != NULL) {
1484 somethings_changing = 1;
1485 if (*passwordReuse == REUSE_PASSWORD) {
1486 spare_bytes[1] = KA_REUSEPW;
1488 spare_bytes[1] = KA_NOREUSEPW;
1492 if (failedPasswordAttempts != NULL) {
1493 if (*failedPasswordAttempts > 255) {
1494 tst = ADMKASFAILEDPASSWORDATTEMPTSTOOBIG;
1495 goto fail_kas_PrincipalFieldsSet;
1497 somethings_changing = 1;
1498 spare_bytes[2] = *failedPasswordAttempts + 1;
1501 if (failedPasswordLockTime != NULL) {
1502 if (*failedPasswordLockTime > 36 * 60 * 60) {
1503 tst = ADMKASFAILEDPASSWORDLOCKTIME;
1504 goto fail_kas_PrincipalFieldsSet;
1506 somethings_changing = 1;
1507 spare_bytes[3] = ((*failedPasswordLockTime + 511) >> 9) + 1;
1510 was_spare = pack_long(spare_bytes);
1512 if (somethings_changing) {
1513 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
1514 goto fail_kas_PrincipalFieldsSet;
1517 ubik_KAM_SetFields(kaserver.servers, 0, who->principal,
1518 who->instance, flags, expiration, lifetime, -1,
1524 tst = ADMKASPRINCIPALFIELDSNOCHANGE;
1527 fail_kas_PrincipalFieldsSet:
1536 * kas_ServerStatsGet - get server statistics.
1540 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1542 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1544 * OUT stats - the statistics retrieved.
1548 * No locks are held by this function.
1552 * Returns != 0 upon successful completion.
1556 kas_ServerStatsGet(const void *cellHandle, const void *serverHandle,
1557 kas_serverStats_p stats, afs_status_p st)
1560 afs_status_t tst = 0;
1561 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1562 kas_server_p k_handle = (kas_server_p) serverHandle;
1563 kas_server_t kaserver;
1570 * Validate input arguments and make rpc.
1573 if (stats == NULL) {
1574 tst = ADMKASSTATSNULL;
1575 goto fail_kas_ServerStatsGet;
1578 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
1579 goto fail_kas_ServerStatsGet;
1583 ubik_KAM_GetStats(kaserver.servers, 0, KAMAJORVERSION, &admins,
1584 &statics, &dynamics);
1586 goto fail_kas_ServerStatsGet;
1589 stats->allocations = statics.allocs;
1590 stats->frees = statics.frees;
1591 stats->changePasswordRequests = statics.cpws;
1592 stats->adminAccounts = admins;
1593 stats->host = dynamics.host;
1594 stats->serverStartTime = dynamics.start_time;
1595 stats->hashTableUtilization = dynamics.hashTableUtilization;
1597 i = sizeof(kas_serverProcStats_t);
1598 memcpy(&stats->authenticate, &dynamics.Authenticate, i);
1599 memcpy(&stats->changePassword, &dynamics.ChangePassword, i);
1600 memcpy(&stats->getTicket, &dynamics.GetTicket, i);
1601 memcpy(&stats->createUser, &dynamics.CreateUser, i);
1602 memcpy(&stats->setPassword, &dynamics.SetPassword, i);
1603 memcpy(&stats->setFields, &dynamics.SetFields, i);
1604 memcpy(&stats->deleteUser, &dynamics.DeleteUser, i);
1605 memcpy(&stats->getEntry, &dynamics.GetEntry, i);
1606 memcpy(&stats->listEntry, &dynamics.ListEntry, i);
1607 memcpy(&stats->getStats, &dynamics.GetStats, i);
1608 memcpy(&stats->getPassword, &dynamics.GetPassword, i);
1609 memcpy(&stats->getRandomKey, &dynamics.GetRandomKey, i);
1610 memcpy(&stats->debug, &dynamics.Debug, i);
1611 memcpy(&stats->udpAuthenticate, &dynamics.UAuthenticate, i);
1612 memcpy(&stats->udpGetTicket, &dynamics.UGetTicket, i);
1613 memcpy(&stats->unlock, &dynamics.Unlock, i);
1614 memcpy(&stats->lockStatus, &dynamics.LockStatus, i);
1616 stats->stringChecks = dynamics.string_checks;
1619 fail_kas_ServerStatsGet:
1628 * kas_ServerDebugGet - get server debug info.
1632 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1634 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1636 * OUT stats - the debug info retrieved.
1640 * No locks are held by this function.
1644 * Returns != 0 upon successful completion.
1648 kas_ServerDebugGet(const void *cellHandle, const void *serverHandle,
1649 kas_serverDebugInfo_p debug, afs_status_p st)
1652 afs_status_t tst = 0;
1653 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1654 kas_server_p k_handle = (kas_server_p) serverHandle;
1655 kas_server_t kaserver;
1656 struct ka_debugInfo info;
1660 * Validate input arguments and make rpc.
1663 if (debug == NULL) {
1664 tst = ADMKASDEBUGNULL;
1665 goto fail_kas_ServerDebugGet;
1668 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
1669 goto fail_kas_ServerDebugGet;
1671 tst = ubik_KAM_Debug(kaserver.servers, 0, KAMAJORVERSION, 0, &info);
1673 goto fail_kas_ServerDebugGet;
1675 debug->host = info.host;
1676 debug->serverStartTime = info.startTime;
1677 debug->currentTime = info.reserved1;
1678 debug->noAuth = info.noAuth;
1679 debug->lastTransaction = info.lastTrans;
1680 strcpy(debug->lastOperation, info.lastOperation);
1681 strcpy(debug->lastPrincipalAuth, info.lastAuth);
1682 strcpy(debug->lastPrincipalUDPAuth, info.lastUAuth);
1683 strcpy(debug->lastPrincipalTGS, info.lastTGS);
1684 strcpy(debug->lastPrincipalUDPTGS, info.lastUTGS);
1685 strcpy(debug->lastPrincipalAdmin, info.lastAdmin);
1686 strcpy(debug->lastServerTGS, info.lastTGSServer);
1687 strcpy(debug->lastServerUDPTGS, info.lastUTGSServer);
1688 debug->nextAutoCheckPointWrite = info.nextAutoCPW;
1689 debug->updatesRemainingBeforeAutoCheckPointWrite = info.updatesRemaining;
1690 debug->dbHeaderRead = info.dbHeaderRead;
1691 debug->dbVersion = info.dbVersion;
1692 debug->dbFreePtr = info.dbFreePtr;
1693 debug->dbEOFPtr = info.dbEofPtr;
1694 debug->dbKvnoPtr = info.dbKvnoPtr;
1695 debug->dbSpecialKeysVersion = info.dbSpecialKeysVersion;
1696 debug->dbHeaderLock = info.cheader_lock;
1697 debug->keyCacheLock = info.keycache_lock;
1698 debug->keyCacheVersion = info.kcVersion;
1699 debug->keyCacheSize = info.kcSize;
1700 debug->keyCacheUsed = info.kcUsed;
1701 for (i = 0; i < info.kcUsed; i++) {
1702 debug->keyCache[i].lastUsed = info.kcInfo[i].used;
1703 debug->keyCache[i].keyVersionNumber = info.kcInfo[i].kvno;
1704 debug->keyCache[i].primary = info.kcInfo[i].primary;
1705 debug->keyCache[i].keyCheckSum = info.kcInfo[i].keycksum;
1706 strcpy(debug->keyCache[i].principal, info.kcInfo[i].principal);
1710 fail_kas_ServerDebugGet:
1719 * kas_ServerRandomKeyGet - get a random key from a server.
1723 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1725 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1727 * OUT key - a random key.
1731 * No locks are held by this function.
1735 * Returns != 0 upon successful completion.
1739 kas_ServerRandomKeyGet(const void *cellHandle, const void *serverHandle,
1740 kas_encryptionKey_p kas_keyp, afs_status_p st)
1743 afs_status_t tst = 0;
1744 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1745 kas_server_p k_handle = (kas_server_p) serverHandle;
1746 kas_server_t kaserver;
1750 * Validate input arguments and make rpc.
1753 if (kas_keyp == NULL) {
1754 tst = ADMKASKEYNULL;
1755 goto fail_kas_ServerRandomKeyGet;
1758 if (!ChooseValidServer(c_handle, k_handle, &kaserver, &tst)) {
1759 goto fail_kas_ServerRandomKeyGet;
1762 tst = ubik_KAM_GetRandomKey(kaserver.servers, 0, &key);
1764 goto fail_kas_ServerRandomKeyGet;
1766 memcpy(kas_keyp, &key, sizeof(*kas_keyp));
1769 fail_kas_ServerRandomKeyGet:
1778 * kas_StringToKey - turn a string key into a key.
1782 * IN cellName - the name of the cell where the key will be used.
1784 * IN string - the string to be converted.
1786 * OUT key - the encryption key.
1790 * No locks are held by this function.
1794 * Returns != 0 upon successful completion.
1798 kas_StringToKey(const char *cellName, const char *string,
1799 kas_encryptionKey_p key, afs_status_p st)
1802 afs_status_t tst = 0;
1804 ka_StringToKey((char *)string, (char *)cellName, (struct ktc_encryptionKey *)key);
1815 * kas_KeyCheckSum - compute the checksum of an encryption key.
1819 * IN key - the encryption key.
1821 * OUT cksumP - key checksum
1825 * No locks are held by this function.
1829 * Returns != 0 upon successful completion.
1833 kas_KeyCheckSum(const kas_encryptionKey_p key, unsigned int *cksumP,
1837 afs_status_t tst = 0;
1840 if ((tst = ka_KeyCheckSum((char *)key, &cksum32)) == 0) {