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>
16 #ifdef IGNORE_SOME_GCC_WARNINGS
17 # pragma GCC diagnostic warning "-Wstrict-prototypes"
23 #include <rx/rxstat.h>
24 #include "afs_kasAdmin.h"
25 #include "../adminutil/afs_AdminInternal.h"
26 #include <afs/afs_AdminErrors.h>
27 #include <afs/afs_utilAdmin.h>
28 #include <afs/kauth.h>
29 #include <afs/kautils.h>
30 #include <afs/kaport.h>
38 struct ubik_client
*servers
;
41 } kas_server_t
, *kas_server_p
;
44 * IsValidServerHandle - verify the validity of a kas_server_t handle.
48 * IN serverHandle - the handle to be verified.
52 * No locks are obtained or released by this function
56 * Returns != 0 upon successful completion.
60 IsValidServerHandle(const kas_server_p serverHandle
, afs_status_p st
)
66 * Validate input parameters
69 if (serverHandle
== NULL
) {
70 tst
= ADMKASSERVERHANDLENULL
;
71 goto fail_IsValidServerHandle
;
74 if ((serverHandle
->begin_magic
!= BEGIN_MAGIC
)
75 || (serverHandle
->end_magic
!= END_MAGIC
)) {
76 tst
= ADMKASSERVERHANDLEBADMAGIC
;
77 goto fail_IsValidServerHandle
;
80 if (!serverHandle
->is_valid
) {
81 tst
= ADMKASSERVERHANDLENOTVALID
;
82 goto fail_IsValidServerHandle
;
85 if (serverHandle
->servers
== NULL
) {
86 tst
= ADMKASSERVERHANDLENOSERVERS
;
87 goto fail_IsValidServerHandle
;
91 fail_IsValidServerHandle
:
100 * IsValidCellHandle - verify the validity of a afs_cell_handle_t handle
101 * for doing kas related functions.
105 * IN cellHandle - the handle to be verified.
109 * No locks are obtained or released by this function
113 * Returns != 0 upon successful completion.
117 IsValidCellHandle(const afs_cell_handle_p cellHandle
, afs_status_p st
)
120 afs_status_t tst
= 0;
123 * Validate input parameters
126 if (!CellHandleIsValid((void *)cellHandle
, &tst
)) {
127 goto fail_IsValidCellHandle
;
130 if (!cellHandle
->kas_valid
) {
131 tst
= ADMCLIENTCELLKASINVALID
;
132 goto fail_IsValidCellHandle
;
135 if (cellHandle
->kas
== NULL
) {
136 tst
= ADMCLIENTCELLKASNULL
;
137 goto fail_IsValidCellHandle
;
141 fail_IsValidCellHandle
:
150 * For all kas admin functions that take a cellHandle and a serverHandle,
151 * the intention is that is the cellHandle is not NULL, we should use
152 * it. Otherwise, we use the serverHandle. It is an error for both
153 * of these parameters to be non-NULL.
157 * ChooseValidServer - given a serverHandle and a cellHandle, choose the
158 * one that is non-NULL, validate it, and return a ubik_client structure
163 * IN cellHandle - the cell where kas calls are to be made
165 * IN serverHandle - the group of server(s) that should be used to satisfy
170 * No locks are obtained or released by this function
174 * Returns != 0 upon successful completion.
178 ChooseValidServer(const afs_cell_handle_p cellHandle
,
179 const kas_server_p serverHandle
, kas_server_p kasHandle
,
183 afs_status_t tst
= 0;
186 * Validate input parameters
189 if (kasHandle
== NULL
) {
190 tst
= ADMKASKASHANDLENULL
;
191 goto fail_ChooseValidServer
;
195 * Only one of the input handle parameters to this function should
198 if ((cellHandle
== NULL
) && (serverHandle
== NULL
)) {
199 tst
= ADMKASCELLHANDLEANDSERVERHANDLENULL
;
200 goto fail_ChooseValidServer
;
203 if ((cellHandle
!= NULL
) && (serverHandle
!= NULL
)) {
204 tst
= ADMKASCELLHANDLEANDSERVERHANDLENOTNULL
;
205 goto fail_ChooseValidServer
;
209 * Validate the non-NULL handle
212 if (cellHandle
!= NULL
) {
213 if (IsValidCellHandle(cellHandle
, &tst
)) {
214 kasHandle
->servers
= cellHandle
->kas
;
215 kasHandle
->cell
= cellHandle
->working_cell
;
217 goto fail_ChooseValidServer
;
220 if (IsValidServerHandle(serverHandle
, &tst
)) {
221 kasHandle
->servers
= serverHandle
->servers
;
222 kasHandle
->cell
= serverHandle
->cell
;
224 goto fail_ChooseValidServer
;
228 kasHandle
->begin_magic
= BEGIN_MAGIC
;
229 kasHandle
->end_magic
= END_MAGIC
;
230 kasHandle
->is_valid
= 1;
233 fail_ChooseValidServer
:
243 kaentryinfo_to_kas_principalEntry_t(struct kaentryinfo
*from
,
244 kas_principalEntry_p to
, afs_status_p st
)
247 afs_status_t tst
= 0;
249 unsigned char misc_stuff
[4];
252 tst
= ADMKASFROMNULL
;
253 goto fail_kaentryinfo_to_kas_principalEntry_t
;
258 goto fail_kaentryinfo_to_kas_principalEntry_t
;
261 if (from
->flags
& KAFADMIN
) {
262 to
->adminSetting
= KAS_ADMIN
;
264 to
->adminSetting
= NO_KAS_ADMIN
;
267 if (from
->flags
& KAFNOTGS
) {
268 to
->tgsSetting
= NO_TGS
;
270 to
->tgsSetting
= TGS
;
273 if (from
->flags
& KAFNOSEAL
) {
274 to
->encSetting
= NO_ENCRYPT
;
276 to
->encSetting
= ENCRYPT
;
279 if (from
->flags
& KAFNOCPW
) {
280 to
->cpwSetting
= NO_CHANGE_PASSWORD
;
282 to
->cpwSetting
= CHANGE_PASSWORD
;
285 reuse
= (short)from
->reserved3
;
287 to
->rpwSetting
= REUSE_PASSWORD
;
289 to
->rpwSetting
= NO_REUSE_PASSWORD
;
293 if (from
->user_expiration
== NEVERDATE
) {
294 to
->userExpiration
= 0;
296 to
->userExpiration
= from
->user_expiration
;
299 to
->lastModTime
= from
->modification_time
;
300 strcpy(to
->lastModPrincipal
.principal
, from
->modification_user
.name
);
301 strcpy(to
->lastModPrincipal
.instance
, from
->modification_user
.instance
);
302 to
->lastChangePasswordTime
= from
->change_password_time
;
303 to
->maxTicketLifetime
= from
->max_ticket_lifetime
;
304 to
->keyVersion
= from
->key_version
;
305 memcpy(&to
->key
, &from
->key
, sizeof(to
->key
));
306 to
->keyCheckSum
= from
->keyCheckSum
;
308 unpack_long(from
->misc_auth_bytes
, misc_stuff
);
309 to
->daysToPasswordExpire
= misc_stuff
[0];
310 to
->failLoginCount
= misc_stuff
[2];
311 to
->lockTime
= misc_stuff
[3] << 9;
314 fail_kaentryinfo_to_kas_principalEntry_t
:
323 * kas_ServerOpen - open a handle to a set of kaserver's.
327 * IN cellHandle - a previously opened cellHandle that corresponds
328 * to the cell where the server(s) live.
330 * IN serverList - a NULL terminated list (a la argv) of server's that
333 * OUT serverHandleP - a pointer to a void pointer that upon successful
334 * completion contains serverHandle that can be used in other kas functions.
338 * No locks are obtained or released by this function
342 * Returns != 0 upon successful completion.
346 * This function make some assumptions about the afsconf_cell used by
347 * ka_AuthSpecificServersConn (since I just wrote ka_AuthSpecificServersConn).
348 * It only fills in the fields that are required.
350 * Also we assume that the servers listed are members of the cell in
351 * cellHandle without verifying that this is in fact the case. kas itself
352 * always assumes that the -servers parameter lists servers in the current
353 * cell without verifying, so I am no worse than the current
354 * implementation. In fact I'm actually a little more flexible since you
355 * can actually use my serverList to play with servers in another cell.
356 * You can't do that with kas. For certain functions in kas the same
357 * cell assumption can cause things to fail (the ka_StringToKey function in
362 kas_ServerOpen(const void *cellHandle
, const char **serverList
,
363 void **serverHandleP
, afs_status_p st
)
366 afs_status_t tst
= 0;
367 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
368 int server_count
= 0, server_addr
;
369 struct afsconf_cell server_info
;
370 kas_server_p k_handle
= malloc(sizeof(kas_server_t
));
373 * Validate input parameters
376 if (c_handle
== NULL
) {
377 tst
= ADMCLIENTCELLHANDLENULL
;
378 goto fail_kas_ServerOpen
;
381 if (c_handle
->kas_valid
== 0) {
382 tst
= ADMCLIENTCELLKASINVALID
;
383 goto fail_kas_ServerOpen
;
386 if (serverList
== NULL
) {
387 tst
= ADMKASSERVERLISTNULL
;
388 goto fail_kas_ServerOpen
;
391 if (serverHandleP
== NULL
) {
392 tst
= ADMKASSERVERHANDLEPNULL
;
393 goto fail_kas_ServerOpen
;
396 if (k_handle
== NULL
) {
398 goto fail_kas_ServerOpen
;
401 k_handle
->begin_magic
= BEGIN_MAGIC
;
402 k_handle
->end_magic
= END_MAGIC
;
403 k_handle
->is_valid
= 0;
404 k_handle
->servers
= NULL
;
407 * Convert serverList to numeric addresses
410 for (server_count
= 0; serverList
[server_count
] != NULL
; server_count
++) {
411 if (server_count
>= MAXHOSTSPERCELL
) {
412 tst
= ADMKASSERVERLISTTOOLONG
;
413 goto fail_kas_ServerOpen
;
415 if (util_AdminServerAddressGetFromName
416 (serverList
[server_count
], &server_addr
, &tst
)) {
417 server_info
.hostAddr
[server_count
].sin_addr
.s_addr
=
419 server_info
.hostAddr
[server_count
].sin_port
=
420 htons(AFSCONF_KAUTHPORT
);
422 goto fail_kas_ServerOpen
;
426 if (server_count
== 0) {
427 tst
= ADMKASSERVERLISTEMPTY
;
428 goto fail_kas_ServerOpen
;
432 * Get a ubik_client handle for the specified servers
434 server_info
.numServers
= server_count
;
437 ka_AuthSpecificServersConn(KA_MAINTENANCE_SERVICE
,
438 &c_handle
->tokens
->kas_token
,
439 &server_info
, &k_handle
->servers
))) {
440 k_handle
->is_valid
= 1;
441 k_handle
->cell
= c_handle
->working_cell
;
442 *serverHandleP
= (void *)k_handle
;
444 goto fail_kas_ServerOpen
;
450 if ((rc
== 0) && (k_handle
!= NULL
)) {
461 * kas_ServerClose - close a serverHandle.
465 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
469 * No locks are obtained or released by this function
473 * Returns != 0 upon successful completion.
477 kas_ServerClose(const void *serverHandle
, afs_status_p st
)
480 afs_status_t tst
= 0;
481 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
483 if (!IsValidServerHandle(k_handle
, &tst
)) {
484 goto fail_kas_ServerClose
;
487 tst
= ubik_ClientDestroy(k_handle
->servers
);
489 goto fail_kas_ServerClose
;
492 k_handle
->is_valid
= 0;
496 fail_kas_ServerClose
:
505 * kas_PrincipalCreate - create a new principal.
509 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
511 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
513 * IN who - a kas_identity_p containing the identity of the new principal
516 * IN password - the new principal's initial password.
520 * No locks are obtained or released by this function
524 * Returns != 0 upon successful completion.
528 kas_PrincipalCreate(const void *cellHandle
, const void *serverHandle
,
529 const kas_identity_p who
, const char *password
,
533 afs_status_t tst
= 0;
534 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
535 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
536 kas_server_t kaserver
;
538 struct kas_encryptionKey kas_key
;
541 * Validate input arguments and make rpc.
546 goto fail_kas_PrincipalCreate
;
549 if (password
== NULL
) {
550 tst
= ADMKASPASSWORDNULL
;
551 goto fail_kas_PrincipalCreate
;
554 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
555 goto fail_kas_PrincipalCreate
;
558 if (!kas_StringToKey(kaserver
.cell
, password
, &kas_key
, &tst
)) {
559 goto fail_kas_PrincipalCreate
;
562 memcpy(&key
, &kas_key
, sizeof(key
));
565 ubik_KAM_CreateUser(kaserver
.servers
, 0, who
->principal
,
568 goto fail_kas_PrincipalCreate
;
573 fail_kas_PrincipalCreate
:
582 * kas_PrincipalDelete - delete an existing principal.
586 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
588 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
590 * IN who - a kas_identity_p containing the identity of the principal
595 * No locks are obtained or released by this function
599 * Returns != 0 upon successful completion.
603 kas_PrincipalDelete(const void *cellHandle
, const void *serverHandle
,
604 const kas_identity_p who
, afs_status_p st
)
607 afs_status_t tst
= 0;
608 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
609 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
610 kas_server_t kaserver
;
613 * Validate input arguments and make rpc.
618 goto fail_kas_PrincipalDelete
;
621 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
622 goto fail_kas_PrincipalDelete
;
625 ubik_KAM_DeleteUser(kaserver
.servers
, 0, who
->principal
,
628 goto fail_kas_PrincipalDelete
;
632 fail_kas_PrincipalDelete
:
641 * GetPrincipalLockStatus - get the lock status of a principal.
645 * IN kaserver - a valid kaserver handle previously returned by
648 * IN who - a kas_identity_p containing the identity of the principal
651 * OUT lockedUntil - the remaining number of seconds the principal is locked.
655 * No locks are obtained or released by this function
659 * Returns != 0 upon successful completion.
663 GetPrincipalLockStatus(const kas_server_p kaserver
, const kas_identity_p who
,
664 unsigned int *lockedUntil
, afs_status_p st
)
667 afs_status_t tst
= 0;
673 * Validate input arguments and make rpc.
676 if (kaserver
== NULL
) {
677 tst
= ADMKASKASERVERNULL
;
678 goto fail_GetPrincipalLockStatus
;
683 goto fail_GetPrincipalLockStatus
;
686 if (lockedUntil
== NULL
) {
687 tst
= ADMKASLOCKEDUNTILNULL
;
688 goto fail_GetPrincipalLockStatus
;
692 * Unlike every other kas rpc we make here, the lock/unlock rpc's
693 * aren't ubik based. So instead of calling ubik_Call, we use
694 * ubik_CallIter. ubik_CallIter steps through the list of hosts
695 * in the ubik_client and calls them one at a time. Since there's
696 * no synchronization of this data across the servers we have to
697 * manually keep track of the shortest time to unlock the user ourselves.
699 * The original inspiration for this function is ka_islocked
700 * in admin_tools.c. I think that function is totally bogus so I'm
703 * This function should contact all the kaservers and request the lock
704 * status of the principal. If any of the servers say the principal is
705 * unlocked, we report it as unlocked. If all the servers say the
706 * principal is locked, we find the server with the shortest lock time
707 * remaining on the principal and return that time.
709 * This is different than kas, but I think kas is buggy.
716 ubik_CallIter(KAM_LockStatus
, kaserver
->servers
, UPUBIKONLY
,
717 &count
, (long)who
->principal
, (long)who
->instance
, (long)&locked
, 0,
718 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
721 if ((locked
< *lockedUntil
) || !once
) {
722 *lockedUntil
= locked
;
727 } while ((tst
!= UNOSERVERS
) && (locked
!= 0));
730 * Check to see if any server reported this principal unlocked.
733 if ((tst
== 0) && (locked
== 0)) {
736 if ((tst
== 0) || (tst
== UNOSERVERS
)) {
740 fail_GetPrincipalLockStatus
:
749 * kas_PrincipalGet - retrieve information about a single principal.
753 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
755 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
757 * IN who - a kas_identity_p containing the identity of the principal
760 * OUT principal - upon successful completion contains information
765 * No locks are obtained or released by this function
769 * Returns != 0 upon successful completion.
773 kas_PrincipalGet(const void *cellHandle
, const void *serverHandle
,
774 const kas_identity_p who
, kas_principalEntry_p principal
,
778 afs_status_t tst
= 0;
779 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
780 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
781 kas_server_t kaserver
;
782 struct kaentryinfo entry
;
785 * Validate input arguments and make rpc.
790 goto fail_kas_PrincipalGet
;
793 if (principal
== NULL
) {
794 tst
= ADMKASPRINCIPALNULL
;
795 goto fail_kas_PrincipalGet
;
798 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
799 goto fail_kas_PrincipalGet
;
803 ubik_KAM_GetEntry(kaserver
.servers
, 0, who
->principal
,
804 who
->instance
, KAMAJORVERSION
, &entry
);
806 goto fail_kas_PrincipalGet
;
810 * copy the kaentryinfo structure to our kas_principalEntry_t
813 if (!kaentryinfo_to_kas_principalEntry_t(&entry
, principal
, &tst
)) {
814 goto fail_kas_PrincipalGet
;
818 fail_kas_PrincipalGet
:
826 typedef struct principal_get
{
830 kas_server_t kaserver
;
831 kas_identity_t principal
[CACHED_ITEMS
];
832 } principal_get_t
, *principal_get_p
;
835 DeletePrincipalSpecificData(void *rpc_specific
, afs_status_p st
)
838 afs_status_t tst
= 0;
839 principal_get_p prin
= (principal_get_p
) rpc_specific
;
841 prin
->kaserver
.is_valid
= 0;
851 GetPrincipalRPC(void *rpc_specific
, int slot
, int *last_item
,
852 int *last_item_contains_data
, afs_status_p st
)
855 afs_status_t tst
= 0;
856 principal_get_p prin
= (principal_get_p
) rpc_specific
;
859 ubik_KAM_ListEntry(prin
->kaserver
.servers
, 0, prin
->current
,
860 &prin
->next
, &prin
->count
, (kaident
*)&prin
->principal
[slot
]);
862 prin
->current
= prin
->next
;
863 if (prin
->next
== 0) {
865 *last_item_contains_data
= 0;
877 GetPrincipalFromCache(void *rpc_specific
, int slot
, void *dest
,
881 afs_status_t tst
= 0;
882 principal_get_p prin
= (principal_get_p
) rpc_specific
;
884 memcpy(dest
, &prin
->principal
[slot
], sizeof(kas_identity_t
));
894 * kas_PrincipalGetBegin - start the process of iterating over the entire
899 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
901 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
903 * OUT iterationIdP - upon successful completion contains a iterator that
904 * can be passed to kas_PrincipalGetNext.
908 * No locks are obtained or released by this function
912 * Returns != 0 upon successful completion.
918 kas_PrincipalGetBegin(const void *cellHandle
, const void *serverHandle
,
919 void **iterationIdP
, afs_status_p st
)
922 afs_status_t tst
= 0;
923 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
924 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
925 afs_admin_iterator_p iter
= malloc(sizeof(afs_admin_iterator_t
));
926 principal_get_p principal
= malloc(sizeof(principal_get_t
));
934 goto fail_kas_PrincipalGetBegin
;
937 if (principal
== NULL
) {
939 goto fail_kas_PrincipalGetBegin
;
942 if (iterationIdP
== NULL
) {
943 tst
= ADMITERATIONIDPNULL
;
944 goto fail_kas_PrincipalGetBegin
;
947 if (!ChooseValidServer(c_handle
, k_handle
, &principal
->kaserver
, &tst
)) {
948 goto fail_kas_PrincipalGetBegin
;
952 * Initialize the iterator structure
955 principal
->current
= 0;
957 principal
->count
= 0;
959 (iter
, (void *)principal
, GetPrincipalRPC
, GetPrincipalFromCache
,
960 NULL
, DeletePrincipalSpecificData
, &tst
)) {
961 *iterationIdP
= (void *)iter
;
965 fail_kas_PrincipalGetBegin
:
971 if (principal
!= NULL
) {
983 * kas_PrincipalGetNext - retrieve the next principal from the kaserver.
987 * IN iterationId - an iterator previously returned by kas_PrincipalGetBegin
989 * OUT who - upon successful completion contains the next principal from the
994 * Hold the iterator mutex across the call to the kaserver.
998 * Returns != 0 upon successful completion.
999 * Returns 0 and st == ADMITERATORDONE when the last entry is returned.
1003 kas_PrincipalGetNext(const void *iterationId
, kas_identity_p who
,
1007 afs_status_t tst
= 0;
1008 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
1011 * Validate arguments
1015 tst
= ADMKASWHONULL
;
1016 goto fail_kas_PrincipalGetNext
;
1020 tst
= ADMITERATORNULL
;
1021 goto fail_kas_PrincipalGetNext
;
1024 rc
= IteratorNext(iter
, (void *)who
, &tst
);
1026 fail_kas_PrincipalGetNext
:
1035 * kas_PrincipalGetDone - finish using a principal iterator
1039 * IN iterationId - an iterator previously returned by kas_PrincipalGetBegin
1043 * No locks are held by this function.
1047 * Returns != 0 upon successful completion.
1051 * It is the user's responsibility to make sure kas_PrincipalGetDone
1052 * is called only once for each iterator.
1056 kas_PrincipalGetDone(const void *iterationIdP
, afs_status_p st
)
1059 afs_status_t tst
= 0;
1060 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationIdP
;
1067 tst
= ADMITERATORNULL
;
1068 goto fail_kas_PrincipalGetDone
;
1071 rc
= IteratorDone(iter
, &tst
);
1073 fail_kas_PrincipalGetDone
:
1082 * kas_PrincipalKeySet - set a principal's password to a known value.
1086 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1088 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1090 * IN who - the principal for whom the password is being set.
1092 * IN keyVersion - the version number of the new key.
1094 * IN key - the new password.
1098 * No locks are held by this function.
1102 * Returns != 0 upon successful completion.
1106 kas_PrincipalKeySet(const void *cellHandle
, const void *serverHandle
,
1107 const kas_identity_p who
, int keyVersion
,
1108 const kas_encryptionKey_p kas_keyp
, afs_status_p st
)
1111 afs_status_t tst
= 0;
1112 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1113 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
1114 kas_server_t kaserver
;
1118 * Validate input arguments and make rpc.
1122 tst
= ADMKASWHONULL
;
1123 goto fail_kas_PrincipalKeySet
;
1126 if (kas_keyp
== NULL
) {
1127 tst
= ADMKASKEYNULL
;
1128 goto fail_kas_PrincipalKeySet
;
1131 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
1132 goto fail_kas_PrincipalKeySet
;
1135 memcpy(&key
, kas_keyp
, sizeof(key
));
1138 ubik_KAM_SetPassword(kaserver
.servers
, 0, who
->principal
,
1139 who
->instance
, keyVersion
, key
);
1140 memset(&key
, 0, sizeof(key
));
1142 goto fail_kas_PrincipalKeySet
;
1145 /* If we failed to fail we must have succeeded */
1148 fail_kas_PrincipalKeySet
:
1157 * kas_PrincipalLockStatusGet - determine a principal's lock status.
1161 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1163 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1165 * IN who - the principal whose lock status is being checked.
1167 * OUT lock_end_timeP - the number of seconds until the principal is unlocked.
1168 * If 0 => user is unlocked.
1172 * No locks are held by this function.
1176 * Returns != 0 upon successful completion.
1180 * See the comments in GetPrincipalLockStatus regarding how the locking data
1181 * is kept INconsistently between servers.
1185 kas_PrincipalLockStatusGet(const void *cellHandle
, const void *serverHandle
,
1186 const kas_identity_p who
,
1187 unsigned int *lock_end_timeP
, afs_status_p st
)
1190 afs_status_t tst
= 0;
1191 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1192 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
1193 kas_server_t kaserver
;
1196 * Validate input arguments and make rpc.
1200 tst
= ADMKASWHONULL
;
1201 goto fail_kas_PrincipalLockStatusGet
;
1204 if (lock_end_timeP
== NULL
) {
1205 tst
= ADMKASLOCKENDTIMEPNULL
;
1206 goto fail_kas_PrincipalLockStatusGet
;
1209 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
1210 goto fail_kas_PrincipalLockStatusGet
;
1213 rc
= GetPrincipalLockStatus(&kaserver
, who
, lock_end_timeP
, &tst
);
1215 fail_kas_PrincipalLockStatusGet
:
1224 * kas_PrincipalUnlock - unlock a principal.
1228 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1230 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1232 * IN who - the principal who is being unlocked.
1236 * No locks are held by this function.
1240 * Returns != 0 upon successful completion.
1244 * See the comments in GetPrincipalLockStatus regarding how the locking data
1245 * is kept INconsistently between servers.
1249 kas_PrincipalUnlock(const void *cellHandle
, const void *serverHandle
,
1250 const kas_identity_p who
, afs_status_p st
)
1253 afs_status_t tst
= 0;
1254 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1255 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
1256 kas_server_t kaserver
;
1258 afs_status_t save_tst
= 0;
1261 * Validate input arguments and make rpc.
1265 tst
= ADMKASWHONULL
;
1266 goto fail_kas_PrincipalUnlock
;
1269 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
1270 goto fail_kas_PrincipalUnlock
;
1275 ubik_CallIter(KAM_Unlock
, kaserver
.servers
, 0, &count
,
1276 (long)who
->principal
, (long)who
->instance
, 0, 0, 0,
1277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1278 if (tst
&& (tst
!= UNOSERVERS
)) {
1279 if (save_tst
== 0) {
1280 save_tst
= tst
; /* save the first failure */
1283 } while (tst
!= UNOSERVERS
);
1285 if ((tst
== 0) || (tst
== UNOSERVERS
)) {
1289 fail_kas_PrincipalUnlock
:
1298 getPrincipalFlags(const void *cellHandle
, const void *serverHandle
,
1299 const kas_identity_p who
, afs_int32
* cur_flags
,
1303 afs_status_t tst
= 0;
1304 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1305 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
1306 kas_server_t kaserver
;
1307 struct kaentryinfo tentry
;
1309 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
1310 goto fail_getPrincipalFlags
;
1314 ubik_KAM_GetEntry(kaserver
.servers
, 0, who
->principal
,
1315 who
->instance
, KAMAJORVERSION
, &tentry
);
1317 *cur_flags
= tentry
.flags
;
1321 fail_getPrincipalFlags
:
1330 * kas_PrincipalFieldsSet - modify an existing principal.
1334 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1336 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1338 * IN who - the principal who is being modified.
1340 * IN isAdmin - the admin status of the principal.
1342 * IN grantTickets - should the TGS issue tickets for the principal.
1344 * IN canEncrypt - should the TGS allow the use of encryption via the
1347 * IN canChangePassword - should the principal be allowed to change their
1350 * IN expirationDate - the date when the principal will expire.
1352 * IN maxTicketLifetime - the maximum lifetime of a ticket issued for
1355 * IN passwordExpires - the maximum number of days a particular
1356 * password can be used. The limit is 255, 0 => no expiration.
1358 * IN passwordReuse - can a password be reused by this principal.
1360 * IN failedPasswordAttempts - number of failed login attempts before
1361 * a principal is locked. The limit is 255, 0 => no limit.
1363 * IN failedPasswordLockTime - the number of seconds a principal is
1364 * locked once failedPasswordAttempts is reached. Some bizarre rounding
1365 * occurs for this value, see kas for more details.
1369 * No locks are held by this function.
1373 * Returns != 0 upon successful completion.
1377 * See the comments in GetPrincipalLockStatus regarding how the locking data
1378 * is kept INconsistently between servers.
1382 kas_PrincipalFieldsSet(const void *cellHandle
, const void *serverHandle
,
1383 const kas_identity_p who
, const kas_admin_p isAdmin
,
1384 const kas_tgs_p grantTickets
,
1385 const kas_enc_p canEncrypt
,
1386 const kas_cpw_p canChangePassword
,
1387 const unsigned int *expirationDate
,
1388 const unsigned int *maxTicketLifetime
,
1389 const unsigned int *passwordExpires
,
1390 const kas_rpw_p passwordReuse
,
1391 const unsigned int *failedPasswordAttempts
,
1392 const unsigned int *failedPasswordLockTime
,
1396 afs_status_t tst
= 0;
1397 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1398 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
1399 kas_server_t kaserver
;
1400 afs_int32 flags
= 0;
1401 Date expiration
= 0;
1402 afs_int32 lifetime
= 0;
1404 char spare_bytes
[4] = { 0, 0, 0, 0 };
1405 int somethings_changing
= 0;
1408 * Validate input arguments.
1412 tst
= ADMKASWHONULL
;
1413 goto fail_kas_PrincipalFieldsSet
;
1417 * set flags based upon input
1419 * If we're changing the flags, we need to get the current value of
1420 * the flags first and then make the changes
1423 if ((isAdmin
!= NULL
) || (grantTickets
!= NULL
) || (canEncrypt
!= NULL
)
1424 || (canChangePassword
!= NULL
)) {
1425 if (!getPrincipalFlags(cellHandle
, serverHandle
, who
, &flags
, &tst
)) {
1426 goto fail_kas_PrincipalFieldsSet
;
1430 if (isAdmin
!= NULL
) {
1431 somethings_changing
= 1;
1432 if (*isAdmin
== KAS_ADMIN
) {
1439 if (grantTickets
!= NULL
) {
1440 somethings_changing
= 1;
1441 if (*grantTickets
== NO_TGS
) {
1448 if (canEncrypt
!= NULL
) {
1449 somethings_changing
= 1;
1450 if (*canEncrypt
== NO_ENCRYPT
) {
1453 flags
&= ~KAFNOSEAL
;
1457 if (canChangePassword
!= NULL
) {
1458 somethings_changing
= 1;
1459 if (*canChangePassword
== NO_CHANGE_PASSWORD
) {
1466 flags
= (flags
& KAF_SETTABLE_FLAGS
) | KAFNORMAL
;
1468 if (expirationDate
!= NULL
) {
1469 somethings_changing
= 1;
1470 expiration
= *expirationDate
;
1473 if (maxTicketLifetime
!= NULL
) {
1474 somethings_changing
= 1;
1475 lifetime
= *maxTicketLifetime
;
1478 if (passwordExpires
!= NULL
) {
1479 if (*passwordExpires
> 255) {
1480 tst
= ADMKASPASSWORDEXPIRESTOOBIG
;
1481 goto fail_kas_PrincipalFieldsSet
;
1483 somethings_changing
= 1;
1484 spare_bytes
[0] = *passwordExpires
+ 1;
1487 if (passwordReuse
!= NULL
) {
1488 somethings_changing
= 1;
1489 if (*passwordReuse
== REUSE_PASSWORD
) {
1490 spare_bytes
[1] = KA_REUSEPW
;
1492 spare_bytes
[1] = KA_NOREUSEPW
;
1496 if (failedPasswordAttempts
!= NULL
) {
1497 if (*failedPasswordAttempts
> 255) {
1498 tst
= ADMKASFAILEDPASSWORDATTEMPTSTOOBIG
;
1499 goto fail_kas_PrincipalFieldsSet
;
1501 somethings_changing
= 1;
1502 spare_bytes
[2] = *failedPasswordAttempts
+ 1;
1505 if (failedPasswordLockTime
!= NULL
) {
1506 if (*failedPasswordLockTime
> 36 * 60 * 60) {
1507 tst
= ADMKASFAILEDPASSWORDLOCKTIME
;
1508 goto fail_kas_PrincipalFieldsSet
;
1510 somethings_changing
= 1;
1511 spare_bytes
[3] = ((*failedPasswordLockTime
+ 511) >> 9) + 1;
1514 was_spare
= pack_long(spare_bytes
);
1516 if (somethings_changing
) {
1517 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
1518 goto fail_kas_PrincipalFieldsSet
;
1521 ubik_KAM_SetFields(kaserver
.servers
, 0, who
->principal
,
1522 who
->instance
, flags
, expiration
, lifetime
, -1,
1528 tst
= ADMKASPRINCIPALFIELDSNOCHANGE
;
1531 fail_kas_PrincipalFieldsSet
:
1540 * kas_ServerStatsGet - get server statistics.
1544 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1546 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1548 * OUT stats - the statistics retrieved.
1552 * No locks are held by this function.
1556 * Returns != 0 upon successful completion.
1560 kas_ServerStatsGet(const void *cellHandle
, const void *serverHandle
,
1561 kas_serverStats_p stats
, afs_status_p st
)
1564 afs_status_t tst
= 0;
1565 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1566 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
1567 kas_server_t kaserver
;
1574 * Validate input arguments and make rpc.
1577 if (stats
== NULL
) {
1578 tst
= ADMKASSTATSNULL
;
1579 goto fail_kas_ServerStatsGet
;
1582 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
1583 goto fail_kas_ServerStatsGet
;
1587 ubik_KAM_GetStats(kaserver
.servers
, 0, KAMAJORVERSION
, &admins
,
1588 &statics
, &dynamics
);
1590 goto fail_kas_ServerStatsGet
;
1593 stats
->allocations
= statics
.allocs
;
1594 stats
->frees
= statics
.frees
;
1595 stats
->changePasswordRequests
= statics
.cpws
;
1596 stats
->adminAccounts
= admins
;
1597 stats
->host
= dynamics
.host
;
1598 stats
->serverStartTime
= dynamics
.start_time
;
1599 stats
->hashTableUtilization
= dynamics
.hashTableUtilization
;
1601 i
= sizeof(kas_serverProcStats_t
);
1602 memcpy(&stats
->authenticate
, &dynamics
.Authenticate
, i
);
1603 memcpy(&stats
->changePassword
, &dynamics
.ChangePassword
, i
);
1604 memcpy(&stats
->getTicket
, &dynamics
.GetTicket
, i
);
1605 memcpy(&stats
->createUser
, &dynamics
.CreateUser
, i
);
1606 memcpy(&stats
->setPassword
, &dynamics
.SetPassword
, i
);
1607 memcpy(&stats
->setFields
, &dynamics
.SetFields
, i
);
1608 memcpy(&stats
->deleteUser
, &dynamics
.DeleteUser
, i
);
1609 memcpy(&stats
->getEntry
, &dynamics
.GetEntry
, i
);
1610 memcpy(&stats
->listEntry
, &dynamics
.ListEntry
, i
);
1611 memcpy(&stats
->getStats
, &dynamics
.GetStats
, i
);
1612 memcpy(&stats
->getPassword
, &dynamics
.GetPassword
, i
);
1613 memcpy(&stats
->getRandomKey
, &dynamics
.GetRandomKey
, i
);
1614 memcpy(&stats
->debug
, &dynamics
.Debug
, i
);
1615 memcpy(&stats
->udpAuthenticate
, &dynamics
.UAuthenticate
, i
);
1616 memcpy(&stats
->udpGetTicket
, &dynamics
.UGetTicket
, i
);
1617 memcpy(&stats
->unlock
, &dynamics
.Unlock
, i
);
1618 memcpy(&stats
->lockStatus
, &dynamics
.LockStatus
, i
);
1620 stats
->stringChecks
= dynamics
.string_checks
;
1623 fail_kas_ServerStatsGet
:
1632 * kas_ServerDebugGet - get server debug info.
1636 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1638 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1640 * OUT stats - the debug info retrieved.
1644 * No locks are held by this function.
1648 * Returns != 0 upon successful completion.
1652 kas_ServerDebugGet(const void *cellHandle
, const void *serverHandle
,
1653 kas_serverDebugInfo_p debug
, afs_status_p st
)
1656 afs_status_t tst
= 0;
1657 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1658 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
1659 kas_server_t kaserver
;
1660 struct ka_debugInfo info
;
1664 * Validate input arguments and make rpc.
1667 if (debug
== NULL
) {
1668 tst
= ADMKASDEBUGNULL
;
1669 goto fail_kas_ServerDebugGet
;
1672 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
1673 goto fail_kas_ServerDebugGet
;
1675 tst
= ubik_KAM_Debug(kaserver
.servers
, 0, KAMAJORVERSION
, 0, &info
);
1677 goto fail_kas_ServerDebugGet
;
1679 debug
->host
= info
.host
;
1680 debug
->serverStartTime
= info
.startTime
;
1681 debug
->currentTime
= info
.reserved1
;
1682 debug
->noAuth
= info
.noAuth
;
1683 debug
->lastTransaction
= info
.lastTrans
;
1684 strcpy(debug
->lastOperation
, info
.lastOperation
);
1685 strcpy(debug
->lastPrincipalAuth
, info
.lastAuth
);
1686 strcpy(debug
->lastPrincipalUDPAuth
, info
.lastUAuth
);
1687 strcpy(debug
->lastPrincipalTGS
, info
.lastTGS
);
1688 strcpy(debug
->lastPrincipalUDPTGS
, info
.lastUTGS
);
1689 strcpy(debug
->lastPrincipalAdmin
, info
.lastAdmin
);
1690 strcpy(debug
->lastServerTGS
, info
.lastTGSServer
);
1691 strcpy(debug
->lastServerUDPTGS
, info
.lastUTGSServer
);
1692 debug
->nextAutoCheckPointWrite
= info
.nextAutoCPW
;
1693 debug
->updatesRemainingBeforeAutoCheckPointWrite
= info
.updatesRemaining
;
1694 debug
->dbHeaderRead
= info
.dbHeaderRead
;
1695 debug
->dbVersion
= info
.dbVersion
;
1696 debug
->dbFreePtr
= info
.dbFreePtr
;
1697 debug
->dbEOFPtr
= info
.dbEofPtr
;
1698 debug
->dbKvnoPtr
= info
.dbKvnoPtr
;
1699 debug
->dbSpecialKeysVersion
= info
.dbSpecialKeysVersion
;
1700 debug
->dbHeaderLock
= info
.cheader_lock
;
1701 debug
->keyCacheLock
= info
.keycache_lock
;
1702 debug
->keyCacheVersion
= info
.kcVersion
;
1703 debug
->keyCacheSize
= info
.kcSize
;
1704 debug
->keyCacheUsed
= info
.kcUsed
;
1705 for (i
= 0; i
< info
.kcUsed
; i
++) {
1706 debug
->keyCache
[i
].lastUsed
= info
.kcInfo
[i
].used
;
1707 debug
->keyCache
[i
].keyVersionNumber
= info
.kcInfo
[i
].kvno
;
1708 debug
->keyCache
[i
].primary
= info
.kcInfo
[i
].primary
;
1709 debug
->keyCache
[i
].keyCheckSum
= info
.kcInfo
[i
].keycksum
;
1710 strcpy(debug
->keyCache
[i
].principal
, info
.kcInfo
[i
].principal
);
1714 fail_kas_ServerDebugGet
:
1723 * kas_ServerRandomKeyGet - get a random key from a server.
1727 * IN cellHandle - a cellHandle previously returned by afsclient_CellOpen.
1729 * IN serverHandle - a serverHandle previously returned by kas_ServerOpen.
1731 * OUT key - a random key.
1735 * No locks are held by this function.
1739 * Returns != 0 upon successful completion.
1743 kas_ServerRandomKeyGet(const void *cellHandle
, const void *serverHandle
,
1744 kas_encryptionKey_p kas_keyp
, afs_status_p st
)
1747 afs_status_t tst
= 0;
1748 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1749 kas_server_p k_handle
= (kas_server_p
) serverHandle
;
1750 kas_server_t kaserver
;
1754 * Validate input arguments and make rpc.
1757 if (kas_keyp
== NULL
) {
1758 tst
= ADMKASKEYNULL
;
1759 goto fail_kas_ServerRandomKeyGet
;
1762 if (!ChooseValidServer(c_handle
, k_handle
, &kaserver
, &tst
)) {
1763 goto fail_kas_ServerRandomKeyGet
;
1766 tst
= ubik_KAM_GetRandomKey(kaserver
.servers
, 0, &key
);
1768 goto fail_kas_ServerRandomKeyGet
;
1770 memcpy(kas_keyp
, &key
, sizeof(*kas_keyp
));
1773 fail_kas_ServerRandomKeyGet
:
1782 * kas_StringToKey - turn a string key into a key.
1786 * IN cellName - the name of the cell where the key will be used.
1788 * IN string - the string to be converted.
1790 * OUT key - the encryption key.
1794 * No locks are held by this function.
1798 * Returns != 0 upon successful completion.
1802 kas_StringToKey(const char *cellName
, const char *string
,
1803 kas_encryptionKey_p key
, afs_status_p st
)
1806 afs_status_t tst
= 0;
1808 ka_StringToKey((char *)string
, (char *)cellName
, (struct ktc_encryptionKey
*)key
);
1819 * kas_KeyCheckSum - compute the checksum of an encryption key.
1823 * IN key - the encryption key.
1825 * OUT cksumP - key checksum
1829 * No locks are held by this function.
1833 * Returns != 0 upon successful completion.
1837 kas_KeyCheckSum(const kas_encryptionKey_p key
, unsigned int *cksumP
,
1841 afs_status_t tst
= 0;
1844 if ((tst
= ka_KeyCheckSum((char *)key
, &cksum32
)) == 0) {