Bug Summary

File:kauth/kaprocs.c
Location:line 1639, column 5
Description:Value stored to 'code' is never read

Annotated Source Code

1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
10#include <afsconfig.h>
11#include <afs/param.h>
12#include <afs/stds.h>
13
14#include <roken.h>
15
16#ifdef HAVE_SYS_RESOURCE_H1
17# include <sys/resource.h>
18#endif
19
20#ifdef IGNORE_SOME_GCC_WARNINGS
21# pragma GCC diagnostic warning "-Wdeprecated-declarations"
22#endif
23
24#include "kauth.h"
25
26#define HC_DEPRECATED
27#include <hcrypto/des.h>
28
29#include <lock.h>
30#include <ubik.h>
31#include <lwp.h>
32#include <rx/xdr.h>
33#include <rx/rx.h>
34#include <rx/rxkad.h>
35#include <afs/cellconfig.h>
36#include <afs/auth.h>
37#include <afs/com_err.h>
38#include <afs/afsutil.h>
39#include <afs/audit.h>
40
41#include "kautils.h"
42#include "kaserver.h"
43#include "kalog.h"
44#include "kaport.h"
45#include "kauth_internal.h"
46
47#include "kadatabase.h"
48#include "kaprocs.h"
49
50extern struct ubik_dbase *KA_dbase;
51struct kaheader cheader;
52Dateafs_uint32 cheaderReadTime; /* time cheader last read in */
53extern struct afsconf_dir *KA_conf; /* for getting cell info */
54
55
56
57char lrealm[MAXKTCREALMLEN64];
58
59#ifndef EXPIREPW /* password expiration default yes */
60#define EXPIREPW
61#endif
62
63#ifndef AUTOCPWINTERVAL(24*3600)
64#define AUTOCPWINTERVAL(24*3600) (24*3600)
65#endif
66#ifndef AUTOCPWUPDATES128
67#define AUTOCPWUPDATES128 128
68#endif
69
70extern int npwSums;
71
72static afs_int32 autoCPWInterval;
73static afs_int32 autoCPWUpdates;
74
75static afs_int32 set_password(struct ubik_trans *tt, char *name,
76 char *instance,
77 struct ktc_encryptionKey *password,
78 afs_int32 kvno, afs_int32 caller);
79static afs_int32 impose_reuse_limits(EncryptionKey *password,
80 struct kaentry *tentry);
81static int create_user(struct ubik_trans *tt, char *name, char *instance,
82 struct ktc_encryptionKey *key, afs_int32 caller,
83 afs_int32 flags);
84
85/* This routine is called whenever an RPC interface needs the time. It uses
86 the current time to randomize a 128 bit value that is used to change the
87 AuthServer Admin and TGS keys automatically. */
88
89static Dateafs_uint32 nextAutoCPWTime = 0;
90static afs_int32 totalUpdates = 0;
91
92/* This routine is ostensibly to get the current time, but basically its job is
93 to periodically update a random number. It also periodically updates the
94 keys for the builtin servers. This is why it needs a transaction pointer
95 and returns an error code. If the caller is in a read transaction, the tt
96 ptr should be zero and the return code need not be checked. */
97
98static afs_int32
99get_time(Dateafs_uint32 *timeP,
100 struct ubik_trans *tt, /* tt != 0: a write transaction */
101 int admin) /* the caller is an admin user */
102{
103 /* random value used to change Admin & TGS keys, this is at risk during
104 * multi-threaded operation, but I think the consequences are fairly
105 * harmless. */
106 static afs_uint32 random_value[4];
107
108 struct timeval time;
109 unsigned int bit, nbit;
110 int i;
111 afs_int32 to;
112
113 gettimeofday(&time, NULL((void *)0));
114 bit = (random_value[3] >> 31) & 1; /* get high bit of high word */
115 for (i = 0; i < 4; i++) {
116 nbit = random_value[i] >> 31;
117 random_value[i] = (random_value[i] << 1) + bit;
118 bit = nbit & 1;
119 }
120 /* get 60ths from usec. This is all the real randomness there is. */
121 random_value[0] += time.tv_usec / 16667;
122
123 if (nextAutoCPWTime == 0) { /* initialize things */
124 nextAutoCPWTime = time.tv_sec + autoCPWInterval;
125 memcpy(&random_value[0], &time, 8);
126 memcpy(&random_value[2], &time, 8);
127 }
128
129 if ((++totalUpdates >= autoCPWUpdates) && tt && /* a write transaction */
130 ((admin && (time.tv_sec >= nextAutoCPWTime))
131 || (time.tv_sec >= nextAutoCPWTime + autoCPWInterval))) {
132 struct ktc_encryptionKey key;
133 char buf[4 * sizeof(key) + 1];
134 struct kaentry tentry;
135 afs_int32 code;
136 char bob[KA_TIMESTR_LEN30];
137
138 ka_timestr(time.tv_sec, bob, KA_TIMESTR_LEN30);
139 es_Report("Auto CPW at %s\n", bob);
140 if (!admin)
141 es_Report(" ... even though no ADMIN user\n");
142
143 code = FindBlock(tt, KA_ADMIN_NAME"AuthServer", KA_ADMIN_INST"Admin", &to, &tentry);
144 if (code)
145 return code;
146 if (to) { /* check if auto cpw is disabled */
147 if (!(ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFNOCPW0x040)) {
148 memcpy(&key, &random_value[0], sizeof(key));
149 DES_set_odd_parityhc_DES_set_odd_parity(ktc_to_cblock(&key));
150 code =
151 set_password(tt, KA_ADMIN_NAME"AuthServer", KA_ADMIN_INST"Admin", &key, 0,
152 0);
153 if (code == 0) {
154 DES_init_random_number_generatorhc_DES_init_random_number_generator(ktc_to_cblock(&key));
155 ka_ConvertBytes(buf, sizeof(buf), (char *)&key,
156 sizeof(key));
157 es_Report("New Admin key is %s\n", buf);
158 } else {
159 es_Report
160 ("in get_time: set_password failed because: %d\n",
161 code);
162 return code;
163 }
164 }
165 }
166
167 code = FindBlock(tt, KA_TGS_NAME"krbtgt", lrealm, &to, &tentry);
168 if (code)
169 return code;
170 if (to) { /* check if auto cpw is disabled */
171 if (!(ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFNOCPW0x040)) {
172 memcpy(&key, &random_value[2], sizeof(key));
173 DES_set_odd_parityhc_DES_set_odd_parity(ktc_to_cblock(&key));
174 code = set_password(tt, KA_TGS_NAME"krbtgt", lrealm, &key, 0, 0);
175 if (code == 0) {
176 ka_ConvertBytes(buf, sizeof(buf), (char *)&key,
177 sizeof(key));
178 es_Report("New TGS key is %s\n", buf);
179 } else {
180 es_Report
181 ("in get_time: set_password failed because: %s\n",
182 afs_error_message(code));
183 return code;
184 }
185 }
186 }
187 code = ka_FillKeyCache(tt); /* ensure in-core copy is uptodate */
188 if (code)
189 return code;
190
191 nextAutoCPWTime = time.tv_sec + autoCPWInterval;
192 totalUpdates = 0;
193 }
194 if (timeP)
195 *timeP = time.tv_sec;
196 return 0;
197}
198
199static int noAuthenticationRequired; /* global state */
200static int recheckNoAuth; /* global state */
201
202/* kaprocsInited is sort of a lock: during a transaction only one process runs
203 while kaprocsInited is false. */
204
205static int kaprocsInited = 0;
206
207/* This variable is protected by the kaprocsInited flag. */
208
209static int (*rebuildDatabase) (struct ubik_trans *);
210
211/* This is called to initialize the database */
212
213static int
214initialize_database(struct ubik_trans *tt)
215{
216 struct ktc_encryptionKey key;
217 int code;
218
219 gettimeofday((struct timeval *)&key, NULL((void *)0)); /* this is just a cheap seed key */
220 DES_set_odd_parityhc_DES_set_odd_parity(ktc_to_cblock(&key));
221 DES_init_random_number_generatorhc_DES_init_random_number_generator(ktc_to_cblock(&key));
222 if ((code = DES_new_random_keyhc_DES_new_random_key(ktc_to_cblock(&key)))
223 || (code =
224 create_user(tt, KA_ADMIN_NAME"AuthServer", KA_ADMIN_INST"Admin", &key, 0,
225 KAFNORMAL0x001 | KAFNOSEAL0x020 | KAFNOTGS0x008)))
226 return code;
227 if ((code = DES_new_random_keyhc_DES_new_random_key(ktc_to_cblock(&key)))
228 || (code =
229 create_user(tt, KA_TGS_NAME"krbtgt", lrealm, &key, 0,
230 KAFNORMAL0x001 | KAFNOSEAL0x020 | KAFNOTGS0x008)))
231 return code;
232 return 0;
233}
234
235/* This routine handles initialization required by this module. The initFlags
236 parameter passes some information about the command line arguments. */
237
238afs_int32
239init_kaprocs(const char *lclpath, int initFlags)
240{
241 int code;
242 struct ubik_trans *tt;
243 struct ktc_encryptionKey key;
244 afs_int32 kvno;
245
246 kaprocsInited = 0;
247 if (myHost == 0)
248 return KAINTERNALERROR(180518L);
249 if (KA_conf == 0)
250 return KAINTERNALERROR(180518L);
251 code = afsconf_GetLocalCell(KA_conf, lrealm, sizeof(lrealm));
252 if (code) {
253 printf("** Can't determine local cell name!\n");
254 return KANOCELLS(180500L);
255 }
256 ucstring(lrealm, lrealm, sizeof(lrealm));
257
258 recheckNoAuth = 1;
259 if (initFlags & 1)
260 noAuthenticationRequired = 1;
261 if (initFlags & 2)
262 recheckNoAuth = 0;
263 if (recheckNoAuth)
264 noAuthenticationRequired = afsconf_GetNoAuthFlag(KA_conf);
265 if (noAuthenticationRequired)
266 printf("Running server with security disabled\n");
267
268 if (initFlags & 4) {
269 autoCPWInterval = 10;
270 autoCPWUpdates = 10;
271 } else {
272 autoCPWInterval = AUTOCPWINTERVAL(24*3600);
273 autoCPWUpdates = AUTOCPWUPDATES128;
274 }
275
276 init_kadatabase(initFlags);
277 rebuildDatabase = initialize_database;
278
279 if ((code = InitAuthServ(&tt, LOCKREAD1, 0))) {
280 printf("init_kaprocs: InitAuthServ failed: code = %d\n", code);
281 return code;
282 }
283 code = ka_LookupKey(tt, KA_ADMIN_NAME"AuthServer", KA_ADMIN_INST"Admin", &kvno, &key);
284 if (code) {
285 ubik_AbortTrans(tt);
286 printf
287 ("init_kaprocs: ka_LookupKey (code = %d) DB not initialized properly?\n",
288 code);
289 return code;
290 }
291 DES_init_random_number_generatorhc_DES_init_random_number_generator(ktc_to_cblock(&key));
292
293 code = ubik_EndTrans(tt);
294 if (code) {
295 printf("init_kaprocs: ubik_EndTrans failed: code = %d\n", code);
296 return code;
297 }
298
299 kaux_opendb((char *)lclpath);/* aux database stores failure counters */
300 rebuildDatabase = 0; /* only do this during init */
301 kaprocsInited = 1;
302 return 0;
303}
304
305/* These variable are for returning debugging info about the state of the
306 server. If they get trashed during multi-threaded operation it doesn't
307 matter. */
308
309/* this is global so COUNT_REQ in krb_udp.c can refer to it. */
310char *lastOperation = 0; /* name of last operation */
311static Dateafs_uint32 lastTrans; /* time of last transaction */
312
313static char adminPrincipal[256];
314static char authPrincipal[256];
315static char tgsPrincipal[256];
316static char tgsServerPrincipal[256];
317
318void
319save_principal(char *p, char *n, char *i, char *c)
320{
321 int s = 255;
322 int l;
323
324 l = strlen(n);
325 if (l > s)
326 return;
327 strcpy(p, n);
328 s -= l;
329 if (i && strlen(i)) {
330 if (s-- <= 0)
331 return;
332 strcat(p, ".");
333 l = strlen(i);
334 if (l > s)
335 return;
336 strcat(p, i);
337 s -= l;
338 }
339 if (c && strlen(c)) {
340 if (s-- <= 0)
341 return;
342 strcat(p, "@");
343 l = strlen(c);
344 if (l > s)
345 return;
346 strcat(p, c);
347 }
348}
349
350static afs_int32
351check_auth(struct rx_call *call,
352 struct ubik_trans *at,
353 int admin, /* require caller to be ADMIN */
354 afs_int32 *acaller_id)
355{
356 rxkad_level level;
357 char name[MAXKTCNAMELEN64];
358 char instance[MAXKTCNAMELEN64];
359 char cell[MAXKTCREALMLEN64];
360 afs_int32 kvno;
361 Dateafs_uint32 expiration; /* checked by Security Module */
362 struct kaentry tentry;
363 int code;
364 int si;
365
366 *acaller_id = 0;
367
368 if (recheckNoAuth)
369 noAuthenticationRequired = afsconf_GetNoAuthFlag(KA_conf);
370
371 si = rx_SecurityClassOf(rx_ConnectionOf(call))((((call)->conn))->securityIndex);
372 if (si == RX_SCINDEX_VAB1) {
373 printf("No support for VAB security module yet.\n");
374 return -1;
375 } else if (si == RX_SCINDEX_NULL0) {
376 code = KANOAUTH(180488L);
377 goto no_auth;
378 } else if (si != RX_SCINDEX_KAD2) {
379 es_Report("Unknown security index %d\n", si);
380 return -1;
381 }
382
383 code =
384 rxkad_GetServerInfo(rx_ConnectionOf(call)((call)->conn), &level, &expiration, name,
385 instance, cell, &kvno);
386 if (code) {
387 goto no_auth;
388 }
389 if (level != rxkad_crypt2) {
390 es_Report("Incorrect security level = %d\n", level);
391 code = KANOAUTH(180488L);
392 goto no_auth;
393 }
394
395 if (!name_instance_legal(name, instance))
396 return KABADNAME(180486L);
397 if (strlen(cell)) {
398 ka_PrintUserID
399 ("Authorization rejected because we don't understand intercell stuff yet: ",
400 name, instance, "");
401 printf("@%s\n", cell);
402 return KANOAUTH(180488L);
403 }
404
405 code = FindBlock(at, name, instance, acaller_id, &tentry);
406 if (code)
407 return code;
408 if (*acaller_id == 0) {
409 ka_PrintUserID("User ", name, instance, " unknown.\n");
410 return KANOENT(180484L);
411 }
412 save_principal(adminPrincipal, name, instance, 0);
413
414 if (admin) {
415 if (!(ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFADMIN0x004)) {
416 if (noAuthenticationRequired) {
417 ka_PrintUserID("Authorization approved for ", name, instance,
418 " because there is no authentication required\n");
419 osi_auditU(call, UnAuthEvent"AFS_UnAth", code, AUD_STR1, name, AUD_STR1,
420 instance, AUD_STR1, cell, AUD_END0);
421 return 0;
422 }
423 ka_PrintUserID("User ", name, instance, " is not ADMIN.\n");
424 return KANOAUTH(180488L);
425 }
426 osi_auditU(call, UseOfPrivilegeEvent"AFS_UseOfPriv", code, AUD_STR1, name, AUD_STR1,
427 instance, AUD_STR1, cell, AUD_END0);
428 }
429 return 0;
430
431 no_auth:
432 if (noAuthenticationRequired) {
433 es_Report
434 ("Caller w/o authorization approved no authentication required\n");
435 osi_auditU(call, UnAuthEvent"AFS_UnAth", code, AUD_STR1, name, AUD_STR1, instance,
436 AUD_STR1, cell, AUD_END0);
437 return 0;
438 }
439 return code; /* no auth info */
440}
441
442afs_int32
443AwaitInitialization(void)
444{
445 afs_int32 start = 0;
446 while (!kaprocsInited) {
447 if (!start)
448 start = time(0);
449 else if (time(0) - start > 5)
450 return UNOQUORUM(5376L);
451 IOMGR_Sleep(1);
452 }
453 return 0;
454}
455
456/* This is called by every RPC interface to create a Ubik transaction and read
457 the database header into core */
458
459afs_int32
460InitAuthServ(struct ubik_trans **tt,
461 int lock, /* indicate read/write transaction */
462 int *this_op) /* opcode of RPC proc, for COUNT_ABO */
463{
464 int code;
465 afs_int32 start = 0; /* time started waiting for quorum */
466 float wait = 0.91; /* start waiting for 1 second */
467
468 /* Wait for server initialization to finish if not during init_kaprocs */
469 if (this_op)
470 if ((code = AwaitInitialization()))
471 return code;
472
473 for (code = UNOQUORUM(5376L); code == UNOQUORUM(5376L);) {
474 if (lock == LOCKREAD1)
475 code = ubik_BeginTransReadAny(KA_dbase, UBIK_READTRANS0, tt);
476 else
477 code = ubik_BeginTrans(KA_dbase, UBIK_WRITETRANS1, tt);
478 if (code == UNOQUORUM(5376L)) { /* no quorum elected */
479 if (!start)
480 start = time(0);
481 else {
482 int delay = time(0) - start;
483 if (this_op) { /* punt quickly, if RPC call */
484 if (delay > 5)
485 return code;
486 } else { /* more patient during init. */
487 if (delay > 500)
488 return code;
489 }
490 }
491 printf("Waiting for quorum election.\n");
492 if (wait < 15.0)
493 wait *= 1.1;
494 IOMGR_Sleep((int)wait);
495 }
496 }
497 if (code)
498 return code;
499 if ((code = ubik_SetLock(*tt, 1, 1, lock))) {
500 if (this_op)
501 COUNT_ABO(*this_op)++;
502 ubik_AbortTrans(*tt);
503 return code;
504 }
505 /* check that dbase is initialized and setup cheader */
506 if (lock == LOCKREAD1) {
507 /* init but don't fix because this is read only */
508 code = CheckInit(*tt, 0);
509 if (code) {
510 ubik_AbortTrans(*tt); /* abort, since probably I/O error */
511 /* we did the check under a ReadAny transaction, but now, after
512 * getting a write transaction (and thus some real guarantees
513 * about what databases are really out there), we will check again
514 * in CheckInit before nuking the database. Since this may now get
515 * a UNOQUORUM we'll just do this from the top.
516 */
517 if ((code = InitAuthServ(tt, LOCKWRITE2, this_op)))
518 return code;
519 if ((code = ubik_EndTrans(*tt)))
520 return code;
521
522 /* now open the read transaction that was originally requested. */
523 return InitAuthServ(tt, lock, this_op);
524 }
525 } else {
526 if ((code = CheckInit(*tt, rebuildDatabase))) {
527 if (this_op)
528 COUNT_ABO(*this_op)++;
529 ubik_AbortTrans(*tt);
530 return code;
531 }
532 }
533 lastTrans = time(0);
534 ka_FillKeyCache(*tt); /* ensure in-core copy is uptodate */
535 return 0;
536}
537
538/* returns true if name is specially known by AuthServer */
539
540static int
541special_name(char *name, char *instance)
542
543{
544 return ((!strcmp(name, KA_TGS_NAME"krbtgt") && !strcmp(instance, lrealm))
545 || (strcmp(name, KA_ADMIN_NAME"AuthServer") == 0));
546}
547
548static int
549create_user(struct ubik_trans *tt, char *name, char *instance,
550 struct ktc_encryptionKey *key, afs_int32 caller,
551 afs_int32 flags)
552{
553 int code;
554 afs_int32 to;
555 struct kaentry tentry;
556 afs_int32 maxLifetime;
557
558 code = FindBlock(tt, name, instance, &to, &tentry);
559 if (code)
560 return code;
561 if (to)
562 return KAEXIST(180481L); /* name already exists, we fail */
563
564 to = AllocBlock(tt, &tentry);
565 if (to == 0)
566 return KACREATEFAIL(180483L);
567
568 /* otherwise we have a block */
569 strncpy(tentry.userID.name, name, sizeof(tentry.userID.name));
570 strncpy(tentry.userID.instance, instance, sizeof(tentry.userID.instance));
571 tentry.flags = htonl(flags)(__builtin_constant_p(flags) ? ((((__uint32_t)(flags)) >>
24) | ((((__uint32_t)(flags)) & (0xff << 16)) >>
8) | ((((__uint32_t)(flags)) & (0xff << 8)) <<
8) | (((__uint32_t)(flags)) << 24)) : __bswap32_var(flags
))
;
572 if (special_name(name, instance)) { /* this overrides key & version */
573 tentry.flags = htonl(ntohl(tentry.flags) | KAFSPECIAL)(__builtin_constant_p((__builtin_constant_p(tentry.flags) ? (
(((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t)(
tentry.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tentry.flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.flags)) << 24)) : __bswap32_var(tentry.flags))
| 0x100) ? ((((__uint32_t)((__builtin_constant_p(tentry.flags
) ? ((((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t
)(tentry.flags)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(tentry.flags)) & (0xff << 8)) << 8
) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x100)) >> 24) | ((((__uint32_t)((__builtin_constant_p
(tentry.flags) ? ((((__uint32_t)(tentry.flags)) >> 24) |
((((__uint32_t)(tentry.flags)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.flags)) & (0xff << 8))
<< 8) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x100)) & (0xff << 16)) >> 8
) | ((((__uint32_t)((__builtin_constant_p(tentry.flags) ? (((
(__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t)(tentry
.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tentry.flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.flags)) << 24)) : __bswap32_var(tentry.flags))
| 0x100)) & (0xff << 8)) << 8) | (((__uint32_t
)((__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry
.flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags)) | 0x100
)) << 24)) : __bswap32_var((__builtin_constant_p(tentry
.flags) ? ((((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t
)(tentry.flags)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(tentry.flags)) & (0xff << 8)) << 8
) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x100))
;
574 tentry.key_version = htonl(-1)(__builtin_constant_p(-1) ? ((((__uint32_t)(-1)) >> 24)
| ((((__uint32_t)(-1)) & (0xff << 16)) >> 8)
| ((((__uint32_t)(-1)) & (0xff << 8)) << 8) |
(((__uint32_t)(-1)) << 24)) : __bswap32_var(-1))
; /* don't save this key */
575 if ((code = ka_NewKey(tt, to, &tentry, key)))
576 return code;
577 } else {
578 memcpy(&tentry.key, key, sizeof(tentry.key));
579 tentry.key_version = htonl(0)(__builtin_constant_p(0) ? ((((__uint32_t)(0)) >> 24) |
((((__uint32_t)(0)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(0)) & (0xff << 8)) << 8) | (((
__uint32_t)(0)) << 24)) : __bswap32_var(0))
;
580 }
581 tentry.user_expiration = htonl(NEVERDATE)(__builtin_constant_p(037777777777) ? ((((__uint32_t)(037777777777
)) >> 24) | ((((__uint32_t)(037777777777)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(037777777777)) & (0xff
<< 8)) << 8) | (((__uint32_t)(037777777777)) <<
24)) : __bswap32_var(037777777777))
;
582 code = get_time(&tentry.modification_time, tt, 1);
583 if (code)
584 return code;
585
586 /* time and addr of entry for guy changing this entry */
587 tentry.modification_time = htonl(tentry.modification_time)(__builtin_constant_p(tentry.modification_time) ? ((((__uint32_t
)(tentry.modification_time)) >> 24) | ((((__uint32_t)(tentry
.modification_time)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(tentry.modification_time)) & (0xff <<
8)) << 8) | (((__uint32_t)(tentry.modification_time)) <<
24)) : __bswap32_var(tentry.modification_time))
;
588 tentry.modification_id = htonl(caller)(__builtin_constant_p(caller) ? ((((__uint32_t)(caller)) >>
24) | ((((__uint32_t)(caller)) & (0xff << 16)) >>
8) | ((((__uint32_t)(caller)) & (0xff << 8)) <<
8) | (((__uint32_t)(caller)) << 24)) : __bswap32_var(caller
))
;
589 tentry.change_password_time = tentry.modification_time;
590
591 if (strcmp(name, KA_TGS_NAME"krbtgt") == 0)
592 maxLifetime = MAXKTCTICKETLIFETIME(30*24*3600);
593 else if (strcmp(name, KA_ADMIN_NAME"AuthServer") == 0)
594 maxLifetime = 10 * 3600;
595 else if (strcmp(name, AUTH_SUPERUSER"afs") == 0)
596 maxLifetime = 100 * 3600;
597 else
598 maxLifetime = 25 * 3600; /* regular users */
599 tentry.max_ticket_lifetime = htonl(maxLifetime)(__builtin_constant_p(maxLifetime) ? ((((__uint32_t)(maxLifetime
)) >> 24) | ((((__uint32_t)(maxLifetime)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(maxLifetime)) & (0xff
<< 8)) << 8) | (((__uint32_t)(maxLifetime)) <<
24)) : __bswap32_var(maxLifetime))
;
600
601 code = ThreadBlock(tt, to, &tentry);
602 return code;
603}
604
605/* Put actual stub routines here */
606
607afs_int32
608SKAM_CreateUser(struct rx_call *call, char *aname, char *ainstance,
609 EncryptionKey ainitpw)
610{
611 afs_int32 code;
612
613 code = kamCreateUser(call, aname, ainstance, ainitpw);
614 osi_auditU(call, AFS_KAM_CrUserEvent"AFS_KAM_CrUser", code, AUD_STR1, aname, AUD_STR1,
615 ainstance, AUD_END0);
616 return code;
617}
618
619
620afs_int32
621kamCreateUser(struct rx_call *call, char *aname, char *ainstance,
622 EncryptionKey ainitpw)
623{
624 int code;
625 struct ubik_trans *tt;
626 afs_int32 caller; /* Disk offset of caller's entry */
627
628 COUNT_REQ(CreateUser)int *this_op = &dynamic_statistics.CreateUser.aborts; dynamic_statistics
.CreateUser.requests++; lastOperation = "CreateUser"
;
629 if (!DES_check_key_parityhc_DES_check_key_parity(EncryptionKey_to_cblock(&ainitpw)) ||
630 DES_is_weak_keyhc_DES_is_weak_key(EncryptionKey_to_cblock(&ainitpw)))
631 return KABADKEY(180496L);
632 if (!name_instance_legal(aname, ainstance))
633 return KABADNAME(180486L);
634 if ((code = InitAuthServ(&tt, LOCKWRITE2, this_op)))
635 return code;
636 code = check_auth(call, tt, 1, &caller);
637 if (code) {
638 COUNT_ABO(*this_op)++;
639 ubik_AbortTrans(tt);
640 return code;
641 }
642 code = create_user(tt, aname, ainstance, EncryptionKey_to_ktc(&ainitpw), caller, KAFNORMAL0x001);
643 if (code) {
644 COUNT_ABO(*this_op)++;
645 ubik_AbortTrans(tt);
646 return code;
647 }
648 code = ubik_EndTrans(tt);
649 KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,2)
650 LOG_CRUSER)kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,2)
;
651 return code;
652}
653
654afs_int32
655SKAA_ChangePassword(struct rx_call *call, char *aname, char *ainstance,
656 ka_CBS *arequest, ka_BBS *oanswer)
657{
658 afs_int32 code;
659
660 code = ChangePassWord(call, aname, ainstance, arequest, oanswer);
661 osi_auditU(call, AFS_KAA_ChPswdEvent"AFS_KAA_ChPswd", code, AUD_STR1, aname, AUD_STR1,
662 ainstance, AUD_END0);
663 return code;
664}
665
666afs_int32
667ChangePassWord(struct rx_call *call, char *aname, char *ainstance,
668 ka_CBS *arequest, ka_BBS *oanswer)
669{
670 int code;
671 struct ubik_trans *tt;
672 afs_int32 to; /* offset of block */
673 struct kaentry tentry;
674 struct ka_cpwRequest request; /* request after decryption */
675 char *answer; /* where answer is to be put */
676 int answer_len; /* length of answer packet */
677 afs_int32 kvno; /* requested key version number */
678 DES_key_schedule user_schedule; /* key schedule for user's key */
679 Dateafs_uint32 request_time; /* time request originated */
680
681 COUNT_REQ(ChangePassword)int *this_op = &dynamic_statistics.ChangePassword.aborts;
dynamic_statistics.ChangePassword.requests++; lastOperation =
"ChangePassword"
;
682 if (!name_instance_legal(aname, ainstance))
683 return KABADNAME(180486L);
684 if (strcmp(ainstance, KA_ADMIN_NAME"AuthServer") == 0)
685 return KABADNAME(180486L);
686 if ((code = InitAuthServ(&tt, LOCKWRITE2, this_op)))
687 return code;
688
689 code = FindBlock(tt, aname, ainstance, &to, &tentry);
690 if (code) {
691 goto abort;
692 }
693 if (to == 0) { /* no such user */
694 code = KANOENT(180484L);
695 goto abort;
696 }
697 if (ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFNOCPW0x040) {
698 code = KABADCPW(180509L);
699 goto abort;
700 }
701
702 /* decrypt request w/ user password */
703 if ((code = DES_key_schedhc_DES_key_sched(ktc_to_cblock(&tentry.key), &user_schedule)))
704 es_Report("In KAChangePassword: key_sched returned %d\n", code);
705 DES_pcbc_encrypthc_DES_pcbc_encrypt(arequest->SeqBody, &request,
706 min(arequest->SeqLen, sizeof(request))(((arequest->SeqLen) < (sizeof(request))) ? (arequest->
SeqLen) : (sizeof(request)))
, &user_schedule,
707 ktc_to_cblockptr(&tentry.key), DECRYPT0);
708
709 /* validate the request */
710 request_time = ntohl(request.time)(__builtin_constant_p(request.time) ? ((((__uint32_t)(request
.time)) >> 24) | ((((__uint32_t)(request.time)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(request.time
)) & (0xff << 8)) << 8) | (((__uint32_t)(request
.time)) << 24)) : __bswap32_var(request.time))
; /* reorder date */
711 kvno = ntohl(request.kvno)(__builtin_constant_p(request.kvno) ? ((((__uint32_t)(request
.kvno)) >> 24) | ((((__uint32_t)(request.kvno)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(request.kvno
)) & (0xff << 8)) << 8) | (((__uint32_t)(request
.kvno)) << 24)) : __bswap32_var(request.kvno))
;
712 if ((abs(request_time - time(0)) > KTC_TIME_UNCERTAINTY(15*60)) || strncmp(request.label, KA_CPW_REQ_LABEL"CPWl", sizeof(request.label)) || (request.spare) || (kvno > MAXKAKVNO127)) { /* these are reseved */
713 code = KABADREQUEST(180490L);
714 goto abort;
715 }
716
717 /* check to see if the new password was used before, or if there has
718 * not been sufficient time since the last password change
719 */
720 code = impose_reuse_limits(ktc_to_EncryptionKey(&request.newpw), &tentry);
721 if (code) {
722 goto abort;
723 }
724
725 /* Create the Answer Packet */
726 answer_len = sizeof(Dateafs_uint32) + KA_LABELSIZE4;
727 if (oanswer->MaxSeqLen < answer_len) {
728 code = KAANSWERTOOLONG(180489L);
729 goto abort;
730 }
731 oanswer->SeqLen = answer_len;
732 answer = oanswer->SeqBody;
733 request.time = htonl(request_time + 1)(__builtin_constant_p(request_time + 1) ? ((((__uint32_t)(request_time
+ 1)) >> 24) | ((((__uint32_t)(request_time + 1)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(request_time
+ 1)) & (0xff << 8)) << 8) | (((__uint32_t)(
request_time + 1)) << 24)) : __bswap32_var(request_time
+ 1))
;
734 memcpy(answer, (char *)&request.time, sizeof(Dateafs_uint32));
735 answer += sizeof(Dateafs_uint32);
736 memcpy(answer, KA_CPW_ANS_LABEL"Pass", KA_LABELSIZE4);
737
738 DES_pcbc_encrypthc_DES_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, answer_len,
739 &user_schedule, ktc_to_cblockptr(&tentry.key), ENCRYPT1);
740
741 code = set_password(tt, aname, ainstance, &request.newpw, kvno, 0);
742 if (code) {
743 code = KAIO(180482L);
744 goto abort;
745 }
746
747 cheader.stats.cpws = htonl(ntohl(cheader.stats.cpws) + 1)(__builtin_constant_p((__builtin_constant_p(cheader.stats.cpws
) ? ((((__uint32_t)(cheader.stats.cpws)) >> 24) | ((((__uint32_t
)(cheader.stats.cpws)) & (0xff << 16)) >> 8) |
((((__uint32_t)(cheader.stats.cpws)) & (0xff << 8)
) << 8) | (((__uint32_t)(cheader.stats.cpws)) << 24
)) : __bswap32_var(cheader.stats.cpws)) + 1) ? ((((__uint32_t
)((__builtin_constant_p(cheader.stats.cpws) ? ((((__uint32_t)
(cheader.stats.cpws)) >> 24) | ((((__uint32_t)(cheader.
stats.cpws)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(cheader.stats.cpws)) & (0xff << 8)) << 8) |
(((__uint32_t)(cheader.stats.cpws)) << 24)) : __bswap32_var
(cheader.stats.cpws)) + 1)) >> 24) | ((((__uint32_t)((__builtin_constant_p
(cheader.stats.cpws) ? ((((__uint32_t)(cheader.stats.cpws)) >>
24) | ((((__uint32_t)(cheader.stats.cpws)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(cheader.stats.cpws)) &
(0xff << 8)) << 8) | (((__uint32_t)(cheader.stats
.cpws)) << 24)) : __bswap32_var(cheader.stats.cpws)) + 1
)) & (0xff << 16)) >> 8) | ((((__uint32_t)((__builtin_constant_p
(cheader.stats.cpws) ? ((((__uint32_t)(cheader.stats.cpws)) >>
24) | ((((__uint32_t)(cheader.stats.cpws)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(cheader.stats.cpws)) &
(0xff << 8)) << 8) | (((__uint32_t)(cheader.stats
.cpws)) << 24)) : __bswap32_var(cheader.stats.cpws)) + 1
)) & (0xff << 8)) << 8) | (((__uint32_t)((__builtin_constant_p
(cheader.stats.cpws) ? ((((__uint32_t)(cheader.stats.cpws)) >>
24) | ((((__uint32_t)(cheader.stats.cpws)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(cheader.stats.cpws)) &
(0xff << 8)) << 8) | (((__uint32_t)(cheader.stats
.cpws)) << 24)) : __bswap32_var(cheader.stats.cpws)) + 1
)) << 24)) : __bswap32_var((__builtin_constant_p(cheader
.stats.cpws) ? ((((__uint32_t)(cheader.stats.cpws)) >> 24
) | ((((__uint32_t)(cheader.stats.cpws)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(cheader.stats.cpws)) &
(0xff << 8)) << 8) | (((__uint32_t)(cheader.stats
.cpws)) << 24)) : __bswap32_var(cheader.stats.cpws)) + 1
))
;
748 code =
749 kawrite(tt, DOFFSET(0, &cheader, &cheader.stats.cpws)((0)+(((char *)(&cheader.stats.cpws)) - ((char *)(&cheader
))))
,
750 (char *)&cheader.stats.cpws, sizeof(afs_int32));
751 if (code) {
752 code = KAIO(180482L);
753 goto abort;
754 }
755
756 code = ubik_EndTrans(tt);
757 return code;
758
759 abort:
760 COUNT_ABO(*this_op)++;
761 ubik_AbortTrans(tt);
762 return code;
763}
764
765static afs_int32
766impose_reuse_limits(EncryptionKey *password, struct kaentry *tentry)
767{
768 int code;
769 Dateafs_uint32 now;
770 int i;
771 extern int MinHours;
772 afs_uint32 newsum;
773
774 if (!tentry->pwsums[0] && npwSums > 1 && !tentry->pwsums[1])
775 return 0; /* password reuse limits not in effect */
776
777 code = get_time(&now, 0, 0);
778 if (code)
779 return code;
780
781 if ((now - ntohl(tentry->change_password_time)(__builtin_constant_p(tentry->change_password_time) ? ((((
__uint32_t)(tentry->change_password_time)) >> 24) | (
(((__uint32_t)(tentry->change_password_time)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(tentry->change_password_time
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
->change_password_time)) << 24)) : __bswap32_var(tentry
->change_password_time))
) < MinHours * 60 * 60)
782 return KATOOSOON(180521L);
783
784 if (!memcmp(password, &(tentry->key), sizeof(EncryptionKey)))
785 return KAREUSED(180520L);
786
787 code = ka_KeyCheckSum((char *)password, &newsum);
788 if (code)
789 return code;
790
791 newsum = newsum & 0x000000ff;
792 for (i = 0; i < npwSums; i++) {
793 if (newsum == tentry->pwsums[i])
794 return KAREUSED(180520L);
795 }
796
797 return 0;
798}
799
800
801static afs_int32
802set_password(struct ubik_trans *tt, char *name, char *instance,
803 struct ktc_encryptionKey *password, afs_int32 kvno, afs_int32 caller)
804{
805 afs_int32 code;
806 afs_int32 to; /* offset of block */
807 struct kaentry tentry;
808 Dateafs_uint32 now;
809 int i;
810 extern int npwSums;
811 afs_uint32 newsum;
812
813 code = FindBlock(tt, name, instance, &to, &tentry);
814 if (code)
815 return code;
816 if (to == 0)
817 return KANOENT(180484L); /* no such user */
818
819 /* if password reuse limits in effect, set the checksums, the hard way */
820 if (!tentry.pwsums[0] && npwSums > 1 && !tentry.pwsums[1]) {
821 /* do nothing, no limits */ ;
822 } else {
823 code = ka_KeyCheckSum((char *)&(tentry.key), &newsum);
824 if (code)
825 return code;
826 for (i = npwSums - 1; i; i--)
827 tentry.pwsums[i] = tentry.pwsums[i - 1];
828 tentry.pwsums[0] = newsum & 0x000000ff;
829 }
830
831
832 if (special_name(name, instance)) { /* set key over rides key_version */
833 tentry.flags = htonl(ntohl(tentry.flags) | KAFSPECIAL)(__builtin_constant_p((__builtin_constant_p(tentry.flags) ? (
(((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t)(
tentry.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tentry.flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.flags)) << 24)) : __bswap32_var(tentry.flags))
| 0x100) ? ((((__uint32_t)((__builtin_constant_p(tentry.flags
) ? ((((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t
)(tentry.flags)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(tentry.flags)) & (0xff << 8)) << 8
) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x100)) >> 24) | ((((__uint32_t)((__builtin_constant_p
(tentry.flags) ? ((((__uint32_t)(tentry.flags)) >> 24) |
((((__uint32_t)(tentry.flags)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.flags)) & (0xff << 8))
<< 8) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x100)) & (0xff << 16)) >> 8
) | ((((__uint32_t)((__builtin_constant_p(tentry.flags) ? (((
(__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t)(tentry
.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tentry.flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.flags)) << 24)) : __bswap32_var(tentry.flags))
| 0x100)) & (0xff << 8)) << 8) | (((__uint32_t
)((__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry
.flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags)) | 0x100
)) << 24)) : __bswap32_var((__builtin_constant_p(tentry
.flags) ? ((((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t
)(tentry.flags)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(tentry.flags)) & (0xff << 8)) << 8
) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x100))
;
834 if ((code = ka_NewKey(tt, to, &tentry, password)))
835 return (code);
836 } else {
837 memcpy(&tentry.key, password, sizeof(tentry.key));
838 if (!kvno) {
839 kvno = ntohl(tentry.key_version)(__builtin_constant_p(tentry.key_version) ? ((((__uint32_t)(tentry
.key_version)) >> 24) | ((((__uint32_t)(tentry.key_version
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(tentry
.key_version)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.key_version)) << 24)) : __bswap32_var(tentry.key_version
))
;
840 if ((kvno < 1) || (kvno >= MAXKAKVNO127))
841 kvno = 1;
842 else
843 kvno++;
844 }
845 tentry.key_version = htonl((afs_int32) kvno)(__builtin_constant_p((afs_int32) kvno) ? ((((__uint32_t)((afs_int32
) kvno)) >> 24) | ((((__uint32_t)((afs_int32) kvno)) &
(0xff << 16)) >> 8) | ((((__uint32_t)((afs_int32
) kvno)) & (0xff << 8)) << 8) | (((__uint32_t
)((afs_int32) kvno)) << 24)) : __bswap32_var((afs_int32
) kvno))
; /* requested key version */
846 }
847
848
849
850 /* no-write prevents recursive call to set_password by AuthCPW code. */
851 code = get_time(&now, 0, 0);
852 if (code)
853 return code;
854 if (caller) {
855 tentry.modification_time = htonl(now)(__builtin_constant_p(now) ? ((((__uint32_t)(now)) >> 24
) | ((((__uint32_t)(now)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(now)) & (0xff << 8)) << 8
) | (((__uint32_t)(now)) << 24)) : __bswap32_var(now))
;
856 tentry.modification_id = htonl(caller)(__builtin_constant_p(caller) ? ((((__uint32_t)(caller)) >>
24) | ((((__uint32_t)(caller)) & (0xff << 16)) >>
8) | ((((__uint32_t)(caller)) & (0xff << 8)) <<
8) | (((__uint32_t)(caller)) << 24)) : __bswap32_var(caller
))
;
857 }
858
859 tentry.change_password_time = htonl(now)(__builtin_constant_p(now) ? ((((__uint32_t)(now)) >> 24
) | ((((__uint32_t)(now)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(now)) & (0xff << 8)) << 8
) | (((__uint32_t)(now)) << 24)) : __bswap32_var(now))
;
860
861 if ((code = kawrite(tt, to, (char *) &tentry, sizeof(tentry))))
862 return (KAIO(180482L));
863 return (0);
864}
865
866afs_int32
867SKAM_SetPassword(struct rx_call *call, char *aname, char *ainstance,
868 afs_int32 akvno, EncryptionKey apassword)
869{
870 afs_int32 code;
871
872 code = kamSetPassword(call, aname, ainstance, akvno, apassword);
873 osi_auditU(call, AFS_KAM_SetPswdEvent"AFS_KAM_SetPswd", code, AUD_STR1, aname, AUD_STR1,
874 ainstance, AUD_END0);
875 return code;
876}
877
878afs_int32
879kamSetPassword(struct rx_call *call, char *aname, char *ainstance,
880 afs_int32 akvno, EncryptionKey apassword)
881{
882 int code;
883 struct ubik_trans *tt;
884 afs_int32 caller; /* Disk offset of caller's entry */
885 struct kaentry tentry;
886
887 COUNT_REQ(SetPassword)int *this_op = &dynamic_statistics.SetPassword.aborts; dynamic_statistics
.SetPassword.requests++; lastOperation = "SetPassword"
;
888 if (akvno > MAXKAKVNO127)
889 return KABADARGUMENT(180492L);
890 if (!DES_check_key_parityhc_DES_check_key_parity(EncryptionKey_to_cblock(&apassword)) ||
891 DES_is_weak_keyhc_DES_is_weak_key(EncryptionKey_to_cblock(&apassword)))
892 return KABADKEY(180496L);
893
894 if (!name_instance_legal(aname, ainstance))
895 return KABADNAME(180486L);
896 if ((code = InitAuthServ(&tt, LOCKWRITE2, this_op)))
897 return code;
898 code = check_auth(call, tt, 0, &caller);
899 if (code) {
900 goto abort;
901 }
902 if ((code = karead(tt, caller, (char *)&tentry, sizeof(tentry)))) {
903 code = KAIO(180482L);
904 goto abort;
905 }
906 /* if the user is changing his own password or ADMIN then go ahead. */
907 if ((strcmp(tentry.userID.name, aname) == 0)
908 && (strcmp(tentry.userID.instance, ainstance) == 0)) {
909 if (ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFNOCPW0x040)
910 code = KABADCPW(180509L);
911 else {
912 code = impose_reuse_limits(&apassword, &tentry);
913 if (!code)
914 code =
915 set_password(tt, aname, ainstance, EncryptionKey_to_ktc(&apassword), akvno, 0);
916 }
917 } else if (ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFADMIN0x004) {
918 code = set_password(tt, aname, ainstance, EncryptionKey_to_ktc(&apassword), akvno, caller);
919 } else
920 code = KANOAUTH(180488L);
921 if (code)
922 goto abort;
923
924 code = ubik_EndTrans(tt);
925 KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,1)
926 LOG_CHPASSWD)kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,1)
;
927 return code;
928
929 abort:
930 COUNT_ABO(*this_op)++;
931 ubik_AbortTrans(tt);
932 return code;
933}
934
935static Dateafs_uint32
936CoerseLifetime(Dateafs_uint32 start, Dateafs_uint32 end)
937{
938 unsigned char kerberosV4Life;
939 kerberosV4Life = time_to_life(start, end);
940 end = life_to_time(start, kerberosV4Life);
941 return end;
942}
943
944static afs_int32
945GetEndTime(Dateafs_uint32 start, /* start time of ticket */
946 Dateafs_uint32 reqEnd, /* requested end time */
947 Dateafs_uint32 expiration, /* authorizing ticket's expiration */
948 struct kaentry *caller,
949 struct kaentry *server,
950 Dateafs_uint32 *endP) /* actual end time */
951{
952 Dateafs_uint32 cExp, sExp;
953 Dateafs_uint32 cLife, sLife;
954 Dateafs_uint32 end;
955
956 if (ntohl(caller->flags)(__builtin_constant_p(caller->flags) ? ((((__uint32_t)(caller
->flags)) >> 24) | ((((__uint32_t)(caller->flags)
) & (0xff << 16)) >> 8) | ((((__uint32_t)(caller
->flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(caller->flags)) << 24)) : __bswap32_var(caller->
flags))
& KAFNOTGS0x008)
957 return KABADUSER(180508L); /* no new tickets for this user */
958 if (expiration && (ntohl(server->flags)(__builtin_constant_p(server->flags) ? ((((__uint32_t)(server
->flags)) >> 24) | ((((__uint32_t)(server->flags)
) & (0xff << 16)) >> 8) | ((((__uint32_t)(server
->flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(server->flags)) << 24)) : __bswap32_var(server->
flags))
& KAFNOSEAL0x020))
959 return KABADSERVER(180507L); /* can't be target of GetTicket req */
960 if (!expiration)
961 expiration = NEVERDATE037777777777;
962
963 cExp = ntohl(caller->user_expiration)(__builtin_constant_p(caller->user_expiration) ? ((((__uint32_t
)(caller->user_expiration)) >> 24) | ((((__uint32_t)
(caller->user_expiration)) & (0xff << 16)) >>
8) | ((((__uint32_t)(caller->user_expiration)) & (0xff
<< 8)) << 8) | (((__uint32_t)(caller->user_expiration
)) << 24)) : __bswap32_var(caller->user_expiration))
;
964 sExp = ntohl(server->user_expiration)(__builtin_constant_p(server->user_expiration) ? ((((__uint32_t
)(server->user_expiration)) >> 24) | ((((__uint32_t)
(server->user_expiration)) & (0xff << 16)) >>
8) | ((((__uint32_t)(server->user_expiration)) & (0xff
<< 8)) << 8) | (((__uint32_t)(server->user_expiration
)) << 24)) : __bswap32_var(server->user_expiration))
;
965 if (cExp < start)
966 return KAPWEXPIRED(180519L);
967 if (sExp < start)
968 return KABADSERVER(180507L);
969 cLife = start + ntohl(caller->max_ticket_lifetime)(__builtin_constant_p(caller->max_ticket_lifetime) ? ((((__uint32_t
)(caller->max_ticket_lifetime)) >> 24) | ((((__uint32_t
)(caller->max_ticket_lifetime)) & (0xff << 16)) >>
8) | ((((__uint32_t)(caller->max_ticket_lifetime)) & (
0xff << 8)) << 8) | (((__uint32_t)(caller->max_ticket_lifetime
)) << 24)) : __bswap32_var(caller->max_ticket_lifetime
))
;
970 sLife = start + ntohl(server->max_ticket_lifetime)(__builtin_constant_p(server->max_ticket_lifetime) ? ((((__uint32_t
)(server->max_ticket_lifetime)) >> 24) | ((((__uint32_t
)(server->max_ticket_lifetime)) & (0xff << 16)) >>
8) | ((((__uint32_t)(server->max_ticket_lifetime)) & (
0xff << 8)) << 8) | (((__uint32_t)(server->max_ticket_lifetime
)) << 24)) : __bswap32_var(server->max_ticket_lifetime
))
;
971 end =
972 umin(umin(reqEnd, expiration),
973 umin(umin(cLife, sLife), umin(cExp, sExp)));
974 end = CoerseLifetime(start, end);
975 *endP = end;
976 return 0;
977}
978
979static afs_int32
980PrepareTicketAnswer(ka_BBS *oanswer, afs_int32 challenge, char *ticket,
981 afs_int32 ticketLen, struct ktc_encryptionKey *sessionKey,
982 Dateafs_uint32 start, Dateafs_uint32 end, struct kaentry *caller,
983 struct kaentry *server, char *cell, char *label)
984{
985 afs_int32 code;
986 struct ka_ticketAnswer *answer;
987 afs_int32 cksum;
988
989 code = KAANSWERTOOLONG(180489L);
990 if (oanswer->MaxSeqLen <
991 sizeof(struct ka_ticketAnswer) - 5 * MAXKTCNAMELEN64 - MAXKTCTICKETLEN12000 +
992 ticketLen)
993 return code;
994
995 answer = (struct ka_ticketAnswer *)oanswer->SeqBody;
996 answer->challenge = htonl(challenge)(__builtin_constant_p(challenge) ? ((((__uint32_t)(challenge)
) >> 24) | ((((__uint32_t)(challenge)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(challenge)) & (0xff <<
8)) << 8) | (((__uint32_t)(challenge)) << 24)) :
__bswap32_var(challenge))
;
997 memcpy(&answer->sessionKey, sessionKey, sizeof(struct ktc_encryptionKey));
998 answer->startTime = htonl(start)(__builtin_constant_p(start) ? ((((__uint32_t)(start)) >>
24) | ((((__uint32_t)(start)) & (0xff << 16)) >>
8) | ((((__uint32_t)(start)) & (0xff << 8)) <<
8) | (((__uint32_t)(start)) << 24)) : __bswap32_var(start
))
;
999 answer->endTime = htonl(end)(__builtin_constant_p(end) ? ((((__uint32_t)(end)) >> 24
) | ((((__uint32_t)(end)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(end)) & (0xff << 8)) << 8
) | (((__uint32_t)(end)) << 24)) : __bswap32_var(end))
;
1000 answer->kvno = server->key_version;
1001 answer->ticketLen = htonl(ticketLen)(__builtin_constant_p(ticketLen) ? ((((__uint32_t)(ticketLen)
) >> 24) | ((((__uint32_t)(ticketLen)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(ticketLen)) & (0xff <<
8)) << 8) | (((__uint32_t)(ticketLen)) << 24)) :
__bswap32_var(ticketLen))
;
1002
1003 {
1004 char *ans = answer->name; /* pointer to variable part */
1005 int rem; /* space remaining */
1006 int len; /* macro temp. */
1007
1008 rem = oanswer->MaxSeqLen - (ans - oanswer->SeqBody);
1009#undef putstr
1010#define putstr(str)len = strlen (str)+1; if (rem < len) goto abort; strcpy (ans
, str); ans += len; rem -= len
len = strlen (str)+1;\
1011 if (rem < len) return code;\
1012 strcpy (ans, str);\
1013 ans += len; rem -= len
1014 putstr(caller->userID.name)len = strlen (caller->userID.name)+1; if (rem < len) goto
abort; strcpy (ans, caller->userID.name); ans += len; rem
-= len
;
1015 putstr(caller->userID.instance)len = strlen (caller->userID.instance)+1; if (rem < len
) goto abort; strcpy (ans, caller->userID.instance); ans +=
len; rem -= len
;
1016 putstr(cell)len = strlen (cell)+1; if (rem < len) goto abort; strcpy (
ans, cell); ans += len; rem -= len
;
1017 putstr(server->userID.name)len = strlen (server->userID.name)+1; if (rem < len) goto
abort; strcpy (ans, server->userID.name); ans += len; rem
-= len
;
1018 putstr(server->userID.instance)len = strlen (server->userID.instance)+1; if (rem < len
) goto abort; strcpy (ans, server->userID.instance); ans +=
len; rem -= len
;
1019 if (rem < ticketLen + KA_LABELSIZE4)
1020 return code;
1021 memcpy(ans, ticket, ticketLen);
1022 ans += ticketLen;
1023 if (label)
1024 memcpy(ans, label, KA_LABELSIZE4);
1025 else
1026 memset(ans, 0, KA_LABELSIZE4);
1027 ans += KA_LABELSIZE4;
1028 oanswer->SeqLen = (ans - oanswer->SeqBody);
1029 }
1030 cksum = 0;
1031 answer->cksum = htonl(cksum)(__builtin_constant_p(cksum) ? ((((__uint32_t)(cksum)) >>
24) | ((((__uint32_t)(cksum)) & (0xff << 16)) >>
8) | ((((__uint32_t)(cksum)) & (0xff << 8)) <<
8) | (((__uint32_t)(cksum)) << 24)) : __bswap32_var(cksum
))
;
1032 oanswer->SeqLen = round_up_to_ebs(oanswer->SeqLen)(((oanswer->SeqLen) + 7) & (~7));
1033 if (oanswer->SeqLen > oanswer->MaxSeqLen)
1034 return code;
1035 return 0;
1036}
1037
1038/* This is used to get a ticket granting ticket or an admininstration ticket.
1039 These two specific, built-in servers are special cases, which require the
1040 client's key as an additional security precaution. The GetTicket operation
1041 is normally disabled for these two principals. */
1042
1043static afs_int32
1044Authenticate(int version, struct rx_call *call, char *aname, char *ainstance,
1045 Dateafs_uint32 start, Dateafs_uint32 end, ka_CBS *arequest, ka_BBS *oanswer)
1046{
1047 int code;
1048 struct ubik_trans *tt;
1049 afs_int32 to; /* offset of block */
1050 kaentry tentry;
1051 struct kaentry server; /* entry for desired server */
1052 struct ka_gettgtRequest request; /* request after decryption */
1053 int tgt, adm; /* type of request */
1054 char *sname; /* principal of server */
1055 char *sinst;
1056 char ticket[MAXKTCTICKETLEN12000]; /* our copy of the ticket */
1057 int ticketLen;
1058 struct ktc_encryptionKey sessionKey; /* we have to invent a session key */
1059 char *answer; /* where answer is to be put */
1060 int answer_len; /* length of answer packet */
1061 Dateafs_uint32 answer_time; /* 1+ request time in network order */
1062 afs_int32 temp; /* for htonl conversions */
1063 DES_key_schedule user_schedule; /* key schedule for user's key */
1064 afs_int32 tgskvno; /* key version of service key */
1065 struct ktc_encryptionKey tgskey; /* service key for encrypting ticket */
1066 Dateafs_uint32 now;
1067 afs_uint32 pwexpires;
1068
1069 COUNT_REQ(Authenticate)int *this_op = &dynamic_statistics.Authenticate.aborts; dynamic_statistics
.Authenticate.requests++; lastOperation = "Authenticate"
;
1070 if (!name_instance_legal(aname, ainstance))
1071 return KABADNAME(180486L);
1072 if ((code = InitAuthServ(&tt, LOCKREAD1, this_op)))
1073 return code;
1074 get_time(&now, 0, 0);
1075
1076 sname = sinst = NULL((void *)0);
1077
1078 code = FindBlock(tt, aname, ainstance, &to, &tentry);
1079 if (code) {
1080 goto abort;
1081 }
1082 if (to == 0) { /* no such user */
1083 code = KANOENT(180484L);
1084 goto abort;
1085 }
1086#ifdef LOCKPW
1087 /* have to check for locked before verifying the password, otherwise all
1088 * KALOCKED means is "yup, you guessed the password all right, now wait a
1089 * few minutes and we'll let you in"
1090 */
1091 if (kaux_islocked
1092 (to, (u_int) tentry.misc_auth_bytes[ATTEMPTS2],
1093 (afs_uint32) tentry.misc_auth_bytes[LOCKTIME3] << 9)) {
1094 code = KALOCKED(180522L);
1095 goto abort;
1096 }
1097#endif /* LOCKPW */
1098
1099 save_principal(authPrincipal, aname, ainstance, 0);
1100
1101 /* decrypt request w/ user password */
1102 if ((code = DES_key_schedhc_DES_key_sched(ktc_to_cblock(&tentry.key), &user_schedule)))
1103 es_Report("In KAAuthenticate: key_sched returned %d\n", code);
1104 DES_pcbc_encrypthc_DES_pcbc_encrypt(arequest->SeqBody, &request,
1105 min(arequest->SeqLen, sizeof(request))(((arequest->SeqLen) < (sizeof(request))) ? (arequest->
SeqLen) : (sizeof(request)))
, &user_schedule,
1106 ktc_to_cblockptr(&tentry.key), DECRYPT0);
1107
1108 request.time = ntohl(request.time)(__builtin_constant_p(request.time) ? ((((__uint32_t)(request
.time)) >> 24) | ((((__uint32_t)(request.time)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(request.time
)) & (0xff << 8)) << 8) | (((__uint32_t)(request
.time)) << 24)) : __bswap32_var(request.time))
; /* reorder date */
1109 tgt = !strncmp(request.label, KA_GETTGT_REQ_LABEL"gTGS", sizeof(request.label));
1110 adm = !strncmp(request.label, KA_GETADM_REQ_LABEL"gADM", sizeof(request.label));
1111 if (!(tgt || adm)) {
1112 kaux_inc(to, ((unsigned char)tentry.misc_auth_bytes[LOCKTIME3]) << 9);
1113 code = KABADREQUEST(180490L);
1114 goto abort;
1115 } else
1116 kaux_write(to, 0, 0); /* reset counters */
1117
1118#ifdef EXPIREPW
1119 if (!tentry.misc_auth_bytes[EXPIRES0]) {
1120 /* 0 in the database means never, but 0 on the network means today */
1121 /* 255 on the network means "long time, maybe never" */
1122 pwexpires = 255;
1123 } else {
1124 pwexpires = tentry.misc_auth_bytes[EXPIRES0];
1125
1126 pwexpires =
1127 ntohl(tentry.change_password_time)(__builtin_constant_p(tentry.change_password_time) ? ((((__uint32_t
)(tentry.change_password_time)) >> 24) | ((((__uint32_t
)(tentry.change_password_time)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.change_password_time)) & (0xff
<< 8)) << 8) | (((__uint32_t)(tentry.change_password_time
)) << 24)) : __bswap32_var(tentry.change_password_time)
)
+ 24 * 60 * 60 * pwexpires;
1128 if (adm) { /* provide a little slack for admin ticket */
1129 pwexpires += 30 * 24 * 60 * 60; /* 30 days */
1130 }
1131 if (pwexpires < now) {
1132 code = KAPWEXPIRED(180519L);
1133 goto abort;
1134 } else {
1135 pwexpires = (pwexpires - now) / (24 * 60 * 60);
1136 if (pwexpires > 255)
1137 pwexpires = 255;
1138 }
1139 }
1140#endif /* EXPIREPW */
1141
1142 if (abs(request.time - now) > KTC_TIME_UNCERTAINTY(15*60)) {
1143#if 0
1144 if (oanswer->MaxSeqLen < sizeof(afs_int32))
1145 code = KAANSWERTOOLONG(180489L);
1146 else { /* return our time if possible */
1147 oanswer->SeqLen = sizeof(afs_int32);
1148 request.time = htonl(now)(__builtin_constant_p(now) ? ((((__uint32_t)(now)) >> 24
) | ((((__uint32_t)(now)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(now)) & (0xff << 8)) << 8
) | (((__uint32_t)(now)) << 24)) : __bswap32_var(now))
;
1149 memcpy(oanswer->SeqBody, &request.time, sizeof(afs_int32));
1150 }
1151#endif
1152 code = KACLOCKSKEW(180514L);
1153 goto abort;
1154 }
1155 sname = (tgt ? KA_TGS_NAME"krbtgt" : KA_ADMIN_NAME"AuthServer");
1156 sinst = (tgt ? lrealm : KA_ADMIN_INST"Admin");
1157 code = FindBlock(tt, sname, sinst, &to, &server);
1158 if (code)
1159 goto abort;
1160 if (to == 0) {
1161 code = KANOENT(180484L);
1162 goto abort;
1163 }
1164
1165 tgskvno = ntohl(server.key_version)(__builtin_constant_p(server.key_version) ? ((((__uint32_t)(server
.key_version)) >> 24) | ((((__uint32_t)(server.key_version
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(server
.key_version)) & (0xff << 8)) << 8) | (((__uint32_t
)(server.key_version)) << 24)) : __bswap32_var(server.key_version
))
;
1166 memcpy(&tgskey, &server.key, sizeof(tgskey));
1167
1168 code = DES_new_random_keyhc_DES_new_random_key(ktc_to_cblock(&sessionKey));
1169 if (code) {
1170 code = KANOKEYS(180494L);
1171 goto abort;
1172 }
1173
1174 code = GetEndTime(start, end, 0 /*!GetTicket */ , &tentry, &server, &end);
1175 if (code)
1176 goto abort;
1177
1178 code =
1179 tkt_MakeTicket(ticket, &ticketLen, &tgskey, aname, ainstance, "",
1180 start, end, &sessionKey,
1181 rx_HostOf(rx_PeerOf(rx_ConnectionOf(call)))((((((call)->conn))->peer))->host), sname,
1182 sinst);
1183 if (code)
1184 goto abort;
1185
1186 switch (version) {
1187 case 0:
1188 answer_len =
1189 ticketLen + sizeof(Dateafs_uint32) + sizeof(struct ktc_encryptionKey) +
1190 2 * sizeof(afs_int32) + KA_LABELSIZE4;
1191 answer_len = round_up_to_ebs(answer_len)(((answer_len) + 7) & (~7));
1192 if (answer_len > oanswer->MaxSeqLen) {
1193 code = KAANSWERTOOLONG(180489L);
1194 goto abort;
1195 }
1196 oanswer->SeqLen = answer_len;
1197 answer = oanswer->SeqBody;
1198 answer_time = htonl(request.time + 1)(__builtin_constant_p(request.time + 1) ? ((((__uint32_t)(request
.time + 1)) >> 24) | ((((__uint32_t)(request.time + 1))
& (0xff << 16)) >> 8) | ((((__uint32_t)(request
.time + 1)) & (0xff << 8)) << 8) | (((__uint32_t
)(request.time + 1)) << 24)) : __bswap32_var(request.time
+ 1))
;
1199 memcpy(answer, (char *)&answer_time, sizeof(Dateafs_uint32));
1200 answer += sizeof(Dateafs_uint32);
1201 memcpy(answer, (char *)&sessionKey, sizeof(struct ktc_encryptionKey));
1202 answer += sizeof(struct ktc_encryptionKey);
1203 temp = htonl(tgskvno)(__builtin_constant_p(tgskvno) ? ((((__uint32_t)(tgskvno)) >>
24) | ((((__uint32_t)(tgskvno)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tgskvno)) & (0xff << 8)) <<
8) | (((__uint32_t)(tgskvno)) << 24)) : __bswap32_var(
tgskvno))
;
1204 memcpy(answer, (char *)&temp, sizeof(afs_int32));
1205 answer += sizeof(afs_int32);
1206 temp = htonl(ticketLen)(__builtin_constant_p(ticketLen) ? ((((__uint32_t)(ticketLen)
) >> 24) | ((((__uint32_t)(ticketLen)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(ticketLen)) & (0xff <<
8)) << 8) | (((__uint32_t)(ticketLen)) << 24)) :
__bswap32_var(ticketLen))
;
1207 memcpy(answer, (char *)&temp, sizeof(afs_int32));
1208 answer += sizeof(afs_int32);
1209 memcpy(answer, ticket, ticketLen);
1210 answer += ticketLen;
1211 memcpy(answer, (tgt ? KA_GETTGT_ANS_LABEL"tgsT" : KA_GETADM_ANS_LABEL"admT"),
1212 KA_LABELSIZE4);
1213 break;
1214 case 1:
1215 case 2:
1216 code =
1217 PrepareTicketAnswer(oanswer, request.time + 1, ticket, ticketLen,
1218 &sessionKey, start, end, &tentry, &server, "",
1219 (tgt ? KA_GETTGT_ANS_LABEL"tgsT" :
1220 KA_GETADM_ANS_LABEL"admT"));
1221 if (code)
1222 goto abort;
1223#ifdef EXPIREPW
1224 if ((version == 2)
1225 && oanswer->SeqLen < oanswer->MaxSeqLen + sizeof(afs_int32)) {
1226 temp = pwexpires << 24; /* move it into the high byte */
1227 pwexpires = htonl(temp)(__builtin_constant_p(temp) ? ((((__uint32_t)(temp)) >>
24) | ((((__uint32_t)(temp)) & (0xff << 16)) >>
8) | ((((__uint32_t)(temp)) & (0xff << 8)) <<
8) | (((__uint32_t)(temp)) << 24)) : __bswap32_var(temp
))
;
1228
1229 memcpy((char *)oanswer->SeqBody + oanswer->SeqLen, &pwexpires,
1230 sizeof(afs_int32));
1231 oanswer->SeqLen += sizeof(afs_int32);
1232 oanswer->SeqLen = round_up_to_ebs(oanswer->SeqLen)(((oanswer->SeqLen) + 7) & (~7));
1233 if (oanswer->SeqLen > oanswer->MaxSeqLen) {
1234 code = KAANSWERTOOLONG(180489L);
1235 goto abort;
1236 }
1237 }
1238#endif /* EXPIREPW */
1239 break;
1240
1241 default:
1242 code = KAINTERNALERROR(180518L);
1243 goto abort;
1244 }
1245 DES_pcbc_encrypthc_DES_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, oanswer->SeqLen,
1246 &user_schedule, ktc_to_cblockptr(&tentry.key), ENCRYPT1);
1247 code = ubik_EndTrans(tt);
1248 KALOG(aname, ainstance, sname, sinst, NULL, call->conn->peer->host,kalog_log(aname,ainstance,sname,sinst,((void *)0),call->conn
->peer->host,3)
1249 LOG_AUTHENTICATE)kalog_log(aname,ainstance,sname,sinst,((void *)0),call->conn
->peer->host,3)
;
1250 return code;
1251
1252 abort:
1253 COUNT_ABO(*this_op)++;
1254 ubik_AbortTrans(tt);
1255 KALOG(aname, ainstance, sname, sinst, NULL, call->conn->peer->host,kalog_log(aname,ainstance,sname,sinst,((void *)0),call->conn
->peer->host,7)
1256 LOG_AUTHFAILED)kalog_log(aname,ainstance,sname,sinst,((void *)0),call->conn
->peer->host,7)
;
1257 return code;
1258}
1259
1260afs_int32
1261SKAA_Authenticate_old(struct rx_call *call, char *aname, char *ainstance,
1262 Dateafs_uint32 start, Dateafs_uint32 end, ka_CBS *arequest,
1263 ka_BBS *oanswer)
1264{
1265 int code;
1266
1267 IOMGR_Sleep(1); /* discourage use of this mechanism */
1268 code =
1269 Authenticate(0, call, aname, ainstance, start, end, arequest,
1270 oanswer);
1271 osi_auditU(call, AFS_KAA_AuthOEvent"AFS_KAA_AuthO", code, AUD_STR1, aname, AUD_STR1,
1272 ainstance, AUD_END0);
1273
1274 return code;
1275}
1276
1277afs_int32
1278SKAA_Authenticate(struct rx_call *call, char *aname, char *ainstance,
1279 Dateafs_uint32 start, Dateafs_uint32 end, ka_CBS *arequest, ka_BBS *oanswer)
1280{
1281 int code;
1282
1283 code =
1284 Authenticate(1, call, aname, ainstance, start, end, arequest,
1285 oanswer);
1286 osi_auditU(call, AFS_KAA_AuthEvent"AFS_KAA_Auth", code, AUD_STR1, aname, AUD_STR1,
1287 ainstance, AUD_END0);
1288
1289 return code;
1290}
1291
1292afs_int32
1293SKAA_AuthenticateV2(struct rx_call *call, char *aname, char *ainstance,
1294 Dateafs_uint32 start, Dateafs_uint32 end, ka_CBS *arequest, ka_BBS *oanswer)
1295{
1296 int code;
1297
1298 code =
1299 Authenticate(2, call, aname, ainstance, start, end, arequest,
1300 oanswer);
1301 osi_auditU(call, AFS_KAA_AuthEvent"AFS_KAA_Auth", code, AUD_STR1, aname, AUD_STR1,
1302 ainstance, AUD_END0);
1303
1304 return code;
1305}
1306
1307afs_int32
1308SKAM_SetFields(struct rx_call *call,
1309 char *aname,
1310 char *ainstance,
1311 afs_int32 aflags,
1312 Dateafs_uint32 aexpiration,
1313 afs_int32 alifetime,
1314 afs_int32 amaxAssociates,
1315 afs_uint32 misc_auth_bytes, /* 4 bytes, each 0 means unspecified */
1316 afs_int32 spare2)
1317{
1318 afs_int32 code;
1319
1320 code =
1321 kamSetFields(call, aname, ainstance, aflags, aexpiration, alifetime,
1322 amaxAssociates, misc_auth_bytes, spare2);
1323 osi_auditU(call, AFS_KAM_SetFldEvent"AFS_KAM_SetFld", code, AUD_STR1, aname, AUD_STR1,
1324 ainstance, AUD_LONG5, aflags, AUD_DATE6, aexpiration, AUD_LONG5,
1325 alifetime, AUD_LONG5, amaxAssociates, AUD_END0);
1326 return code;
1327}
1328
1329afs_int32
1330kamSetFields(struct rx_call *call,
1331 char *aname,
1332 char *ainstance,
1333 afs_int32 aflags,
1334 Dateafs_uint32 aexpiration,
1335 afs_int32 alifetime,
1336 afs_int32 amaxAssociates,
1337 afs_uint32 misc_auth_bytes, /* 4 bytes, each 0 means unspecified */
1338 afs_int32 spare2)
1339{
1340 afs_int32 code;
1341 Dateafs_uint32 now;
1342 struct ubik_trans *tt;
1343 afs_int32 caller;
1344 afs_int32 tentry_offset; /* offset of entry */
1345 struct kaentry tentry;
1346 unsigned char newvals[4];
1347
1348 COUNT_REQ(SetFields)int *this_op = &dynamic_statistics.SetFields.aborts; dynamic_statistics
.SetFields.requests++; lastOperation = "SetFields"
;
1349
1350 if (spare2)
1351 return KABADARGUMENT(180492L); /* not supported yet... */
1352
1353 /* make sure we're supposed to do something */
1354 if (!(aflags || aexpiration || alifetime || (amaxAssociates >= 0)
1355 || misc_auth_bytes)
1356 || ((aflags & ~KAFNORMAL0x001) & ~KAF_SETTABLE_FLAGS(0x004 | 0x008 | 0x020 | 0x040 | 0x080)))
1357 return KABADARGUMENT(180492L); /* arguments no good */
1358 if (!name_instance_legal(aname, ainstance))
1359 return KABADNAME(180486L);
1360 if ((code = InitAuthServ(&tt, LOCKWRITE2, this_op)))
1361 return code;
1362 code = check_auth(call, tt, 1, &caller);
1363 if (code) {
1364 goto abort;
1365 }
1366
1367 code = FindBlock(tt, aname, ainstance, &tentry_offset, &tentry);
1368 if (code)
1369 goto abort;
1370 if (tentry_offset == 0) { /* no such user */
1371 code = KANOENT(180484L);
1372 goto abort;
1373 }
1374 if ((ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFNORMAL0x001) == 0)
1375 return KAINTERNALERROR(180518L);
1376 if (aflags) {
1377 /* Keep track of the total number of admin accounts. This way we can
1378 * update database without any admin privilege initially */
1379 if ((aflags & KAFADMIN0x004) != (ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFADMIN0x004)) {
1380 /* if admin state is changing */
1381 int delta;
1382 if (ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFADMIN0x004)
1383 delta = -1;
1384 else
1385 delta = 1;
1386 if ((code = update_admin_count(tt, delta)))
1387 goto abort;
1388 }
1389 tentry.flags =
1390 htonl((ntohl(tentry.flags) & ~KAF_SETTABLE_FLAGS) | aflags)(__builtin_constant_p(((__builtin_constant_p(tentry.flags) ? (
(((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t)(
tentry.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tentry.flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.flags)) << 24)) : __bswap32_var(tentry.flags))
& ~(0x004 | 0x008 | 0x020 | 0x040 | 0x080)) | aflags) ? (
(((__uint32_t)(((__builtin_constant_p(tentry.flags) ? ((((__uint32_t
)(tentry.flags)) >> 24) | ((((__uint32_t)(tentry.flags)
) & (0xff << 16)) >> 8) | ((((__uint32_t)(tentry
.flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.flags)) << 24)) : __bswap32_var(tentry.flags))
& ~(0x004 | 0x008 | 0x020 | 0x040 | 0x080)) | aflags)) >>
24) | ((((__uint32_t)(((__builtin_constant_p(tentry.flags) ?
((((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t
)(tentry.flags)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(tentry.flags)) & (0xff << 8)) << 8
) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) & ~(0x004 | 0x008 | 0x020 | 0x040 | 0x080
)) | aflags)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(((__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry
.flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags)) & ~
(0x004 | 0x008 | 0x020 | 0x040 | 0x080)) | aflags)) & (0xff
<< 8)) << 8) | (((__uint32_t)(((__builtin_constant_p
(tentry.flags) ? ((((__uint32_t)(tentry.flags)) >> 24) |
((((__uint32_t)(tentry.flags)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.flags)) & (0xff << 8))
<< 8) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) & ~(0x004 | 0x008 | 0x020 | 0x040 | 0x080
)) | aflags)) << 24)) : __bswap32_var(((__builtin_constant_p
(tentry.flags) ? ((((__uint32_t)(tentry.flags)) >> 24) |
((((__uint32_t)(tentry.flags)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.flags)) & (0xff << 8))
<< 8) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) & ~(0x004 | 0x008 | 0x020 | 0x040 | 0x080
)) | aflags))
;
1391 }
1392 if ((code = get_time(&now, tt, 1)))
1393 goto abort;
1394 if (aexpiration) {
1395 tentry.user_expiration = htonl(aexpiration)(__builtin_constant_p(aexpiration) ? ((((__uint32_t)(aexpiration
)) >> 24) | ((((__uint32_t)(aexpiration)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(aexpiration)) & (0xff
<< 8)) << 8) | (((__uint32_t)(aexpiration)) <<
24)) : __bswap32_var(aexpiration))
;
1396 if (!ntohl(tentry.change_password_time)(__builtin_constant_p(tentry.change_password_time) ? ((((__uint32_t
)(tentry.change_password_time)) >> 24) | ((((__uint32_t
)(tentry.change_password_time)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.change_password_time)) & (0xff
<< 8)) << 8) | (((__uint32_t)(tentry.change_password_time
)) << 24)) : __bswap32_var(tentry.change_password_time)
)
) {
1397 tentry.change_password_time = htonl(now)(__builtin_constant_p(now) ? ((((__uint32_t)(now)) >> 24
) | ((((__uint32_t)(now)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(now)) & (0xff << 8)) << 8
) | (((__uint32_t)(now)) << 24)) : __bswap32_var(now))
;
1398 }
1399 }
1400 if (alifetime)
1401 tentry.max_ticket_lifetime = htonl(alifetime)(__builtin_constant_p(alifetime) ? ((((__uint32_t)(alifetime)
) >> 24) | ((((__uint32_t)(alifetime)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(alifetime)) & (0xff <<
8)) << 8) | (((__uint32_t)(alifetime)) << 24)) :
__bswap32_var(alifetime))
;
1402
1403#ifndef NOPWCONTROLS
1404 /*
1405 * We've packed a bunch of bytes into a long for backward compatibility.
1406 * These include password expiration time, and some failed login limits
1407 * counters. Now let's unpack them and stick them into the
1408 * kaentry struct. All the bytes have values in the range
1409 * 1..255, else they were not specified in the interface, and are
1410 * set to zero.
1411 * In the case of password expiration times, 1 means password never
1412 * expires (==>0), 2 means password only lives for one day (==>1),
1413 * and so on.
1414 */
1415 if (misc_auth_bytes) {
1416 unpack_long(misc_auth_bytes, newvals){ newvals[0] = ((unsigned char)(((afs_uint32)(misc_auth_bytes
) & 0xff000000) >> 24) & 0xff); newvals[1] = ((
unsigned char)(((afs_uint32)(misc_auth_bytes) & 0x00ff0000
) >> 16) & 0xff); newvals[2] = ((unsigned char)(((afs_uint32
)(misc_auth_bytes) & 0x0000ff00) >> 8) & 0xff);
newvals[3] = ((unsigned char)(((afs_uint32)(misc_auth_bytes)
& 0x000000ff) >> 0) & 0xff); }
;
1417 if (newvals[EXPIRES0]) {
1418 tentry.misc_auth_bytes[EXPIRES0] = newvals[EXPIRES0] - 1;
1419 }
1420
1421 if (newvals[REUSEFLAGS1]) {
1422 if (newvals[REUSEFLAGS1] & KA_REUSEPW1)
1423 memset(tentry.pwsums, 0, KA_NPWSUMS(200 - sizeof(kaident) - sizeof(struct ktc_encryptionKey) - 11
*4)
);
1424 else if ((newvals[REUSEFLAGS1] & KA_NOREUSEPW2)
1425 && !tentry.pwsums[0])
1426 tentry.pwsums[0] = 0xff;
1427 }
1428
1429 if (newvals[ATTEMPTS2]) {
1430 tentry.misc_auth_bytes[ATTEMPTS2] = newvals[ATTEMPTS2] - 1;
1431 }
1432 if (newvals[LOCKTIME3]) {
1433 tentry.misc_auth_bytes[LOCKTIME3] = newvals[LOCKTIME3] - 1;
1434 }
1435/*
1436 tentry.misc_auth_bytes = htonl(tentry.misc_auth_bytes);
1437*/
1438 }
1439#endif /* NOPWCONTROLS */
1440
1441 if (amaxAssociates >= 0) {
1442 if ((ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFASSOC0x400)
1443 || (ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFSPECIAL0x100))
1444 return KAASSOCUSER(180512L);
1445 if (((ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFASSOCROOT0x200) == 0) && (amaxAssociates > 0)) /* convert normal user to assoc root */
1446 tentry.flags = htonl(ntohl(tentry.flags) | KAFASSOCROOT)(__builtin_constant_p((__builtin_constant_p(tentry.flags) ? (
(((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t)(
tentry.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tentry.flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.flags)) << 24)) : __bswap32_var(tentry.flags))
| 0x200) ? ((((__uint32_t)((__builtin_constant_p(tentry.flags
) ? ((((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t
)(tentry.flags)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(tentry.flags)) & (0xff << 8)) << 8
) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x200)) >> 24) | ((((__uint32_t)((__builtin_constant_p
(tentry.flags) ? ((((__uint32_t)(tentry.flags)) >> 24) |
((((__uint32_t)(tentry.flags)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.flags)) & (0xff << 8))
<< 8) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x200)) & (0xff << 16)) >> 8
) | ((((__uint32_t)((__builtin_constant_p(tentry.flags) ? (((
(__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t)(tentry
.flags)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(tentry.flags)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.flags)) << 24)) : __bswap32_var(tentry.flags))
| 0x200)) & (0xff << 8)) << 8) | (((__uint32_t
)((__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry
.flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags)) | 0x200
)) << 24)) : __bswap32_var((__builtin_constant_p(tentry
.flags) ? ((((__uint32_t)(tentry.flags)) >> 24) | ((((__uint32_t
)(tentry.flags)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(tentry.flags)) & (0xff << 8)) << 8
) | (((__uint32_t)(tentry.flags)) << 24)) : __bswap32_var
(tentry.flags)) | 0x200))
;
1447 tentry.misc.assocRoot.maxAssociates = htonl(amaxAssociates)(__builtin_constant_p(amaxAssociates) ? ((((__uint32_t)(amaxAssociates
)) >> 24) | ((((__uint32_t)(amaxAssociates)) & (0xff
<< 16)) >> 8) | ((((__uint32_t)(amaxAssociates))
& (0xff << 8)) << 8) | (((__uint32_t)(amaxAssociates
)) << 24)) : __bswap32_var(amaxAssociates))
;
1448 }
1449
1450 tentry.modification_time = htonl(now)(__builtin_constant_p(now) ? ((((__uint32_t)(now)) >> 24
) | ((((__uint32_t)(now)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(now)) & (0xff << 8)) << 8
) | (((__uint32_t)(now)) << 24)) : __bswap32_var(now))
;
1451 tentry.modification_id = htonl(caller)(__builtin_constant_p(caller) ? ((((__uint32_t)(caller)) >>
24) | ((((__uint32_t)(caller)) & (0xff << 16)) >>
8) | ((((__uint32_t)(caller)) & (0xff << 8)) <<
8) | (((__uint32_t)(caller)) << 24)) : __bswap32_var(caller
))
;
1452 code = kawrite(tt, tentry_offset, (char *) &tentry, sizeof(tentry));
1453 if (code)
1454 goto abort;
1455
1456 code = ubik_EndTrans(tt);
1457 KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,5)
1458 LOG_SETFIELDS)kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,5)
;
1459 return code;
1460
1461 abort:
1462 COUNT_ABO(*this_op)++;
1463 ubik_AbortTrans(tt);
1464 return code;
1465}
1466
1467/* delete a user */
1468
1469afs_int32
1470SKAM_DeleteUser(struct rx_call *call, char *aname, char *ainstance)
1471{
1472 afs_int32 code;
1473
1474 code = kamDeleteUser(call, aname, ainstance);
1475 osi_auditU(call, AFS_KAM_DelUserEvent"AFS_KAM_DelUser", code, AUD_STR1, aname, AUD_STR1,
1476 ainstance, AUD_END0);
1477 return code;
1478}
1479
1480afs_int32
1481kamDeleteUser(struct rx_call *call, char *aname, char *ainstance)
1482{
1483 int code;
1484 struct ubik_trans *tt;
1485 afs_int32 caller;
1486 afs_int32 to;
1487 struct kaentry tentry;
1488 unsigned int nfailures;
1489 afs_uint32 locktime;
1490
1491 COUNT_REQ(DeleteUser)int *this_op = &dynamic_statistics.DeleteUser.aborts; dynamic_statistics
.DeleteUser.requests++; lastOperation = "DeleteUser"
;
1492 if (!name_instance_legal(aname, ainstance))
1493 return KABADNAME(180486L);
1494 if ((code = InitAuthServ(&tt, LOCKWRITE2, this_op)))
1495 return code;
1496 code = check_auth(call, tt, 1, &caller);
1497 if (code) {
1498 abort:
1499 COUNT_ABO(*this_op)++;
1500 ubik_AbortTrans(tt);
1501 return code;
1502 }
1503
1504 code = FindBlock(tt, aname, ainstance, &to, &tentry);
1505 if (code)
1506 goto abort;
1507 if (to == 0) { /* name not found */
1508 code = KANOENT(180484L);
1509 goto abort;
1510 }
1511
1512 kaux_read(to, &nfailures, &locktime);
1513 if (nfailures || locktime)
1514 kaux_write(to, 0, 0); /* zero failure counters at this offset */
1515
1516 /* track all AuthServer identities */
1517 if (special_name(aname, ainstance))
1518 if ((code = ka_DelKey(tt, to, &tentry)))
1519 goto abort;
1520
1521 if (ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
& KAFADMIN0x004) /* keep admin count up-to-date */
1522 if ((code = update_admin_count(tt, -1)))
1523 goto abort;
1524
1525 if ((code = UnthreadBlock(tt, &tentry)) || (code = FreeBlock(tt, to)) || (code = get_time(0, tt, 1)) /* update randomness */
1526 )
1527 goto abort;
1528
1529 code = ubik_EndTrans(tt);
1530 KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,4)
1531 LOG_DELUSER)kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,4)
;
1532 return code;
1533}
1534
1535/* we set a bit in here which indicates that the user's limit of
1536 * authentication failures has been exceeded. If that bit is not set,
1537 * kas can take it on faith that the user ID is not locked. If that
1538 * bit is set, kas has to check all the servers to find one who will
1539 * report that the ID is not locked, or else to find out when the ID
1540 * will be unlocked.
1541 */
1542afs_int32
1543SKAM_GetEntry(struct rx_call *call,
1544 char *aname,
1545 char *ainstance,
1546 afs_int32 aversion, /* major version assumed by caller */
1547 kaentryinfo *aentry) /* entry data copied here */
1548{
1549 afs_int32 code;
1550
1551 code = kamGetEntry(call, aname, ainstance, aversion, aentry);
1552 osi_auditU(call, AFS_KAM_GetEntEvent"AFS_KAM_GetEnt", code, AUD_STR1, aname, AUD_STR1,
1553 ainstance, AUD_END0);
1554 return code;
1555}
1556
1557afs_int32
1558kamGetEntry(struct rx_call *call,
1559 char *aname,
1560 char *ainstance,
1561 afs_int32 aversion, /* major version assumed by caller */
1562 kaentryinfo *aentry) /* entry data copied here */
1563{
1564 afs_int32 code;
1565 struct ubik_trans *tt;
1566 afs_int32 callerIndex;
1567 struct kaentry caller;
1568 afs_int32 to;
1569 afs_uint32 temp;
1570 struct kaentry tentry;
1571 rxkad_level enc_level = rxkad_clear0;
1572 int callerIsAdmin = 0;
1573
1574 COUNT_REQ(GetEntry)int *this_op = &dynamic_statistics.GetEntry.aborts; dynamic_statistics
.GetEntry.requests++; lastOperation = "GetEntry"
;
1575 if (aversion != KAMAJORVERSION5)
1576 return KAOLDINTERFACE(180491L);
1577 if (!name_instance_legal(aname, ainstance))
1578 return KABADNAME(180486L);
1579 if ((code = InitAuthServ(&tt, LOCKREAD1, this_op)))
1580 return code;
1581 code = check_auth(call, tt, 0, &callerIndex);
1582 if (code) {
1583 goto abort;
1584 }
1585 if (noAuthenticationRequired) {
1586 } else if (!callerIndex) {
1587 code = KANOENT(180484L);
1588 goto abort;
1589 } else {
1590 if ((code = karead(tt, callerIndex, (char *)&caller, sizeof(caller)))) {
1591 code = KAIO(180482L);
1592 goto abort;
1593 }
1594 /* if the user is checking his own entry or ADMIN then go ahead. */
1595 callerIsAdmin = (ntohl(caller.flags)(__builtin_constant_p(caller.flags) ? ((((__uint32_t)(caller.
flags)) >> 24) | ((((__uint32_t)(caller.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(caller.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(caller
.flags)) << 24)) : __bswap32_var(caller.flags))
& KAFADMIN0x004);
1596
1597 if (strcmp(caller.userID.name, aname) != 0 && !callerIsAdmin) {
1598 code = KANOAUTH(180488L);
1599 goto abort;
1600 }
1601 }
1602
1603 code = FindBlock(tt, aname, ainstance, &to, &tentry);
1604 if (code)
1605 goto abort;
1606 if (to == 0) { /* entry not found */
1607 code = KANOENT(180484L);
1608 goto abort;
1609 }
1610
1611 get_time(0, 0, 0); /* generate random update */
1612
1613 memset(aentry, 0, sizeof(*aentry));
1614 aentry->minor_version = KAMINORVERSION2;
1615 aentry->flags = ntohl(tentry.flags)(__builtin_constant_p(tentry.flags) ? ((((__uint32_t)(tentry.
flags)) >> 24) | ((((__uint32_t)(tentry.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(tentry.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(tentry
.flags)) << 24)) : __bswap32_var(tentry.flags))
;
1616 aentry->user_expiration = ntohl(tentry.user_expiration)(__builtin_constant_p(tentry.user_expiration) ? ((((__uint32_t
)(tentry.user_expiration)) >> 24) | ((((__uint32_t)(tentry
.user_expiration)) & (0xff << 16)) >> 8) | ((
((__uint32_t)(tentry.user_expiration)) & (0xff << 8
)) << 8) | (((__uint32_t)(tentry.user_expiration)) <<
24)) : __bswap32_var(tentry.user_expiration))
;
1617 aentry->modification_time = ntohl(tentry.modification_time)(__builtin_constant_p(tentry.modification_time) ? ((((__uint32_t
)(tentry.modification_time)) >> 24) | ((((__uint32_t)(tentry
.modification_time)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(tentry.modification_time)) & (0xff <<
8)) << 8) | (((__uint32_t)(tentry.modification_time)) <<
24)) : __bswap32_var(tentry.modification_time))
;
1618 aentry->change_password_time = ntohl(tentry.change_password_time)(__builtin_constant_p(tentry.change_password_time) ? ((((__uint32_t
)(tentry.change_password_time)) >> 24) | ((((__uint32_t
)(tentry.change_password_time)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.change_password_time)) & (0xff
<< 8)) << 8) | (((__uint32_t)(tentry.change_password_time
)) << 24)) : __bswap32_var(tentry.change_password_time)
)
;
1619 aentry->max_ticket_lifetime = ntohl(tentry.max_ticket_lifetime)(__builtin_constant_p(tentry.max_ticket_lifetime) ? ((((__uint32_t
)(tentry.max_ticket_lifetime)) >> 24) | ((((__uint32_t)
(tentry.max_ticket_lifetime)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry.max_ticket_lifetime)) & (0xff
<< 8)) << 8) | (((__uint32_t)(tentry.max_ticket_lifetime
)) << 24)) : __bswap32_var(tentry.max_ticket_lifetime))
;
1620 aentry->key_version = ntohl(tentry.key_version)(__builtin_constant_p(tentry.key_version) ? ((((__uint32_t)(tentry
.key_version)) >> 24) | ((((__uint32_t)(tentry.key_version
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(tentry
.key_version)) & (0xff << 8)) << 8) | (((__uint32_t
)(tentry.key_version)) << 24)) : __bswap32_var(tentry.key_version
))
;
1621
1622 temp = (unsigned char)tentry.misc_auth_bytes[LOCKTIME3];
1623 temp = temp << 9;
1624 if (kaux_islocked(to, (u_int) tentry.misc_auth_bytes[ATTEMPTS2], temp))
1625 tentry.misc_auth_bytes[REUSEFLAGS1] |= KA_ISLOCKED4; /* saves an RPC */
1626
1627 temp = pack_long(tentry.misc_auth_bytes)( (afs_uint32) ( ((afs_uint32) ((tentry.misc_auth_bytes)[0] &
0xff) << 24) | ((afs_uint32) ((tentry.misc_auth_bytes)
[1] & 0xff) << 16) | ((afs_uint32) ((tentry.misc_auth_bytes
)[2] & 0xff) << 8) | ((afs_uint32) ((tentry.misc_auth_bytes
)[3] & 0xff) << 0) ) )
;
1628 aentry->misc_auth_bytes = temp;
1629 /*
1630 * only return user's key if security disabled or if admin and
1631 * we have an encrypted connection to the user
1632 */
1633 rxkad_GetServerInfo(call->conn, &enc_level, 0, 0, 0, 0, 0);
1634 if ((noAuthenticationRequired)
1635 || (callerIsAdmin && enc_level == rxkad_crypt2))
1636 memcpy(&aentry->key, &tentry.key, sizeof(struct ktc_encryptionKey));
1637 else
1638 memset(&aentry->key, 0, sizeof(aentry->key));
1639 code = ka_KeyCheckSum((char *)&tentry.key, &aentry->keyCheckSum);
Value stored to 'code' is never read
1640 if (!tentry.pwsums[0] && npwSums > 1 && !tentry.pwsums[1]) {
1641 aentry->reserved3 = 0x12340000;
1642 } else {
1643 aentry->reserved3 = 0x12340001;
1644 }
1645
1646 /* Now get entry of user who last modified this entry */
1647 if (ntohl(tentry.modification_id)(__builtin_constant_p(tentry.modification_id) ? ((((__uint32_t
)(tentry.modification_id)) >> 24) | ((((__uint32_t)(tentry
.modification_id)) & (0xff << 16)) >> 8) | ((
((__uint32_t)(tentry.modification_id)) & (0xff << 8
)) << 8) | (((__uint32_t)(tentry.modification_id)) <<
24)) : __bswap32_var(tentry.modification_id))
) {
1648 temp = ntohl(tentry.modification_id)(__builtin_constant_p(tentry.modification_id) ? ((((__uint32_t
)(tentry.modification_id)) >> 24) | ((((__uint32_t)(tentry
.modification_id)) & (0xff << 16)) >> 8) | ((
((__uint32_t)(tentry.modification_id)) & (0xff << 8
)) << 8) | (((__uint32_t)(tentry.modification_id)) <<
24)) : __bswap32_var(tentry.modification_id))
;
1649 code = karead(tt, temp, (char *)&tentry, sizeof(tentry));
1650 if (code) {
1651 code = KAIO(180482L);
1652 goto abort;
1653 }
1654 aentry->modification_user = tentry.userID;
1655 } else {
1656 strcpy(aentry->modification_user.name, "<none>");
1657 strcpy(aentry->modification_user.instance, "\0");
1658 }
1659 code = ubik_EndTrans(tt);
1660 return code;
1661
1662 abort:
1663 COUNT_ABO(*this_op)++;
1664 ubik_AbortTrans(tt);
1665 return code;
1666}
1667
1668afs_int32
1669SKAM_ListEntry(struct rx_call *call,
1670 afs_int32 previous_index, /* last entry ret'd or 0 for first */
1671 afs_int32 *index, /* index of this entry */
1672 afs_int32 *count, /* total entries in database */
1673 kaident *name) /* name & instance of this entry */
1674{
1675 afs_int32 code;
1676
1677 code = kamListEntry(call, previous_index, index, count, name);
1678 osi_auditU(call, AFS_KAM_LstEntEvent"AFS_KAM_LstEnt", code, AUD_LONG5, *index, AUD_END0);
1679 return code;
1680}
1681
1682
1683afs_int32
1684kamListEntry(struct rx_call *call,
1685 afs_int32 previous_index, /* last entry ret'd or 0 for first */
1686 afs_int32 *index, /* index of this entry */
1687 afs_int32 *count, /* total entries in database */
1688 kaident *name) /* name & instance of this entry */
1689{
1690 int code;
1691 struct ubik_trans *tt;
1692 afs_int32 caller;
1693 struct kaentry tentry;
1694
1695 COUNT_REQ(ListEntry)int *this_op = &dynamic_statistics.ListEntry.aborts; dynamic_statistics
.ListEntry.requests++; lastOperation = "ListEntry"
;
1696 if ((code = InitAuthServ(&tt, LOCKREAD1, this_op)))
1697 return code;
1698 code = check_auth(call, tt, 1, &caller);
1699 if (code) {
1700 goto abort;
1701 }
1702
1703 *index = NextBlock(tt, previous_index, &tentry, count);
1704 if (*count < 0) {
1705 code = KAIO(180482L);
1706 goto abort;
1707 }
1708
1709 if (*index) { /* return name & inst of this entry */
1710 strncpy(name->name, tentry.userID.name, sizeof(name->name));
1711 strncpy(name->instance, tentry.userID.instance,
1712 sizeof(name->instance));
1713 } else {
1714 strcpy(name->name, "\0");
1715 strcpy(name->instance, "\0");
1716 }
1717 code = ubik_EndTrans(tt);
1718 return code;
1719
1720 abort:
1721 COUNT_ABO(*this_op)++;
1722 ubik_AbortTrans(tt);
1723 return code;
1724}
1725
1726static afs_int32
1727GetTicket(int version,
1728 struct rx_call *call,
1729 afs_int32 kvno,
1730 char *authDomain,
1731 ka_CBS *aticket,
1732 char *sname,
1733 char *sinstance,
1734 ka_CBS *atimes, /* encrypted start & end time */
1735 ka_BBS *oanswer)
1736{
1737 afs_int32 code;
1738 int import, export;
1739 struct ubik_trans *tt;
1740 struct ktc_encryptionKey tgskey;
1741 DES_key_schedule schedule;
1742 afs_int32 to;
1743 char name[MAXKTCNAMELEN64];
1744 char instance[MAXKTCNAMELEN64];
1745 char cell[MAXKTCNAMELEN64];
1746 int celllen;
1747 struct kaentry caller;
1748 struct kaentry server;
1749 struct ktc_encryptionKey authSessionKey;
1750 struct ktc_encryptionKey sessionKey;
1751 int ticketLen;
1752 char ticket[MAXKTCTICKETLEN12000];
1753 afs_int32 host;
1754 Dateafs_uint32 start;
1755 Dateafs_uint32 expiration;
1756 Dateafs_uint32 now;
1757 Dateafs_uint32 end;
1758 struct ka_getTicketTimes times;
1759 struct ka_getTicketAnswer *answer;
1760
1761 COUNT_REQ(GetTicket)int *this_op = &dynamic_statistics.GetTicket.aborts; dynamic_statistics
.GetTicket.requests++; lastOperation = "GetTicket"
;
1762 if (!name_instance_legal(sname, sinstance))
1763 return KABADNAME(180486L);
1764 if (atimes->SeqLen != sizeof(times))
1765 return KABADARGUMENT(180492L);
1766 if ((code = InitAuthServ(&tt, LOCKREAD1, this_op)))
1767 return code;
1768
1769 export = import = 0;
1770 if ((strcmp(sname, KA_TGS_NAME"krbtgt") == 0) && (strcmp(sinstance, lrealm) != 0))
1771 export = 1;
1772 if ((strlen(authDomain) > 0) && (strcmp(authDomain, lrealm) != 0))
1773 import = 1;
1774
1775 if (strlen(authDomain) == 0)
1776 authDomain = lrealm;
1777 code = ka_LookupKvno(tt, KA_TGS_NAME"krbtgt", authDomain, kvno, &tgskey);
1778 if (code) {
1779 goto abort;
1780 }
1781 code =
1782 tkt_DecodeTicket(aticket->SeqBody, aticket->SeqLen, &tgskey, name,
1783 instance, cell, &authSessionKey, &host, &start,
1784 &expiration);
1785 if (code) {
1786 code = KANOAUTH(180488L);
1787 goto abort;
1788 }
1789 save_principal(tgsPrincipal, name, instance, cell);
1790
1791 if ((code = get_time(&now, 0, 0)))
1792 goto abort;
1793
1794 code = tkt_CheckTimes(start, expiration, now);
1795 if (code <= 0) {
1796 if (code == -1)
1797 code = RXKADEXPIRED(19270409L);
1798 else
1799 code = KANOAUTH(180488L);
1800 goto abort;
1801 }
1802 code = DES_key_schedhc_DES_key_sched(ktc_to_cblock(&authSessionKey), &schedule);
1803 if (code) {
1804 code = KANOAUTH(180488L);
1805 goto abort;
1806 }
1807 celllen = strlen(cell);
1808 if (import && (celllen == 0)) {
1809 code = KABADTICKET(180504L);
1810 goto abort;
1811 }
1812 if (export && (celllen == 0))
1813 strcpy(cell, lrealm);
1814
1815 if (!krb4_cross && celllen && strcmp(lrealm, cell) != 0) {
1816 code = KABADUSER(180508L);
1817 goto abort;
1818 }
1819
1820 DES_ecb_encrypthc_DES_ecb_encrypt((DES_cblock *)atimes->SeqBody, (DES_cblock *)&times, &schedule, DECRYPT0);
1821 times.start = ntohl(times.start)(__builtin_constant_p(times.start) ? ((((__uint32_t)(times.start
)) >> 24) | ((((__uint32_t)(times.start)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(times.start)) & (0xff
<< 8)) << 8) | (((__uint32_t)(times.start)) <<
24)) : __bswap32_var(times.start))
;
1822 times.end = ntohl(times.end)(__builtin_constant_p(times.end) ? ((((__uint32_t)(times.end)
) >> 24) | ((((__uint32_t)(times.end)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(times.end)) & (0xff <<
8)) << 8) | (((__uint32_t)(times.end)) << 24)) :
__bswap32_var(times.end))
;
1823 code = tkt_CheckTimes(times.start, times.end, now);
1824 if (code < 0) {
1825 code = KABADREQUEST(180490L);
1826 goto abort;
1827 }
1828
1829 if (import) {
1830 strcpy(caller.userID.name, name);
1831 strcpy(caller.userID.instance, instance);
1832 caller.max_ticket_lifetime = htonl(MAXKTCTICKETLIFETIME)(__builtin_constant_p((30*24*3600)) ? ((((__uint32_t)((30*24*
3600))) >> 24) | ((((__uint32_t)((30*24*3600))) & (
0xff << 16)) >> 8) | ((((__uint32_t)((30*24*3600)
)) & (0xff << 8)) << 8) | (((__uint32_t)((30*
24*3600))) << 24)) : __bswap32_var((30*24*3600)))
;
1833 caller.flags = htonl(KAFNORMAL)(__builtin_constant_p(0x001) ? ((((__uint32_t)(0x001)) >>
24) | ((((__uint32_t)(0x001)) & (0xff << 16)) >>
8) | ((((__uint32_t)(0x001)) & (0xff << 8)) <<
8) | (((__uint32_t)(0x001)) << 24)) : __bswap32_var(0x001
))
;
1834 caller.user_expiration = htonl(NEVERDATE)(__builtin_constant_p(037777777777) ? ((((__uint32_t)(037777777777
)) >> 24) | ((((__uint32_t)(037777777777)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(037777777777)) & (0xff
<< 8)) << 8) | (((__uint32_t)(037777777777)) <<
24)) : __bswap32_var(037777777777))
;
1835 } else {
1836 code = FindBlock(tt, name, instance, &to, &caller);
1837 if (code)
1838 goto abort;
1839 if (to == 0) {
1840 ka_PrintUserID("GetTicket: User ", name, instance, " unknown.\n");
1841 code = KANOENT(180484L);
1842 goto abort;
1843 }
1844 }
1845
1846 /* get server's entry */
1847 code = FindBlock(tt, sname, sinstance, &to, &server);
1848 if (code)
1849 goto abort;
1850 if (to == 0) { /* entry not found */
1851 ka_PrintUserID("GetTicket: Server ", sname, sinstance, " unknown.\n");
1852 code = KANOENT(180484L);
1853 goto abort;
1854 }
1855 save_principal(tgsServerPrincipal, sname, sinstance, 0);
1856
1857 code = DES_new_random_keyhc_DES_new_random_key(ktc_to_cblock(&sessionKey));
1858 if (code) {
1859 code = KANOKEYS(180494L);
1860 goto abort;
1861 }
1862
1863 code =
1864 GetEndTime(times.start, times.end, expiration, &caller, &server,
1865 &end);
1866 if (code)
1867 goto abort;
1868
1869 code =
1870 tkt_MakeTicket(ticket, &ticketLen, &server.key, caller.userID.name,
1871 caller.userID.instance, cell, times.start, end,
1872 &sessionKey,
1873 rx_HostOf(rx_PeerOf(rx_ConnectionOf(call)))((((((call)->conn))->peer))->host),
1874 server.userID.name, server.userID.instance);
1875 if (code)
1876 goto abort;
1877
1878 switch (version) {
1879 case 0:
1880 code = KAANSWERTOOLONG(180489L);
1881 if (oanswer->MaxSeqLen <
1882 sizeof(struct ka_getTicketAnswer) - 5 * MAXKTCNAMELEN64 -
1883 MAXKTCTICKETLEN12000 + ticketLen)
1884 goto abort;
1885
1886 answer = (struct ka_getTicketAnswer *)oanswer->SeqBody;
1887 memcpy(&answer->sessionKey, &sessionKey,
1888 sizeof(struct ktc_encryptionKey));
1889 answer->startTime = htonl(times.start)(__builtin_constant_p(times.start) ? ((((__uint32_t)(times.start
)) >> 24) | ((((__uint32_t)(times.start)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(times.start)) & (0xff
<< 8)) << 8) | (((__uint32_t)(times.start)) <<
24)) : __bswap32_var(times.start))
;
1890 answer->endTime = htonl(end)(__builtin_constant_p(end) ? ((((__uint32_t)(end)) >> 24
) | ((((__uint32_t)(end)) & (0xff << 16)) >> 8
) | ((((__uint32_t)(end)) & (0xff << 8)) << 8
) | (((__uint32_t)(end)) << 24)) : __bswap32_var(end))
;
1891 answer->kvno = server.key_version;
1892 answer->ticketLen = htonl(ticketLen)(__builtin_constant_p(ticketLen) ? ((((__uint32_t)(ticketLen)
) >> 24) | ((((__uint32_t)(ticketLen)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(ticketLen)) & (0xff <<
8)) << 8) | (((__uint32_t)(ticketLen)) << 24)) :
__bswap32_var(ticketLen))
;
1893
1894 {
1895 char *ans = answer->name; /* ptr to variable part of answer */
1896 int rem, len;
1897
1898 /* space remaining */
1899 rem = oanswer->MaxSeqLen - (ans - oanswer->SeqBody);
1900#undef putstr
1901#define putstr(str)len = strlen (str)+1; if (rem < len) goto abort; strcpy (ans
, str); ans += len; rem -= len
len = strlen (str)+1;\
1902 if (rem < len) goto abort;\
1903 strcpy (ans, str);\
1904 ans += len; rem -= len
1905
1906 putstr(name)len = strlen (name)+1; if (rem < len) goto abort; strcpy (
ans, name); ans += len; rem -= len
;
1907 putstr(instance)len = strlen (instance)+1; if (rem < len) goto abort; strcpy
(ans, instance); ans += len; rem -= len
;
1908 putstr(cell)len = strlen (cell)+1; if (rem < len) goto abort; strcpy (
ans, cell); ans += len; rem -= len
;
1909 putstr(sname)len = strlen (sname)+1; if (rem < len) goto abort; strcpy (
ans, sname); ans += len; rem -= len
;
1910 putstr(sinstance)len = strlen (sinstance)+1; if (rem < len) goto abort; strcpy
(ans, sinstance); ans += len; rem -= len
;
1911 if (rem < ticketLen)
1912 goto abort;
1913 memcpy(ans, ticket, ticketLen);
1914 oanswer->SeqLen = (ans - oanswer->SeqBody) + ticketLen;
1915 }
1916 oanswer->SeqLen = round_up_to_ebs(oanswer->SeqLen)(((oanswer->SeqLen) + 7) & (~7));
1917 break;
1918 case 1:
1919 code =
1920 PrepareTicketAnswer(oanswer, /*challenge */ 0, ticket, ticketLen,
1921 &sessionKey, times.start, end, &caller,
1922 &server, cell, KA_GETTICKET_ANS_LABEL"gtkt");
1923 if (code)
1924 goto abort;
1925 break;
1926 default:
1927 code = KAINTERNALERROR(180518L);
1928 goto abort;
1929 }
1930 DES_pcbc_encrypthc_DES_pcbc_encrypt(oanswer->SeqBody, oanswer->SeqBody, oanswer->SeqLen,
1931 &schedule, ktc_to_cblockptr(&authSessionKey), ENCRYPT1);
1932 code = ubik_EndTrans(tt);
1933 KALOG(name, instance, sname, sinstance, (import ? authDomain : NULL),kalog_log(name,instance,sname,sinstance,(import ? authDomain :
((void *)0)),call->conn->peer->host,0)
1934 call->conn->peer->host, LOG_GETTICKET)kalog_log(name,instance,sname,sinstance,(import ? authDomain :
((void *)0)),call->conn->peer->host,0)
;
1935 return code;
1936
1937 abort:
1938 COUNT_ABO(*this_op)++;
1939 ubik_AbortTrans(tt);
1940 return code;
1941}
1942
1943afs_int32
1944SKAT_GetTicket_old(struct rx_call *call,
1945 afs_int32 kvno,
1946 char *authDomain,
1947 ka_CBS *aticket,
1948 char *sname,
1949 char *sinstance,
1950 ka_CBS *atimes, /* encrypted start & end time */
1951 ka_BBS *oanswer)
1952{
1953 int code;
1954
1955 sleep(1); /* strongly discourage this */
1956 code =
1957 GetTicket(0, call, kvno, authDomain, aticket, sname, sinstance,
1958 atimes, oanswer);
1959
1960 osi_auditU(call, AFS_KAT_GetTicketOEvent"AFS_KAT_GetTktO", code, AUD_STR1, sname, AUD_STR1,
1961 sinstance, AUD_END0);
1962 return code;
1963}
1964
1965afs_int32
1966SKAT_GetTicket(struct rx_call *call,
1967 afs_int32 kvno,
1968 char *authDomain,
1969 ka_CBS *aticket,
1970 char *sname,
1971 char *sinstance,
1972 ka_CBS *atimes, /* encrypted start & end time */
1973 ka_BBS *oanswer)
1974{
1975 int code;
1976
1977 code =
1978 GetTicket(1, call, kvno, authDomain, aticket, sname, sinstance,
1979 atimes, oanswer);
1980 osi_auditU(call, AFS_KAT_GetTicketEvent"AFS_KAT_GetTkt", code, AUD_STR1, sname, AUD_STR1,
1981 sinstance, AUD_END0);
1982 return code;
1983}
1984
1985afs_int32
1986SKAM_GetStats(struct rx_call *call, afs_int32 version,
1987 afs_int32 *admin_accounts, kasstats *statics,
1988 kadstats *dynamics)
1989{
1990 afs_int32 code;
1991
1992 code = kamGetStats(call, version, admin_accounts, statics, dynamics);
1993 osi_auditU(call, AFS_KAM_GetStatEvent"AFS_KAM_GetStat", code, AUD_END0);
1994 return code;
1995}
1996
1997afs_int32
1998kamGetStats(struct rx_call *call, afs_int32 version,
1999 afs_int32 *admin_accounts, kasstats *statics,
2000 kadstats *dynamics)
2001{
2002 afs_int32 code;
2003 struct ubik_trans *tt;
2004 afs_int32 caller;
2005
2006 COUNT_REQ(GetStats)int *this_op = &dynamic_statistics.GetStats.aborts; dynamic_statistics
.GetStats.requests++; lastOperation = "GetStats"
;
2007 if (version != KAMAJORVERSION5)
2008 return KAOLDINTERFACE(180491L);
2009 if ((code = InitAuthServ(&tt, LOCKREAD1, this_op)))
2010 return code;
2011 code = check_auth(call, tt, 1, &caller);
2012 if (code) {
2013 COUNT_ABO(*this_op)++;
2014 ubik_AbortTrans(tt);
2015 return code;
2016 }
2017
2018 *admin_accounts = ntohl(cheader.admin_accounts)(__builtin_constant_p(cheader.admin_accounts) ? ((((__uint32_t
)(cheader.admin_accounts)) >> 24) | ((((__uint32_t)(cheader
.admin_accounts)) & (0xff << 16)) >> 8) | (((
(__uint32_t)(cheader.admin_accounts)) & (0xff << 8)
) << 8) | (((__uint32_t)(cheader.admin_accounts)) <<
24)) : __bswap32_var(cheader.admin_accounts))
;
2019 /* memcpy((char *)statics, (char *)&cheader.stats, sizeof(kasstats)); */
2020 /* these are stored in network byte order and must be copied */
2021 statics->allocs = ntohl(cheader.stats.allocs)(__builtin_constant_p(cheader.stats.allocs) ? ((((__uint32_t)
(cheader.stats.allocs)) >> 24) | ((((__uint32_t)(cheader
.stats.allocs)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(cheader.stats.allocs)) & (0xff << 8)) << 8)
| (((__uint32_t)(cheader.stats.allocs)) << 24)) : __bswap32_var
(cheader.stats.allocs))
;
2022 statics->frees = ntohl(cheader.stats.frees)(__builtin_constant_p(cheader.stats.frees) ? ((((__uint32_t)(
cheader.stats.frees)) >> 24) | ((((__uint32_t)(cheader.
stats.frees)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(cheader.stats.frees)) & (0xff << 8)) << 8) |
(((__uint32_t)(cheader.stats.frees)) << 24)) : __bswap32_var
(cheader.stats.frees))
;
2023 statics->cpws = ntohl(cheader.stats.cpws)(__builtin_constant_p(cheader.stats.cpws) ? ((((__uint32_t)(cheader
.stats.cpws)) >> 24) | ((((__uint32_t)(cheader.stats.cpws
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(cheader
.stats.cpws)) & (0xff << 8)) << 8) | (((__uint32_t
)(cheader.stats.cpws)) << 24)) : __bswap32_var(cheader.
stats.cpws))
;
2024#if KADBVERSION5 != 5
2025 check that the statistics command copies all the fields
2026#endif
2027 memcpy((char *)dynamics, (char *)&dynamic_statistics, sizeof(kadstats));
2028 statics->minor_version = KAMINORVERSION2;
2029 dynamics->minor_version = KAMINORVERSION2;
2030
2031 {
2032 int used = 0;
2033 int i;
2034
2035 for (i = 0; i < HASHSIZE8191; i++)
2036 if (cheader.nameHash[i])
2037 used++;
2038 dynamics->hashTableUtilization =
2039 (used * 10000 + HASHSIZE8191 / 2) / HASHSIZE8191;
2040 }
2041 {
2042#if !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV) && !defined(AFS_NT40_ENV)
2043 struct rusage ru;
2044 /* Unfortunately, although aix_22 has a minimal compatibility
2045 * method of getting to some rusage fields (i.e. stime &
2046 * utime), the version that we have doesn't even have the
2047 * related include files needed for the aix vtimes() call; so
2048 * ignore this for aix till v3.1... */
2049 getrusage(RUSAGE_SELF0, &ru);
2050#if (KAMAJORVERSION5>5)
2051 memcpy(&dynamics->utime, &ru.ru_utime, sizeof(struct katimeval));
2052 memcpy(&dynamics->stime, &ru.ru_stime, sizeof(struct katimeval));
2053 dynamics->dataSize = ru.ru_idrss;
2054 dynamics->stackSize = ru.ru_isrss;
2055 dynamics->pageFailts = ru.ru_majflt;
2056#else
2057 dynamics->string_checks =
2058 (afs_int32) (1000.0 *
2059 ((ru.ru_utime.tv_sec +
2060 ru.ru_utime.tv_usec / 1000000.0) +
2061 (ru.ru_stime.tv_sec +
2062 ru.ru_stime.tv_usec / 1000000.0)));
2063#endif
2064#endif /* AFS_AIX_ENV && AFS_HPUX_ENV && AFS_NT40_ENV */
2065 }
2066
2067 code = ubik_EndTrans(tt);
2068 return code;
2069}
2070
2071afs_int32
2072SKAM_GetPassword(struct rx_call *call, char *name, EncryptionKey *password)
2073{
2074 afs_int32 code;
2075
2076 code = kamGetPassword(call, name, password);
2077 osi_auditU(call, AFS_KAM_GetPswdEvent"AFS_KAM_GetPswd", code, AUD_STR1, name, AUD_END0);
2078 return code;
2079}
2080
2081afs_int32
2082kamGetPassword(struct rx_call *call, char *name, EncryptionKey *password)
2083{
2084 int code = KANOAUTH(180488L);
2085 AFS_UNUSED__attribute__((unused)) COUNT_REQ(GetPassword)int *this_op = &dynamic_statistics.GetPassword.aborts; dynamic_statistics
.GetPassword.requests++; lastOperation = "GetPassword"
;
2086#ifdef GETPASSWORD
2087 {
2088 afs_int32 to;
2089 struct ubik_trans *tt;
2090 struct kaentry tentry;
2091
2092 if (!name_instance_legal(name, ""))
2093 return KABADNAME(180486L);
2094 /* only requests from this host work */
2095 if (rx_HostOf(rx_PeerOf(rx_ConnectionOf(call)))((((((call)->conn))->peer))->host) !=
2096 htonl(INADDR_LOOPBACK)(__builtin_constant_p((u_int32_t)0x7f000001) ? ((((__uint32_t
)((u_int32_t)0x7f000001)) >> 24) | ((((__uint32_t)((u_int32_t
)0x7f000001)) & (0xff << 16)) >> 8) | ((((__uint32_t
)((u_int32_t)0x7f000001)) & (0xff << 8)) << 8
) | (((__uint32_t)((u_int32_t)0x7f000001)) << 24)) : __bswap32_var
((u_int32_t)0x7f000001))
)
2097 return KANOAUTH(180488L);
2098 if (code = InitAuthServ(&tt, LOCKREAD1, this_op))
2099 return code;
2100
2101 /* this isn't likely to be used because of string to key problems, so since
2102 * this is a temporary thing anyway, we'll use it here. */
2103 {
2104 extern char udpAuthPrincipal[256];
2105
2106 save_principal(udpAuthPrincipal, name, 0, 0);
2107 }
2108
2109 get_time(0, 0, 0); /* update random value */
2110 code = FindBlock(tt, name, "", &to, &tentry);
2111 if (code)
2112 goto abort;
2113 if (to == 0) {
2114 code = KANOENT(180484L);
2115 abort:
2116 COUNT_ABO(*this_op)++;
2117 ubik_AbortTrans(tt);
2118 return code;
2119 }
2120
2121 memcpy(password, &tentry.key, sizeof(*password));
2122 code = ubik_EndTrans(tt);
2123 }
2124#endif
2125 return code;
2126}
2127
2128afs_int32
2129SKAM_GetRandomKey(struct rx_call *call, EncryptionKey *key)
2130{
2131 afs_int32 code;
2132
2133 code = kamGetRandomKey(call, key);
2134 osi_auditU(call, AFS_KAM_GetRndKeyEvent"AFS_KAM_GRnKey", code, AUD_END0);
2135 return code;
2136}
2137
2138afs_int32
2139kamGetRandomKey(struct rx_call *call, EncryptionKey *key)
2140{
2141 int code;
2142
2143 AFS_UNUSED__attribute__((unused)) COUNT_REQ(GetRandomKey)int *this_op = &dynamic_statistics.GetRandomKey.aborts; dynamic_statistics
.GetRandomKey.requests++; lastOperation = "GetRandomKey"
;
2144 if ((code = AwaitInitialization()))
2145 return code;
2146 code = DES_new_random_keyhc_DES_new_random_key(EncryptionKey_to_cblock(key));
2147 if (code)
2148 return KANOKEYS(180494L);
2149 return 0;
2150}
2151
2152afs_int32
2153SKAM_Debug(struct rx_call *call,
2154 afs_int32 version,
2155 int checkDB, /* start a transaction to examine DB */
2156 struct ka_debugInfo *info)
2157{
2158 afs_int32 code;
2159
2160 code = kamDebug(call, version, checkDB, info);
2161 osi_auditU(call, AFS_KAM_DbgEvent"AFS_KAM_Dbg", code, AUD_END0);
2162 return code;
2163}
2164
2165afs_int32
2166kamDebug(struct rx_call *call,
2167 afs_int32 version,
2168 int checkDB, /* start a transaction to examine DB */
2169 struct ka_debugInfo *info)
2170{
2171/* COUNT_REQ (Debug); */
2172 if (sizeof(struct kaentry) != sizeof(struct kaOldKeys))
2173 return KAINTERNALERROR(180518L);
2174 if (sizeof(struct ka_cpwRequest) % 8)
2175 return KAINTERNALERROR(180518L);
2176 if (version != KAMAJORVERSION5)
2177 return KAOLDINTERFACE(180491L);
2178
2179 memset(info, 0, sizeof(*info));
2180
2181 info->minorVersion = KAMINORVERSION2;
2182 info->host = dynamic_statistics.host;
2183 info->startTime = dynamic_statistics.start_time;
2184 info->
2185#if (KAMAJORVERSION5>5)
2186 now
2187#else
2188 reserved1
2189#endif
2190 = time(0);
2191 info->noAuth = noAuthenticationRequired;
2192
2193 info->dbVersion = ntohl(cheader.version)(__builtin_constant_p(cheader.version) ? ((((__uint32_t)(cheader
.version)) >> 24) | ((((__uint32_t)(cheader.version)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(cheader.version
)) & (0xff << 8)) << 8) | (((__uint32_t)(cheader
.version)) << 24)) : __bswap32_var(cheader.version))
;
2194 info->dbFreePtr = ntohl(cheader.freePtr)(__builtin_constant_p(cheader.freePtr) ? ((((__uint32_t)(cheader
.freePtr)) >> 24) | ((((__uint32_t)(cheader.freePtr)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(cheader.freePtr
)) & (0xff << 8)) << 8) | (((__uint32_t)(cheader
.freePtr)) << 24)) : __bswap32_var(cheader.freePtr))
;
2195 info->dbEofPtr = ntohl(cheader.eofPtr)(__builtin_constant_p(cheader.eofPtr) ? ((((__uint32_t)(cheader
.eofPtr)) >> 24) | ((((__uint32_t)(cheader.eofPtr)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(cheader.eofPtr
)) & (0xff << 8)) << 8) | (((__uint32_t)(cheader
.eofPtr)) << 24)) : __bswap32_var(cheader.eofPtr))
;
2196 info->dbKvnoPtr = ntohl(cheader.kvnoPtr)(__builtin_constant_p(cheader.kvnoPtr) ? ((((__uint32_t)(cheader
.kvnoPtr)) >> 24) | ((((__uint32_t)(cheader.kvnoPtr)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(cheader.kvnoPtr
)) & (0xff << 8)) << 8) | (((__uint32_t)(cheader
.kvnoPtr)) << 24)) : __bswap32_var(cheader.kvnoPtr))
;
2197 info->dbSpecialKeysVersion = ntohl(cheader.specialKeysVersion)(__builtin_constant_p(cheader.specialKeysVersion) ? ((((__uint32_t
)(cheader.specialKeysVersion)) >> 24) | ((((__uint32_t)
(cheader.specialKeysVersion)) & (0xff << 16)) >>
8) | ((((__uint32_t)(cheader.specialKeysVersion)) & (0xff
<< 8)) << 8) | (((__uint32_t)(cheader.specialKeysVersion
)) << 24)) : __bswap32_var(cheader.specialKeysVersion))
;
2198
2199 info->dbHeaderRead = cheaderReadTime;
2200 info->lastTrans = lastTrans;
2201 if (!lastOperation)
2202 lastOperation = "(Not Available)";
2203 strncpy(info->lastOperation, lastOperation, sizeof(info->lastOperation));
2204 strncpy(info->lastAuth, authPrincipal, sizeof(info->lastAuth));
2205 strncpy(info->lastTGS, tgsPrincipal, sizeof(info->lastTGS));
2206 strncpy(info->lastAdmin, adminPrincipal, sizeof(info->lastAdmin));
2207 strncpy(info->lastTGSServer, tgsServerPrincipal,
2208 sizeof(info->lastTGSServer));
2209 {
2210 extern char udpAuthPrincipal[256];
2211 extern char udptgsPrincipal[256];
2212 extern char udptgsServerPrincipal[256];
2213
2214 strncpy(info->lastUAuth, udpAuthPrincipal, sizeof(info->lastUAuth));
2215 strncpy(info->lastUTGS, udptgsPrincipal, sizeof(info->lastUTGS));
2216 strncpy(info->lastUTGSServer, udptgsServerPrincipal,
2217 sizeof(info->lastUTGSServer));
2218 }
2219 info->nextAutoCPW = nextAutoCPWTime;
2220 info->updatesRemaining = autoCPWUpdates - totalUpdates;
2221 ka_debugKeyCache(info);
2222 return 0;
2223}
2224
2225/* these are auxiliary routines. They don't do any Ubik stuff. They use
2226 * a tacked-on-the-side data file.
2227 * prob'ly ought to check the noauth flag.
2228 */
2229#define ABORTIF(A){if((code = A)){goto abort;}} {if((code = A)){goto abort;}}
2230afs_int32
2231SKAM_Unlock(struct rx_call *call,
2232 char *aname,
2233 char *ainstance,
2234 afs_int32 spare1,
2235 afs_int32 spare2,
2236 afs_int32 spare3,
2237 afs_int32 spare4)
2238{
2239 int code;
2240 struct ubik_trans *tt;
2241 afs_int32 caller;
2242 afs_int32 to;
2243 struct kaentry tentry;
2244
2245 COUNT_REQ(Unlock)int *this_op = &dynamic_statistics.Unlock.aborts; dynamic_statistics
.Unlock.requests++; lastOperation = "Unlock"
;
2246 if (!name_instance_legal(aname, ainstance)) {
2247 code = KABADNAME(180486L);
2248 goto exit;
2249 }
2250 if ((code = InitAuthServ(&tt, LOCKREAD1, this_op)))
2251 goto exit;
2252
2253 ABORTIF(check_auth(call, tt, 1, &caller)){if((code = check_auth(call, tt, 1, &caller))){goto abort
;}}
;
2254 ABORTIF(FindBlock(tt, aname, ainstance, &to, &tentry)){if((code = FindBlock(tt, aname, ainstance, &to, &tentry
))){goto abort;}}
;
2255 ABORTIF((to == 0 ? KANOENT : 0)){if((code = (to == 0 ? (180484L) : 0))){goto abort;}};
2256
2257 kaux_write(to, 0, 0); /* zero failure counters at this offset */
2258
2259 code = ubik_EndTrans(tt);
2260 KALOG(aname, ainstance, NULL, NULL, NULL, call->conn->peer->host,kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,6)
2261 LOG_UNLOCK)kalog_log(aname,ainstance,((void *)0),((void *)0),((void *)0)
,call->conn->peer->host,6)
;
2262 goto exit;
2263
2264 abort:
2265 COUNT_ABO(*this_op)++;
2266 ubik_AbortTrans(tt);
2267
2268 exit:
2269 osi_auditU(call, UnlockEvent"AFS_UnlockUser", code, AUD_STR1, aname, AUD_STR1, ainstance,
2270 AUD_END0);
2271 return code;
2272}
2273
2274afs_int32
2275SKAM_LockStatus(struct rx_call *call,
2276 char *aname,
2277 char *ainstance,
2278 afs_int32 *lockeduntil,
2279 afs_int32 spare1,
2280 afs_int32 spare2,
2281 afs_int32 spare3,
2282 afs_int32 spare4)
2283{
2284 int code;
2285 struct ubik_trans *tt;
2286 afs_int32 callerIndex;
2287 afs_int32 to;
2288 struct kaentry caller;
2289 struct kaentry tentry;
2290 afs_uint32 temp;
2291
2292 COUNT_REQ(LockStatus)int *this_op = &dynamic_statistics.LockStatus.aborts; dynamic_statistics
.LockStatus.requests++; lastOperation = "LockStatus"
;
2293
2294 if (!name_instance_legal(aname, ainstance)) {
2295 code = KABADNAME(180486L);
2296 goto exit;
2297 }
2298 if ((code = InitAuthServ(&tt, LOCKREAD1, this_op)))
2299 goto exit;
2300
2301 if ((code = check_auth(call, tt, 0, &callerIndex)))
2302 goto abort;
2303
2304 if (!noAuthenticationRequired && callerIndex) {
2305 if (karead(tt, callerIndex, (char *)&caller, sizeof(caller))) {
2306 code = KAIO(180482L);
2307 goto abort;
2308 }
2309 /* if the user is checking his own entry or ADMIN then go ahead. */
2310 if ((strcmp(caller.userID.name, aname) != 0)
2311 && !(ntohl(caller.flags)(__builtin_constant_p(caller.flags) ? ((((__uint32_t)(caller.
flags)) >> 24) | ((((__uint32_t)(caller.flags)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(caller.flags
)) & (0xff << 8)) << 8) | (((__uint32_t)(caller
.flags)) << 24)) : __bswap32_var(caller.flags))
& KAFADMIN0x004)) {
2312 code = KANOAUTH(180488L);
2313 goto abort;
2314 }
2315 }
2316
2317 if ((code = FindBlock(tt, aname, ainstance, &to, &tentry)))
2318 goto abort;
2319
2320 if (to == 0) {
2321 code = KANOENT(180484L);
2322 goto abort;
2323 }
2324
2325 temp = (unsigned char)tentry.misc_auth_bytes[LOCKTIME3];
2326 temp = temp << 9;
2327 *lockeduntil =
2328 kaux_islocked(to, (u_int) tentry.misc_auth_bytes[ATTEMPTS2], temp);
2329
2330 code = ubik_EndTrans(tt);
2331 goto exit;
2332
2333 abort:
2334 COUNT_ABO(*this_op)++;
2335 ubik_AbortTrans(tt);
2336 osi_auditU(call, LockStatusEvent"AFS_LockStatus", code, AUD_STR1, aname, AUD_STR1,
2337 ainstance, AUD_END0);
2338
2339 exit:
2340 return code;
2341}