Bug Summary

File:kauth/kadatabase.c
Location:line 161, column 48
Description:The left operand of '==' is a garbage value

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
13#include <roken.h>
14
15#include <ubik.h>
16#include <rx/xdr.h>
17#include <rx/rx.h>
18#include <afs/afsutil.h>
19
20#include "kauth.h"
21#include "kautils.h"
22#include "kaserver.h"
23
24extern Dateafs_uint32 cheaderReadTime; /* time cheader last read in */
25
26#define set_header_word(tt,field,value)kawrite ((tt), ((char *)&(cheader.field) - (char *)&cheader
), ((cheader.field = (value)), (char *)&(cheader.field)),
sizeof(afs_int32))
kawrite ((tt), ((char *)&(cheader.field) - (char *)&cheader), ((cheader.field = (value)), (char *)&(cheader.field)), sizeof(afs_int32))
27
28#define inc_header_word(tt,field)kawrite ((tt), ((char *)&(cheader.field) - (char *)&cheader
), ((cheader.field = ((__builtin_constant_p((__builtin_constant_p
(cheader.field) ? ((((__uint32_t)(cheader.field)) >> 24
) | ((((__uint32_t)(cheader.field)) & (0xff << 16))
>> 8) | ((((__uint32_t)(cheader.field)) & (0xff <<
8)) << 8) | (((__uint32_t)(cheader.field)) << 24
)) : __bswap32_var(cheader.field))+1) ? ((((__uint32_t)((__builtin_constant_p
(cheader.field) ? ((((__uint32_t)(cheader.field)) >> 24
) | ((((__uint32_t)(cheader.field)) & (0xff << 16))
>> 8) | ((((__uint32_t)(cheader.field)) & (0xff <<
8)) << 8) | (((__uint32_t)(cheader.field)) << 24
)) : __bswap32_var(cheader.field))+1)) >> 24) | ((((__uint32_t
)((__builtin_constant_p(cheader.field) ? ((((__uint32_t)(cheader
.field)) >> 24) | ((((__uint32_t)(cheader.field)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(cheader.field
)) & (0xff << 8)) << 8) | (((__uint32_t)(cheader
.field)) << 24)) : __bswap32_var(cheader.field))+1)) &
(0xff << 16)) >> 8) | ((((__uint32_t)((__builtin_constant_p
(cheader.field) ? ((((__uint32_t)(cheader.field)) >> 24
) | ((((__uint32_t)(cheader.field)) & (0xff << 16))
>> 8) | ((((__uint32_t)(cheader.field)) & (0xff <<
8)) << 8) | (((__uint32_t)(cheader.field)) << 24
)) : __bswap32_var(cheader.field))+1)) & (0xff << 8
)) << 8) | (((__uint32_t)((__builtin_constant_p(cheader
.field) ? ((((__uint32_t)(cheader.field)) >> 24) | ((((
__uint32_t)(cheader.field)) & (0xff << 16)) >>
8) | ((((__uint32_t)(cheader.field)) & (0xff << 8)
) << 8) | (((__uint32_t)(cheader.field)) << 24)) :
__bswap32_var(cheader.field))+1)) << 24)) : __bswap32_var
((__builtin_constant_p(cheader.field) ? ((((__uint32_t)(cheader
.field)) >> 24) | ((((__uint32_t)(cheader.field)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(cheader.field
)) & (0xff << 8)) << 8) | (((__uint32_t)(cheader
.field)) << 24)) : __bswap32_var(cheader.field))+1)))),
(char *)&(cheader.field)), sizeof(afs_int32))
kawrite ((tt), ((char *)&(cheader.field) - (char *)&cheader), ((cheader.field = (htonl(ntohl(cheader.field)+1)(__builtin_constant_p((__builtin_constant_p(cheader.field) ? (
(((__uint32_t)(cheader.field)) >> 24) | ((((__uint32_t)
(cheader.field)) & (0xff << 16)) >> 8) | ((((
__uint32_t)(cheader.field)) & (0xff << 8)) <<
8) | (((__uint32_t)(cheader.field)) << 24)) : __bswap32_var
(cheader.field))+1) ? ((((__uint32_t)((__builtin_constant_p(cheader
.field) ? ((((__uint32_t)(cheader.field)) >> 24) | ((((
__uint32_t)(cheader.field)) & (0xff << 16)) >>
8) | ((((__uint32_t)(cheader.field)) & (0xff << 8)
) << 8) | (((__uint32_t)(cheader.field)) << 24)) :
__bswap32_var(cheader.field))+1)) >> 24) | ((((__uint32_t
)((__builtin_constant_p(cheader.field) ? ((((__uint32_t)(cheader
.field)) >> 24) | ((((__uint32_t)(cheader.field)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(cheader.field
)) & (0xff << 8)) << 8) | (((__uint32_t)(cheader
.field)) << 24)) : __bswap32_var(cheader.field))+1)) &
(0xff << 16)) >> 8) | ((((__uint32_t)((__builtin_constant_p
(cheader.field) ? ((((__uint32_t)(cheader.field)) >> 24
) | ((((__uint32_t)(cheader.field)) & (0xff << 16))
>> 8) | ((((__uint32_t)(cheader.field)) & (0xff <<
8)) << 8) | (((__uint32_t)(cheader.field)) << 24
)) : __bswap32_var(cheader.field))+1)) & (0xff << 8
)) << 8) | (((__uint32_t)((__builtin_constant_p(cheader
.field) ? ((((__uint32_t)(cheader.field)) >> 24) | ((((
__uint32_t)(cheader.field)) & (0xff << 16)) >>
8) | ((((__uint32_t)(cheader.field)) & (0xff << 8)
) << 8) | (((__uint32_t)(cheader.field)) << 24)) :
__bswap32_var(cheader.field))+1)) << 24)) : __bswap32_var
((__builtin_constant_p(cheader.field) ? ((((__uint32_t)(cheader
.field)) >> 24) | ((((__uint32_t)(cheader.field)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(cheader.field
)) & (0xff << 8)) << 8) | (((__uint32_t)(cheader
.field)) << 24)) : __bswap32_var(cheader.field))+1))
)), (char *)&(cheader.field)), sizeof(afs_int32))
29
30static int index_OK(afs_int32);
31
32afs_int32
33NameHash(char *aname, char *ainstance)
34{
35 unsigned int hash;
36 int i;
37
38 /* stolen directly from the HashString function in the vol package */
39 hash = 0;
40 for (i = strlen(aname), aname += i - 1; i--; aname--)
41 hash = (hash * 31) + (*((unsigned char *)aname) - 31);
42 for (i = strlen(ainstance), ainstance += i - 1; i--; ainstance--)
43 hash = (hash * 31) + (*((unsigned char *)ainstance) - 31);
44 return (hash % HASHSIZE8191);
45}
46
47/* package up seek and write into one procedure for ease of use */
48
49afs_int32
50kawrite(struct ubik_trans *tt, afs_int32 pos, char *buff, afs_int32 len)
51{
52 afs_int32 code;
53
54 code = ubik_Seek(tt, 0, pos);
55 if (code)
56 return code;
57 code = ubik_Write(tt, buff, len);
58 return code;
59}
60
61/* same thing for read */
62
63afs_int32
64karead(struct ubik_trans *tt, afs_int32 pos, char *buff, afs_int32 len)
65{
66 afs_int32 code;
67
68 code = ubik_Seek(tt, 0, pos);
69 if (code)
70 return code;
71 code = ubik_Read(tt, buff, len);
72 return code;
73}
74
75static struct Lock keycache_lock;
76
77static int maxCachedKeys;
78
79static struct cachedKey {
80 Dateafs_uint32 used;
81 int superseded; /* NEVERDATE => this is current key */
82 afs_int32 kvno;
83 struct ktc_encryptionKey key;
84 char name[MAXKTCNAMELEN64];
85 char inst[MAXKTCNAMELEN64];
86} *keyCache;
87static afs_int32 keyCacheVersion = 0;
88
89static afs_int32 maxKeyLifetime;
90static int dbfixup = 0;
91
92void
93init_kadatabase(int initFlags)
94{
95 Lock_Init(&keycache_lock);
96
97 maxCachedKeys = 10;
98 keyCache =
99 (struct cachedKey *)malloc(maxCachedKeys * sizeof(struct cachedKey));
100 keyCacheVersion = 0;
101 if (initFlags & 4) {
102 maxKeyLifetime = 90;
103 } else {
104 maxKeyLifetime = MAXKTCTICKETLIFETIME(30*24*3600);
105 }
106 if (initFlags & 8)
107 dbfixup++;
108}
109
110/* check that the database has been initialized. Be careful to fail in a safe
111 manner, to avoid bogusly reinitializing the db. */
112/**
113 * reads in db cache from ubik.
114 *
115 * @param[in] ut ubik transaction
116 * @param[in] rock opaque pointer to an int (*) (struct ubik_trans *), which
117 * will be called on rebuilding the database (or NULL to not
118 * rebuild the db)
119 *
120 * @return operation status
121 * @retval 0 success
122 */
123static afs_int32
124UpdateCache(struct ubik_trans *at, void *rock)
125{
126 int (*db_init) (struct ubik_trans *) = rock;
127 afs_int32 code;
128 afs_int32 iversion;
129 afs_int32 tversion;
1
Variable 'tversion' declared without an initial value
130
131 if ((code = karead(at, 0, (char *)&iversion, sizeof(iversion)))
2
Taking true branch
132 || (code =
133 karead(at, sizeof(cheader) - sizeof(afs_int32), (char *)&tversion,
134 sizeof(afs_int32)))) {
135 if (code == UEOF(5390L))
3
Taking false branch
136 printf("No data base\n");
137 else
138 printf("I/O Error\n");
139 } else {
140 iversion = ntohl(iversion)(__builtin_constant_p(iversion) ? ((((__uint32_t)(iversion)) >>
24) | ((((__uint32_t)(iversion)) & (0xff << 16)) >>
8) | ((((__uint32_t)(iversion)) & (0xff << 8)) <<
8) | (((__uint32_t)(iversion)) << 24)) : __bswap32_var
(iversion))
; /* convert to host order */
141 tversion = ntohl(tversion)(__builtin_constant_p(tversion) ? ((((__uint32_t)(tversion)) >>
24) | ((((__uint32_t)(tversion)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tversion)) & (0xff << 8)) <<
8) | (((__uint32_t)(tversion)) << 24)) : __bswap32_var
(tversion))
;
142 if ((iversion == KADBVERSION5) && (tversion == KADBVERSION5)) {
143 code = karead(at, 0, (char *)&cheader, sizeof(cheader));
144 if (code) {
145 printf("SetupHeader failed\n");
146 code = KAIO(180482L);
147 } else {
148 cheaderReadTime = time(0);
149 }
150 } else {
151 printf("DB version should be %d; Initial = %d; Terminal = %d\n",
152 KADBVERSION5, iversion, tversion);
153 code = KAIO(180482L);
154 }
155 }
156 if (code == 0)
4
Taking false branch
157 return 0;
158
159 /* if here, we have no version number or the wrong version number in the
160 * file */
161 if ((code == UEOF(5390L)) || ((iversion == 0) && (tversion == 0)))
5
The left operand of '==' is a garbage value
162 code = KAEMPTY(180485L);
163 else
164 code = KAIO(180482L);
165
166 if ((db_init == 0) || (code == KAIO(180482L)))
167 return code;
168
169 printf("Error discovered in header, rebuilding.\n");
170
171 /* try to write a good header */
172 memset(&cheader, 0, sizeof(cheader));
173 cheader.version = htonl(KADBVERSION)(__builtin_constant_p(5) ? ((((__uint32_t)(5)) >> 24) |
((((__uint32_t)(5)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(5)) & (0xff << 8)) << 8) | (((
__uint32_t)(5)) << 24)) : __bswap32_var(5))
;
174 cheader.checkVersion = htonl(KADBVERSION)(__builtin_constant_p(5) ? ((((__uint32_t)(5)) >> 24) |
((((__uint32_t)(5)) & (0xff << 16)) >> 8) | (
(((__uint32_t)(5)) & (0xff << 8)) << 8) | (((
__uint32_t)(5)) << 24)) : __bswap32_var(5))
;
175 cheader.headerSize = htonl(sizeof(cheader))(__builtin_constant_p(sizeof(cheader)) ? ((((__uint32_t)(sizeof
(cheader))) >> 24) | ((((__uint32_t)(sizeof(cheader))) &
(0xff << 16)) >> 8) | ((((__uint32_t)(sizeof(cheader
))) & (0xff << 8)) << 8) | (((__uint32_t)(sizeof
(cheader))) << 24)) : __bswap32_var(sizeof(cheader)))
;
176 cheader.freePtr = 0;
177 cheader.eofPtr = htonl(sizeof(cheader))(__builtin_constant_p(sizeof(cheader)) ? ((((__uint32_t)(sizeof
(cheader))) >> 24) | ((((__uint32_t)(sizeof(cheader))) &
(0xff << 16)) >> 8) | ((((__uint32_t)(sizeof(cheader
))) & (0xff << 8)) << 8) | (((__uint32_t)(sizeof
(cheader))) << 24)) : __bswap32_var(sizeof(cheader)))
;
178 cheader.kvnoPtr = 0;
179 cheader.specialKeysVersion = htonl(time(0))(__builtin_constant_p(time(0)) ? ((((__uint32_t)(time(0))) >>
24) | ((((__uint32_t)(time(0))) & (0xff << 16)) >>
8) | ((((__uint32_t)(time(0))) & (0xff << 8)) <<
8) | (((__uint32_t)(time(0))) << 24)) : __bswap32_var(
time(0)))
; /* anything non-zero will do */
180 cheader.stats.cpws = cheader.stats.allocs = cheader.stats.frees = 0;
181 cheader.admin_accounts = 0;
182 cheader.hashsize = htonl(HASHSIZE)(__builtin_constant_p(8191) ? ((((__uint32_t)(8191)) >>
24) | ((((__uint32_t)(8191)) & (0xff << 16)) >>
8) | ((((__uint32_t)(8191)) & (0xff << 8)) <<
8) | (((__uint32_t)(8191)) << 24)) : __bswap32_var(8191
))
;
183 code = kawrite(at, 0, (char *)&cheader, sizeof(cheader));
184 if (code)
185 return KAIO(180482L); /* return the error code */
186
187 return db_init(at); /* initialize the db */
188}
189
190afs_int32
191CheckInit(struct ubik_trans *at,
192 int (*db_init) (struct ubik_trans *)) /* procedure to call if rebuilding DB */
193{
194 return ubik_CheckCache(at, UpdateCache, db_init);
195}
196
197/* Allocate a free block of storage for entry, returning address of a new
198 zeroed entry. If zero is returned, a Ubik I/O error can be assumed. */
199
200afs_int32
201AllocBlock(struct ubik_trans *at, struct kaentry *tentry)
202{
203 afs_int32 code;
204 afs_int32 temp;
205
206 if (cheader.freePtr) {
207 /* allocate this dude */
208 temp = 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))
;
209 code = karead(at, temp, (char *)tentry, sizeof(kaentry));
210 if (code)
211 return 0; /* can't read block */
212 code = set_header_word(at, freePtr, tentry->next)kawrite ((at), ((char *)&(cheader.freePtr) - (char *)&
cheader), ((cheader.freePtr = (tentry->next)), (char *)&
(cheader.freePtr)), sizeof(afs_int32))
;
213 } else {
214 /* hosed, nothing on free list, grow file */
215 temp = 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))
; /* remember this guy */
216 code = set_header_word(at, eofPtr, htonl(temp + sizeof(kaentry)))kawrite ((at), ((char *)&(cheader.eofPtr) - (char *)&
cheader), ((cheader.eofPtr = ((__builtin_constant_p(temp + sizeof
(kaentry)) ? ((((__uint32_t)(temp + sizeof(kaentry))) >>
24) | ((((__uint32_t)(temp + sizeof(kaentry))) & (0xff <<
16)) >> 8) | ((((__uint32_t)(temp + sizeof(kaentry))) &
(0xff << 8)) << 8) | (((__uint32_t)(temp + sizeof
(kaentry))) << 24)) : __bswap32_var(temp + sizeof(kaentry
))))), (char *)&(cheader.eofPtr)), sizeof(afs_int32))
;
217 }
218 if (code)
219 return 0;
220
221 code = inc_header_word(at, stats.allocs)kawrite ((at), ((char *)&(cheader.stats.allocs) - (char *
)&cheader), ((cheader.stats.allocs = ((__builtin_constant_p
((__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))+1) ? ((((__uint32_t)((__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))+1)) >> 24) | ((((__uint32_t)((__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))+1)) & (0xff << 16)) >> 8) | (
(((__uint32_t)((__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))+1)) & (0xff <<
8)) << 8) | (((__uint32_t)((__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)
)+1)) << 24)) : __bswap32_var((__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)
)+1)))), (char *)&(cheader.stats.allocs)), sizeof(afs_int32
))
;
222 if (code)
223 return 0;
224 memset(tentry, 0, sizeof(kaentry)); /* zero new entry */
225 return temp;
226}
227
228/* Free a block given its index. It must already have been unthreaded.
229 Returns zero for success or an error code on failure. */
230
231afs_int32
232FreeBlock(struct ubik_trans *at, afs_int32 index)
233{
234 struct kaentry tentry;
235 int code;
236
237 /* check index just to be on the safe side */
238 if (!index_OK(index))
239 return KABADINDEX(180487L);
240
241 memset(&tentry, 0, sizeof(kaentry));
242 tentry.next = cheader.freePtr;
243 tentry.flags = htonl(KAFFREE)(__builtin_constant_p(0x002) ? ((((__uint32_t)(0x002)) >>
24) | ((((__uint32_t)(0x002)) & (0xff << 16)) >>
8) | ((((__uint32_t)(0x002)) & (0xff << 8)) <<
8) | (((__uint32_t)(0x002)) << 24)) : __bswap32_var(0x002
))
;
244 code = set_header_word(at, freePtr, htonl(index))kawrite ((at), ((char *)&(cheader.freePtr) - (char *)&
cheader), ((cheader.freePtr = ((__builtin_constant_p(index) ?
((((__uint32_t)(index)) >> 24) | ((((__uint32_t)(index
)) & (0xff << 16)) >> 8) | ((((__uint32_t)(index
)) & (0xff << 8)) << 8) | (((__uint32_t)(index
)) << 24)) : __bswap32_var(index)))), (char *)&(cheader
.freePtr)), sizeof(afs_int32))
;
245 if (code)
246 return KAIO(180482L);
247 code = kawrite(at, index, (char *)&tentry, sizeof(kaentry));
248 if (code)
249 return KAIO(180482L);
250
251 code = inc_header_word(at, stats.frees)kawrite ((at), ((char *)&(cheader.stats.frees) - (char *)
&cheader), ((cheader.stats.frees = ((__builtin_constant_p
((__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))+1) ? ((((__uint32_t)((__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))+1)) >> 24) | ((((__uint32_t)((__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))+1)) & (0xff << 16)) >> 8) | ((
((__uint32_t)((__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))+1)) & (0xff <<
8)) << 8) | (((__uint32_t)((__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))+
1)) << 24)) : __bswap32_var((__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))+
1)))), (char *)&(cheader.stats.frees)), sizeof(afs_int32)
)
;
252 if (code)
253 return KAIO(180482L);
254 return 0;
255}
256
257/* Look for a block by name and instance. If found read the block's contents
258 into the area pointed to by tentry and return the block's index. If not
259 found offset is set to zero. If an error is encountered a non-zero code is
260 returned. */
261
262afs_int32
263FindBlock(struct ubik_trans *at, char *aname, char *ainstance, afs_int32 *toP,
264 struct kaentry *tentry)
265{
266 afs_int32 i, code;
267 afs_int32 to;
268
269 *toP = 0;
270 i = NameHash(aname, ainstance);
271 for (to = ntohl(cheader.nameHash[i])(__builtin_constant_p(cheader.nameHash[i]) ? ((((__uint32_t)(
cheader.nameHash[i])) >> 24) | ((((__uint32_t)(cheader.
nameHash[i])) & (0xff << 16)) >> 8) | ((((__uint32_t
)(cheader.nameHash[i])) & (0xff << 8)) << 8) |
(((__uint32_t)(cheader.nameHash[i])) << 24)) : __bswap32_var
(cheader.nameHash[i]))
; to != NULLO0;
272 to = ntohl(tentry->next)(__builtin_constant_p(tentry->next) ? ((((__uint32_t)(tentry
->next)) >> 24) | ((((__uint32_t)(tentry->next)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(tentry->
next)) & (0xff << 8)) << 8) | (((__uint32_t)(
tentry->next)) << 24)) : __bswap32_var(tentry->next
))
) {
273 code = karead(at, to, (char *)tentry, sizeof(kaentry));
274 if (code)
275 return code;
276 /* see if the name matches */
277 if (!strcmp(aname, tentry->userID.name)
278 && (ainstance == (char *)0
279 || !strcmp(ainstance, tentry->userID.instance))) {
280 *toP = to; /* found it */
281 return 0;
282 }
283 }
284 *toP = 0; /* no such entry */
285 return 0;
286}
287
288/* Add a block to the hash table given a pointer to the block and its index.
289 The block is threaded onto the hash table and written to disk. The routine
290 returns zero if there were no errors. */
291
292afs_int32
293ThreadBlock(struct ubik_trans *at, afs_int32 index,
294 struct kaentry *tentry)
295{
296 int code;
297 int hi; /* hash index */
298
299 if (!index_OK(index))
300 return KABADINDEX(180487L);
301 hi = NameHash(tentry->userID.name, tentry->userID.instance);
302 tentry->next = cheader.nameHash[hi];
303 code = set_header_word(at, nameHash[hi], htonl(index))kawrite ((at), ((char *)&(cheader.nameHash[hi]) - (char *
)&cheader), ((cheader.nameHash[hi] = ((__builtin_constant_p
(index) ? ((((__uint32_t)(index)) >> 24) | ((((__uint32_t
)(index)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(index)) & (0xff << 8)) << 8) | (((__uint32_t
)(index)) << 24)) : __bswap32_var(index)))), (char *)&
(cheader.nameHash[hi])), sizeof(afs_int32))
;
304 if (code)
305 return KAIO(180482L);
306 code = kawrite(at, index, (char *)tentry, sizeof(kaentry));
307 if (code)
308 return KAIO(180482L);
309 return 0;
310}
311
312/* Remove a block from the hash table. If success return 0, else return an
313 error code. */
314
315afs_int32
316UnthreadBlock(struct ubik_trans *at, struct kaentry *aentry)
317{
318 afs_int32 i, code;
319 afs_int32 to;
320 afs_int32 lo;
321 struct kaentry tentry;
322
323 i = NameHash(aentry->userID.name, aentry->userID.instance);
324 lo = 0;
325 for (to = ntohl(cheader.nameHash[i])(__builtin_constant_p(cheader.nameHash[i]) ? ((((__uint32_t)(
cheader.nameHash[i])) >> 24) | ((((__uint32_t)(cheader.
nameHash[i])) & (0xff << 16)) >> 8) | ((((__uint32_t
)(cheader.nameHash[i])) & (0xff << 8)) << 8) |
(((__uint32_t)(cheader.nameHash[i])) << 24)) : __bswap32_var
(cheader.nameHash[i]))
; to != NULLO0;
326 to = ntohl(tentry.next)(__builtin_constant_p(tentry.next) ? ((((__uint32_t)(tentry.next
)) >> 24) | ((((__uint32_t)(tentry.next)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(tentry.next)) & (0xff
<< 8)) << 8) | (((__uint32_t)(tentry.next)) <<
24)) : __bswap32_var(tentry.next))
) {
327 code = karead(at, to, (char *)&tentry, sizeof(kaentry));
328 if (code)
329 return KAIO(180482L);
330 /* see if the name matches */
331 if (!strcmp(aentry->userID.name, tentry.userID.name)
332 && !strcmp(aentry->userID.instance, tentry.userID.instance)) {
333 /* found it */
334 if (lo) { /* unthread from last block */
335 code =
336 kawrite(at, lo, (char *)&tentry.next, sizeof(afs_int32));
337 if (code)
338 return KAIO(180482L);
339 } else { /* unthread from hash table */
340 code = set_header_word(at, nameHash[i], tentry.next)kawrite ((at), ((char *)&(cheader.nameHash[i]) - (char *)
&cheader), ((cheader.nameHash[i] = (tentry.next)), (char *
)&(cheader.nameHash[i])), sizeof(afs_int32))
;
341 if (code)
342 return KAIO(180482L);
343 }
344 aentry->next = 0; /* just to be sure */
345 return 0;
346 }
347 lo = DOFFSET(to, &tentry, &tentry.next)((to)+(((char *)(&tentry.next)) - ((char *)(&tentry))
))
;
348 }
349 return KANOENT(180484L);
350}
351
352/* Given an index to the last block (or zero the first time) read the contents
353 of the next block and return its index. The last argument is a pointer to
354 an estimate of the number of remaining blocks to read out. The remaining
355 count is an estimate because it may include free blocks that are not
356 returned. If there are no more blocks remaining is zero and the returned
357 index is zero. A non-zero index indicates that tentry has been filled with
358 valid data. If an error is encountered the returned index is zero and the
359 remaining count is negative. */
360
361afs_int32
362NextBlock(struct ubik_trans *at, afs_int32 index, struct kaentry *tentry,
363 afs_int32 *remaining)
364{
365 int code;
366 afs_int32 last;
367
368 if (index == 0) /* get first one */
369 index = sizeof(cheader);
370 else {
371 if (!index_OK(index)) {
372 *remaining = -1; /* error */
373 return 0;
374 }
375 index += sizeof(kaentry);
376 }
377 /* now search for the first entry that isn't free */
378 for (last = 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))
; index < last; index += sizeof(kaentry)) {
379 code = karead(at, index, (char *)tentry, sizeof(kaentry));
380 if (code) {
381 *remaining = -1;
382 return 0;
383 }
384 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))
& (KAFFREE0x002 | KAFOLDKEYS0x010))) {
385 /* estimate remaining number of entries, not including this one */
386 *remaining = (last - index) / sizeof(kaentry) - 1;
387 return index;
388 }
389 }
390 *remaining = 0; /* no more entries */
391 return 0;
392}
393
394/* These are a collections of routines that deal with externally known keys.
395 They maintain a database of key version numbers and the corresponding key
396 and pointer to the user entry. */
397
398afs_int32
399ka_NewKey(struct ubik_trans *tt, afs_int32 tentryaddr,
400 struct kaentry *tentry, struct ktc_encryptionKey *key)
401{
402 struct kaOldKeys okeys; /* old keys block */
403 afs_int32 okeysaddr, nextaddr; /* offset of old keys block */
404 afs_int32 prevptr, nextprevptr;
405 int code, i;
406 Dateafs_uint32 now = time(0);
407 afs_int32 newkeyver; /* new key version number */
408 afs_int32 newtotalkeyentries = 0, oldtotalkeyentries = 0, keyentries;
409 int addednewkey = 0, modified;
410#ifdef AUTH_DBM_LOG
411 int foundcurrentkey = 0;
412#endif
413
414 es_Report("Newkey for %s.%s\n", tentry->userID.name,
415 tentry->userID.instance);
416
417 newkeyver = 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))
+ 1;
418 if ((newkeyver < 1) || (newkeyver >= MAXKAKVNO127))
419 newkeyver = 1;
420
421 /* An entry may have more than one oldkeys blocks. The entry
422 * points to the most current, but all the oldkeys blocks for an
423 * entry are not linked together. All oldkeys blocks for all
424 * entries are linked together off of the header. So we follow
425 * this link.
426 */
427 for (prevptr = 0, okeysaddr = 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))
; okeysaddr;
428 prevptr = nextprevptr, okeysaddr = nextaddr) {
429 /* foreacholdkeysblock */
430 /* Read the oldKeys block */
431 code = karead(tt, okeysaddr, (char *)&okeys, sizeof(okeys));
432 if (code)
433 return code;
434
435 nextaddr = ntohl(okeys.next)(__builtin_constant_p(okeys.next) ? ((((__uint32_t)(okeys.next
)) >> 24) | ((((__uint32_t)(okeys.next)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(okeys.next)) & (0xff <<
8)) << 8) | (((__uint32_t)(okeys.next)) << 24)) :
__bswap32_var(okeys.next))
;
436 nextprevptr = DOFFSET(okeysaddr, &okeys, &okeys.next)((okeysaddr)+(((char *)(&okeys.next)) - ((char *)(&okeys
))))
;
437
438 /* We only want oldkey blocks that belong to this entry */
439 if (ntohl(okeys.entry)(__builtin_constant_p(okeys.entry) ? ((((__uint32_t)(okeys.entry
)) >> 24) | ((((__uint32_t)(okeys.entry)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(okeys.entry)) & (0xff
<< 8)) << 8) | (((__uint32_t)(okeys.entry)) <<
24)) : __bswap32_var(okeys.entry))
!= tentryaddr)
440 continue;
441
442 modified = 0; /* This oldkeys block has not been modified */
443 keyentries = 0; /* Number of valid key entries in the block */
444 for (i = 0; i < NOLDKEYS((200 -3*sizeof(afs_int32))/sizeof(struct kaOldKey)); i++) {
445 /* foreachkey */
446 /* Keep count of number of entries found */
447 if (okeys.keys[i].superseded != 0) {
448 oldtotalkeyentries++;
449 }
450
451 /* If we find the entry that is not superseded, then supersede it */
452 if (ntohl(okeys.keys[i].superseded)(__builtin_constant_p(okeys.keys[i].superseded) ? ((((__uint32_t
)(okeys.keys[i].superseded)) >> 24) | ((((__uint32_t)(okeys
.keys[i].superseded)) & (0xff << 16)) >> 8) |
((((__uint32_t)(okeys.keys[i].superseded)) & (0xff <<
8)) << 8) | (((__uint32_t)(okeys.keys[i].superseded)) <<
24)) : __bswap32_var(okeys.keys[i].superseded))
== NEVERDATE037777777777) {
453 okeys.keys[i].superseded = 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))
;
454 modified = 1;
455#ifdef AUTH_DBM_LOG
456 if (foundcurrentkey) {
457 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Warning: Entry %s.%s contains more than one valid key: fixing\n"
, tentry->userID.name, tentry->userID.instance)); } while
(0)
458 ("Warning: Entry %s.%s contains more than one valid key: fixing\n",do { if ((0) <= LogLevel) (FSLog ("Warning: Entry %s.%s contains more than one valid key: fixing\n"
, tentry->userID.name, tentry->userID.instance)); } while
(0)
459 tentry->userID.name, tentry->userID.instance))do { if ((0) <= LogLevel) (FSLog ("Warning: Entry %s.%s contains more than one valid key: fixing\n"
, tentry->userID.name, tentry->userID.instance)); } while
(0)
;
460 }
461 foundcurrentkey = 1;
462#endif
463 }
464
465 /* If we find an oldkey of the same version or
466 * an old key that has expired, then delete it.
467 */
468 if ((ntohl(okeys.keys[i].version)(__builtin_constant_p(okeys.keys[i].version) ? ((((__uint32_t
)(okeys.keys[i].version)) >> 24) | ((((__uint32_t)(okeys
.keys[i].version)) & (0xff << 16)) >> 8) | ((
((__uint32_t)(okeys.keys[i].version)) & (0xff << 8)
) << 8) | (((__uint32_t)(okeys.keys[i].version)) <<
24)) : __bswap32_var(okeys.keys[i].version))
== newkeyver)
469 || ((now - ntohl(okeys.keys[i].superseded)(__builtin_constant_p(okeys.keys[i].superseded) ? ((((__uint32_t
)(okeys.keys[i].superseded)) >> 24) | ((((__uint32_t)(okeys
.keys[i].superseded)) & (0xff << 16)) >> 8) |
((((__uint32_t)(okeys.keys[i].superseded)) & (0xff <<
8)) << 8) | (((__uint32_t)(okeys.keys[i].superseded)) <<
24)) : __bswap32_var(okeys.keys[i].superseded))
> maxKeyLifetime))) {
470 okeys.keys[i].superseded = 0;
471 okeys.keys[i].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))
;
472 memset(&okeys.keys[i].key, 0,
473 sizeof(struct ktc_encryptionKey));
474 modified = 1;
475
476 es_Report("Dropped oldkey %d seconds old with kvno %d\n",
477 now - ntohl(okeys.keys[i].superseded)(__builtin_constant_p(okeys.keys[i].superseded) ? ((((__uint32_t
)(okeys.keys[i].superseded)) >> 24) | ((((__uint32_t)(okeys
.keys[i].superseded)) & (0xff << 16)) >> 8) |
((((__uint32_t)(okeys.keys[i].superseded)) & (0xff <<
8)) << 8) | (((__uint32_t)(okeys.keys[i].superseded)) <<
24)) : __bswap32_var(okeys.keys[i].superseded))
,
478 ntohl(okeys.keys[i].version)(__builtin_constant_p(okeys.keys[i].version) ? ((((__uint32_t
)(okeys.keys[i].version)) >> 24) | ((((__uint32_t)(okeys
.keys[i].version)) & (0xff << 16)) >> 8) | ((
((__uint32_t)(okeys.keys[i].version)) & (0xff << 8)
) << 8) | (((__uint32_t)(okeys.keys[i].version)) <<
24)) : __bswap32_var(okeys.keys[i].version))
);
479 }
480
481 /* Add our key here if its free */
482 if (!addednewkey && (okeys.keys[i].superseded == 0)) {
483 okeys.keys[i].version = htonl(newkeyver)(__builtin_constant_p(newkeyver) ? ((((__uint32_t)(newkeyver)
) >> 24) | ((((__uint32_t)(newkeyver)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(newkeyver)) & (0xff <<
8)) << 8) | (((__uint32_t)(newkeyver)) << 24)) :
__bswap32_var(newkeyver))
;
484 okeys.keys[i].superseded = 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))
;
485 memcpy(&okeys.keys[i].key, key,
486 sizeof(struct ktc_encryptionKey));
487 modified = 1;
488 addednewkey = okeysaddr;
489 }
490
491 /* Keep count of number of entries found */
492 if (okeys.keys[i].superseded != 0) {
493 keyentries++;
494 newtotalkeyentries++;
495 }
496 } /* foreachkey */
497
498 /* If we modified the block, write it out */
499 if (modified && keyentries) {
500 code = kawrite(tt, okeysaddr, (char *)&okeys, sizeof(okeys));
501 if (code)
502 return code;
503 }
504
505 /* If there are no more entries in this oldkeys block, delete it */
506 if (keyentries == 0) {
507 if (!prevptr) {
508 code = set_header_word(tt, kvnoPtr, okeys.next)kawrite ((tt), ((char *)&(cheader.kvnoPtr) - (char *)&
cheader), ((cheader.kvnoPtr = (okeys.next)), (char *)&(cheader
.kvnoPtr)), sizeof(afs_int32))
;
509 } else {
510 code =
511 kawrite(tt, prevptr, (char *)&okeys.next,
512 sizeof(afs_int32));
513 }
514 if (code)
515 return code;
516 code = FreeBlock(tt, okeysaddr);
517 if (code)
518 return code;
519
520 nextprevptr = prevptr; /* won't bump prevptr */
521 }
522 } /* foreacholdkeysblock */
523
524 /* If we could not add the key, create a new oldkeys block */
525 if (!addednewkey) {
526 /* Allocate and fill in an oldkeys block */
527 addednewkey = AllocBlock(tt, (struct kaentry *)&okeys);
528 if (!addednewkey)
529 return KACREATEFAIL(180483L);
530 okeys.flags = htonl(KAFOLDKEYS)(__builtin_constant_p(0x010) ? ((((__uint32_t)(0x010)) >>
24) | ((((__uint32_t)(0x010)) & (0xff << 16)) >>
8) | ((((__uint32_t)(0x010)) & (0xff << 8)) <<
8) | (((__uint32_t)(0x010)) << 24)) : __bswap32_var(0x010
))
;
531 okeys.entry = htonl(tentryaddr)(__builtin_constant_p(tentryaddr) ? ((((__uint32_t)(tentryaddr
)) >> 24) | ((((__uint32_t)(tentryaddr)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(tentryaddr)) & (0xff <<
8)) << 8) | (((__uint32_t)(tentryaddr)) << 24)) :
__bswap32_var(tentryaddr))
;
532 okeys.keys[0].version = htonl(newkeyver)(__builtin_constant_p(newkeyver) ? ((((__uint32_t)(newkeyver)
) >> 24) | ((((__uint32_t)(newkeyver)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(newkeyver)) & (0xff <<
8)) << 8) | (((__uint32_t)(newkeyver)) << 24)) :
__bswap32_var(newkeyver))
;
533 okeys.keys[0].superseded = 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))
;
534 memcpy(&okeys.keys[0].key, key, sizeof(struct ktc_encryptionKey));
535 newtotalkeyentries++;
536
537 /* Thread onto the header's chain of oldkeys */
538 okeys.next = cheader.kvnoPtr;
539 code = set_header_word(tt, kvnoPtr, htonl(addednewkey))kawrite ((tt), ((char *)&(cheader.kvnoPtr) - (char *)&
cheader), ((cheader.kvnoPtr = ((__builtin_constant_p(addednewkey
) ? ((((__uint32_t)(addednewkey)) >> 24) | ((((__uint32_t
)(addednewkey)) & (0xff << 16)) >> 8) | ((((__uint32_t
)(addednewkey)) & (0xff << 8)) << 8) | (((__uint32_t
)(addednewkey)) << 24)) : __bswap32_var(addednewkey))))
, (char *)&(cheader.kvnoPtr)), sizeof(afs_int32))
;
540 if (code)
541 return code;
542
543 /* Write the oldkeys block out */
544 code = kawrite(tt, addednewkey, (char *)&okeys, sizeof(okeys));
545 if (code)
546 return code;
547
548 es_Report("New oldkey block allocated at %d\n", addednewkey);
549 }
550#ifdef AUTH_DBM_LOG
551 if (oldtotalkeyentries != ntohl(tentry->misc.asServer.nOldKeys)(__builtin_constant_p(tentry->misc.asServer.nOldKeys) ? ((
((__uint32_t)(tentry->misc.asServer.nOldKeys)) >> 24
) | ((((__uint32_t)(tentry->misc.asServer.nOldKeys)) &
(0xff << 16)) >> 8) | ((((__uint32_t)(tentry->
misc.asServer.nOldKeys)) & (0xff << 8)) << 8)
| (((__uint32_t)(tentry->misc.asServer.nOldKeys)) <<
24)) : __bswap32_var(tentry->misc.asServer.nOldKeys))
) {
552 ViceLog(0,do { if ((0) <= LogLevel) (FSLog ("Warning: Entry %s.%s reports %d oldkeys, found %d: fixing\n"
, tentry->userID.name, tentry->userID.instance, (__builtin_constant_p
(tentry->misc.asServer.nOldKeys) ? ((((__uint32_t)(tentry->
misc.asServer.nOldKeys)) >> 24) | ((((__uint32_t)(tentry
->misc.asServer.nOldKeys)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry->misc.asServer.nOldKeys)) &
(0xff << 8)) << 8) | (((__uint32_t)(tentry->misc
.asServer.nOldKeys)) << 24)) : __bswap32_var(tentry->
misc.asServer.nOldKeys)), oldtotalkeyentries)); } while (0)
553 ("Warning: Entry %s.%s reports %d oldkeys, found %d: fixing\n",do { if ((0) <= LogLevel) (FSLog ("Warning: Entry %s.%s reports %d oldkeys, found %d: fixing\n"
, tentry->userID.name, tentry->userID.instance, (__builtin_constant_p
(tentry->misc.asServer.nOldKeys) ? ((((__uint32_t)(tentry->
misc.asServer.nOldKeys)) >> 24) | ((((__uint32_t)(tentry
->misc.asServer.nOldKeys)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry->misc.asServer.nOldKeys)) &
(0xff << 8)) << 8) | (((__uint32_t)(tentry->misc
.asServer.nOldKeys)) << 24)) : __bswap32_var(tentry->
misc.asServer.nOldKeys)), oldtotalkeyentries)); } while (0)
554 tentry->userID.name, tentry->userID.instance,do { if ((0) <= LogLevel) (FSLog ("Warning: Entry %s.%s reports %d oldkeys, found %d: fixing\n"
, tentry->userID.name, tentry->userID.instance, (__builtin_constant_p
(tentry->misc.asServer.nOldKeys) ? ((((__uint32_t)(tentry->
misc.asServer.nOldKeys)) >> 24) | ((((__uint32_t)(tentry
->misc.asServer.nOldKeys)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry->misc.asServer.nOldKeys)) &
(0xff << 8)) << 8) | (((__uint32_t)(tentry->misc
.asServer.nOldKeys)) << 24)) : __bswap32_var(tentry->
misc.asServer.nOldKeys)), oldtotalkeyentries)); } while (0)
555 ntohl(tentry->misc.asServer.nOldKeys), oldtotalkeyentries))do { if ((0) <= LogLevel) (FSLog ("Warning: Entry %s.%s reports %d oldkeys, found %d: fixing\n"
, tentry->userID.name, tentry->userID.instance, (__builtin_constant_p
(tentry->misc.asServer.nOldKeys) ? ((((__uint32_t)(tentry->
misc.asServer.nOldKeys)) >> 24) | ((((__uint32_t)(tentry
->misc.asServer.nOldKeys)) & (0xff << 16)) >>
8) | ((((__uint32_t)(tentry->misc.asServer.nOldKeys)) &
(0xff << 8)) << 8) | (((__uint32_t)(tentry->misc
.asServer.nOldKeys)) << 24)) : __bswap32_var(tentry->
misc.asServer.nOldKeys)), oldtotalkeyentries)); } while (0)
;
556 }
557#endif
558
559 /* Update the tentry. We rely on caller to write it out */
560 tentry->misc.asServer.oldKeys = htonl(addednewkey)(__builtin_constant_p(addednewkey) ? ((((__uint32_t)(addednewkey
)) >> 24) | ((((__uint32_t)(addednewkey)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(addednewkey)) & (0xff
<< 8)) << 8) | (((__uint32_t)(addednewkey)) <<
24)) : __bswap32_var(addednewkey))
;
561 tentry->misc.asServer.nOldKeys = htonl(newtotalkeyentries)(__builtin_constant_p(newtotalkeyentries) ? ((((__uint32_t)(newtotalkeyentries
)) >> 24) | ((((__uint32_t)(newtotalkeyentries)) & (
0xff << 16)) >> 8) | ((((__uint32_t)(newtotalkeyentries
)) & (0xff << 8)) << 8) | (((__uint32_t)(newtotalkeyentries
)) << 24)) : __bswap32_var(newtotalkeyentries))
;
562 tentry->key_version = htonl(newkeyver)(__builtin_constant_p(newkeyver) ? ((((__uint32_t)(newkeyver)
) >> 24) | ((((__uint32_t)(newkeyver)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(newkeyver)) & (0xff <<
8)) << 8) | (((__uint32_t)(newkeyver)) << 24)) :
__bswap32_var(newkeyver))
;
563 memcpy(&tentry->key, key, sizeof(tentry->key));
564
565 /* invalidate key caches everywhere */
566 code = inc_header_word(tt, specialKeysVersion)kawrite ((tt), ((char *)&(cheader.specialKeysVersion) - (
char *)&cheader), ((cheader.specialKeysVersion = ((__builtin_constant_p
((__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))
+1) ? ((((__uint32_t)((__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
))+1)) >> 24) | ((((__uint32_t)((__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))+1)) & (0xff << 16)) >>
8) | ((((__uint32_t)((__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
))+1)) & (0xff << 8)) << 8) | (((__uint32_t)(
(__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))
+1)) << 24)) : __bswap32_var((__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))+1)))), (char *)&(cheader.specialKeysVersion
)), sizeof(afs_int32))
;
567 if (code)
568 return code;
569
570 es_Report("New kvno is %d, now are %d oldkeys\n", newkeyver,
571 newtotalkeyentries);
572 return 0;
573}
574
575afs_int32
576ka_DelKey(struct ubik_trans *tt, afs_int32 tentryaddr,
577 struct kaentry *tentry)
578{
579 int code;
580 struct kaOldKeys okeys; /* old keys block */
581 afs_int32 okeysaddr, nextaddr; /* offset of old keys block */
582 afs_int32 prevptr = 0;
583
584 es_Report("DelKey for %s.%s\n", tentry->userID.name,
585 tentry->userID.instance);
586
587 /* An entry may have more than one oldkeys blocks. The entry
588 * points to the most current, but all the oldkeys blocks for an
589 * entry are not linked together. All oldkeys blocks for all
590 * entries are linked together off of the header. So we follow
591 * this link.
592 */
593 for (okeysaddr = 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))
; okeysaddr; okeysaddr = nextaddr) {
594 /* foreacholdkeysblock */
595 /* Read the oldKeys block */
596 code = karead(tt, okeysaddr, (char *)&okeys, sizeof(okeys));
597 if (code)
598 return code;
599 nextaddr = ntohl(okeys.next)(__builtin_constant_p(okeys.next) ? ((((__uint32_t)(okeys.next
)) >> 24) | ((((__uint32_t)(okeys.next)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(okeys.next)) & (0xff <<
8)) << 8) | (((__uint32_t)(okeys.next)) << 24)) :
__bswap32_var(okeys.next))
;
600
601 /* We only want oldkey blocks that belong to this entry */
602 if (ntohl(okeys.entry)(__builtin_constant_p(okeys.entry) ? ((((__uint32_t)(okeys.entry
)) >> 24) | ((((__uint32_t)(okeys.entry)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(okeys.entry)) & (0xff
<< 8)) << 8) | (((__uint32_t)(okeys.entry)) <<
24)) : __bswap32_var(okeys.entry))
!= tentryaddr) {
603 prevptr = DOFFSET(okeysaddr, &okeys, &okeys.next)((okeysaddr)+(((char *)(&okeys.next)) - ((char *)(&okeys
))))
;
604 continue;
605 }
606
607 /* Delete the oldkeys block */
608 if (prevptr) {
609 code =
610 kawrite(tt, prevptr, (char *)&okeys.next, sizeof(afs_int32));
611 } else {
612 code = set_header_word(tt, kvnoPtr, okeys.next)kawrite ((tt), ((char *)&(cheader.kvnoPtr) - (char *)&
cheader), ((cheader.kvnoPtr = (okeys.next)), (char *)&(cheader
.kvnoPtr)), sizeof(afs_int32))
;
613 }
614 if (code)
615 return code;
616 code = FreeBlock(tt, okeysaddr);
617 if (code)
618 return code;
619 } /* foreacholdkeysblock */
620
621 /* Update the tentry. We rely on caller to write it out */
622 tentry->misc.asServer.oldKeys = 0;
623 tentry->misc.asServer.nOldKeys = 0;
624
625 /* invalidate key caches everywhere */
626 code = inc_header_word(tt, specialKeysVersion)kawrite ((tt), ((char *)&(cheader.specialKeysVersion) - (
char *)&cheader), ((cheader.specialKeysVersion = ((__builtin_constant_p
((__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))
+1) ? ((((__uint32_t)((__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
))+1)) >> 24) | ((((__uint32_t)((__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))+1)) & (0xff << 16)) >>
8) | ((((__uint32_t)((__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
))+1)) & (0xff << 8)) << 8) | (((__uint32_t)(
(__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))
+1)) << 24)) : __bswap32_var((__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))+1)))), (char *)&(cheader.specialKeysVersion
)), sizeof(afs_int32))
;
627 if (code)
628 return code;
629
630 return 0;
631}
632
633void
634ka_debugKeyCache(struct ka_debugInfo *info)
635{
636 int i;
637
638 /* cheader_lock no longer exists */
639 memset(&info->cheader_lock, 0, sizeof(info->cheader_lock));
640 memcpy(&info->keycache_lock, &keycache_lock, sizeof(info->keycache_lock));
641
642 info->kcVersion = keyCacheVersion;
643 info->kcSize = maxCachedKeys;
644 info->kcUsed = 0;
645 for (i = 0; i < maxCachedKeys; i++) {
646 if (keyCache[i].used) {
647 if (info->kcUsed < KADEBUGKCINFOSIZE25) {
648 int j = info->kcUsed;
649 char principal[sizeof(keyCache[0].name) +
650 sizeof(keyCache[0].inst)];
651
652 info->kcInfo[j].used = keyCache[i].superseded;
653 info->kcInfo[j].kvno = keyCache[i].kvno;
654 info->kcInfo[j].primary =
655 (keyCache[i].superseded == NEVERDATE037777777777);
656 info->kcInfo[j].keycksum = 0;
657#if DEBUG_KEY_CACHE
658 {
659 int k;
660 for (k = 0; k < sizeof(struct ktc_encryptionKey); k++)
661 info->kcInfo[j].keycksum +=
662 ((char *)&keyCache[i].key)[k];
663 }
664#endif
665 strcpy(principal, keyCache[i].name);
666 strcat(principal, ".");
667 strcat(principal, keyCache[i].inst);
668 strncpy(info->kcInfo[j].principal, principal,
669 sizeof(info->kcInfo[0].principal));
670 }
671 info->kcUsed++;
672 }
673 }
674}
675
676/* Add a key to the key cache, expanding it if necessary. */
677
678void
679ka_Encache(char *name, char *inst, afs_int32 kvno,
680 struct ktc_encryptionKey *key, Dateafs_uint32 superseded)
681{
682 int i;
683
684 ObtainWriteLock(&keycache_lock)do { ; if (!(&keycache_lock)->excl_locked && !
(&keycache_lock)->readers_reading) (&keycache_lock
) -> excl_locked = 2; else Afs_Lock_Obtain(&keycache_lock
, 2); ; } while (0)
;
685 if (keyCacheVersion != 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))
) {
686 for (i = 0; i < maxCachedKeys; i++)
687 keyCache[i].used = 0;
688 }
689
690 for (i = 0; i < maxCachedKeys; i++)
691 if (keyCache[i].used == 0) {
692 encache:
693 keyCache[i].kvno = kvno;
694 strncpy(keyCache[i].name, name, sizeof(keyCache[i].name));
695 strncpy(keyCache[i].inst, inst, sizeof(keyCache[i].inst));
696 keyCacheVersion = 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))
;
697 memcpy(&keyCache[i].key, key, sizeof(*key));
698 keyCache[i].superseded = superseded;
699 keyCache[i].used = time(0);
700
701 ReleaseWriteLock(&keycache_lock)do { ; (&keycache_lock)->excl_locked &= ~2; if ((&
keycache_lock)->wait_states) Afs_Lock_ReleaseR(&keycache_lock
); ; } while (0)
;
702 return;
703 }
704 /* i == maxCachedKeys */
705 keyCache =
706 (struct cachedKey *)realloc(keyCache,
707 (maxCachedKeys *=
708 2) * sizeof(struct cachedKey));
709 if (keyCache == 0) {
710 es_Report("Can't realloc keyCache! out of memory?");
711 exit(123);
712 }
713
714 {
715 int j = i; /* initialize new storage */
716 while (j < maxCachedKeys)
717 keyCache[j++].used = 0;
718 }
719 goto encache;
720}
721
722/* Look up the key given a principal and a kvno. This is called by GetTicket
723 to get the decryption key for the authenticating ticket. It is also called
724 by the rxkad security module to decrypt admin tickets. The rxkad call is
725 with tt==0, since Rx can't call Ubik. */
726
727afs_int32
728ka_LookupKvno(struct ubik_trans *tt, char *name, char *inst, afs_int32 kvno,
729 struct ktc_encryptionKey *key)
730{
731 int i;
732 int code = 0;
733 afs_int32 to;
734 struct kaentry tentry;
735 afs_int32 ko;
736 struct kaOldKeys okeys;
737
738 ObtainReadLock(&keycache_lock)do { ; if (!((&keycache_lock)->excl_locked & 2) &&
!(&keycache_lock)->wait_states) (&keycache_lock) ->
readers_reading++; else Afs_Lock_Obtain(&keycache_lock, 1
); ; } while (0)
;
739 if (keyCacheVersion != 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))
)
740 code = KAKEYCACHEINVALID(180506L);
741 else {
742 for (i = 0; i < maxCachedKeys; i++) {
743 if (keyCache[i].used) { /* zero used date means invalid */
744 if ((keyCache[i].kvno == kvno)
745 && (strcmp(keyCache[i].name, name) == 0)
746 && (strcmp(keyCache[i].inst, inst) == 0)) {
747 memcpy(key, &keyCache[i].key, sizeof(*key));
748 keyCache[i].used = time(0);
749 ReleaseReadLock(&keycache_lock)do { ; if (!--(&keycache_lock)->readers_reading &&
(&keycache_lock)->wait_states) Afs_Lock_ReleaseW(&
keycache_lock) ; ; } while (0)
;
750 return 0;
751 }
752 }
753 }
754 code = KAUNKNOWNKEY(180505L);
755 }
756 ReleaseReadLock(&keycache_lock)do { ; if (!--(&keycache_lock)->readers_reading &&
(&keycache_lock)->wait_states) Afs_Lock_ReleaseW(&
keycache_lock) ; ; } while (0)
;
757 if (!tt)
758 return code;
759
760 /* we missed in the cache so need to look in the Ubik database */
761 code = FindBlock(tt, name, inst, &to, &tentry);
762 if (code)
763 return code;
764 if (to == 0)
765 return KANOENT(180484L);
766
767 /* first check the current key */
768 if (tentry.key_version == htonl(kvno)(__builtin_constant_p(kvno) ? ((((__uint32_t)(kvno)) >>
24) | ((((__uint32_t)(kvno)) & (0xff << 16)) >>
8) | ((((__uint32_t)(kvno)) & (0xff << 8)) <<
8) | (((__uint32_t)(kvno)) << 24)) : __bswap32_var(kvno
))
) {
769 memcpy(key, &tentry.key, sizeof(*key));
770 ka_Encache(name, inst, kvno, key, NEVERDATE037777777777);
771 return 0;
772 }
773 for (ko = 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))
; ko; ko = ntohl(okeys.next)(__builtin_constant_p(okeys.next) ? ((((__uint32_t)(okeys.next
)) >> 24) | ((((__uint32_t)(okeys.next)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(okeys.next)) & (0xff <<
8)) << 8) | (((__uint32_t)(okeys.next)) << 24)) :
__bswap32_var(okeys.next))
) {
774 code = karead(tt, ko, (char *)&okeys, sizeof(okeys));
775 if (code)
776 return KAIO(180482L);
777 if (ntohl(okeys.entry)(__builtin_constant_p(okeys.entry) ? ((((__uint32_t)(okeys.entry
)) >> 24) | ((((__uint32_t)(okeys.entry)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(okeys.entry)) & (0xff
<< 8)) << 8) | (((__uint32_t)(okeys.entry)) <<
24)) : __bswap32_var(okeys.entry))
== to)
778 for (i = 0; i < NOLDKEYS((200 -3*sizeof(afs_int32))/sizeof(struct kaOldKey)); i++)
779 if (okeys.keys[i].superseded
780 && (ntohl(okeys.keys[i].version)(__builtin_constant_p(okeys.keys[i].version) ? ((((__uint32_t
)(okeys.keys[i].version)) >> 24) | ((((__uint32_t)(okeys
.keys[i].version)) & (0xff << 16)) >> 8) | ((
((__uint32_t)(okeys.keys[i].version)) & (0xff << 8)
) << 8) | (((__uint32_t)(okeys.keys[i].version)) <<
24)) : __bswap32_var(okeys.keys[i].version))
== kvno)) {
781 memcpy(key, &okeys.keys[i].key, sizeof(*key));
782 ka_Encache(name, inst, kvno, key,
783 ntohl(okeys.keys[i].superseded)(__builtin_constant_p(okeys.keys[i].superseded) ? ((((__uint32_t
)(okeys.keys[i].superseded)) >> 24) | ((((__uint32_t)(okeys
.keys[i].superseded)) & (0xff << 16)) >> 8) |
((((__uint32_t)(okeys.keys[i].superseded)) & (0xff <<
8)) << 8) | (((__uint32_t)(okeys.keys[i].superseded)) <<
24)) : __bswap32_var(okeys.keys[i].superseded))
);
784 return 0;
785 }
786 }
787 return KAUNKNOWNKEY(180505L);
788}
789
790/* Look up the primary key and key version for a principal. */
791
792afs_int32
793ka_LookupKey(struct ubik_trans *tt,
794 char *name,
795 char *inst,
796 afs_int32 *kvno, /* returned */
797 struct ktc_encryptionKey *key) /* copied out */
798{
799 int i;
800 afs_int32 to;
801 struct kaentry tentry;
802 afs_int32 code = 0;
803
804 ObtainReadLock(&keycache_lock)do { ; if (!((&keycache_lock)->excl_locked & 2) &&
!(&keycache_lock)->wait_states) (&keycache_lock) ->
readers_reading++; else Afs_Lock_Obtain(&keycache_lock, 1
); ; } while (0)
;
805 if (keyCacheVersion != 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))
)
806 code = KAKEYCACHEINVALID(180506L);
807 else {
808 for (i = 0; i < maxCachedKeys; i++) {
809 if (keyCache[i].used) { /* zero used date means invalid */
810 if ((keyCache[i].superseded == NEVERDATE037777777777)
811 && (strcmp(keyCache[i].name, name) == 0)
812 && (strcmp(keyCache[i].inst, inst) == 0)) {
813 memcpy(key, &keyCache[i].key, sizeof(*key));
814 *kvno = keyCache[i].kvno;
815 keyCache[i].used = time(0);
816 ReleaseReadLock(&keycache_lock)do { ; if (!--(&keycache_lock)->readers_reading &&
(&keycache_lock)->wait_states) Afs_Lock_ReleaseW(&
keycache_lock) ; ; } while (0)
;
817 return 0;
818 }
819 }
820 }
821 code = KAUNKNOWNKEY(180505L);
822 }
823 ReleaseReadLock(&keycache_lock)do { ; if (!--(&keycache_lock)->readers_reading &&
(&keycache_lock)->wait_states) Afs_Lock_ReleaseW(&
keycache_lock) ; ; } while (0)
;
824 if (!tt)
825 return code;
826
827 /* we missed in the cache so need to look in the Ubik database */
828 code = FindBlock(tt, name, inst, &to, &tentry);
829 if (code)
830 return code;
831 if (to == 0)
832 return KANOENT(180484L);
833 memcpy(key, &tentry.key, sizeof(*key));
834 *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
))
;
835 ka_Encache(name, inst, *kvno, key, NEVERDATE037777777777);
836 return 0;
837}
838
839/* This is, hopefully a temporary mechanism to fill the cache will all keys
840 since filling cache misses during rxkad challenge responses will deadlock if
841 Ubik needs to use Rx. */
842
843afs_int32
844ka_FillKeyCache(struct ubik_trans *tt)
845{
846 int nfound;
847 afs_int32 ko;
848 int code;
849 int i;
850 struct ktc_encryptionKey k;
851 struct kaOldKeys okeys;
852 struct kaentry tentry;
853
854 /* this is a little marginal, but... */
855 if (keyCacheVersion == 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))
)
856 return 0;
857
858 nfound = 0;
859 for (ko = 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))
; ko; ko = ntohl(okeys.next)(__builtin_constant_p(okeys.next) ? ((((__uint32_t)(okeys.next
)) >> 24) | ((((__uint32_t)(okeys.next)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(okeys.next)) & (0xff <<
8)) << 8) | (((__uint32_t)(okeys.next)) << 24)) :
__bswap32_var(okeys.next))
) {
860 code = karead(tt, ko, (char *)&okeys, sizeof(okeys));
861 if (code)
862 return KAIO(180482L);
863 /* get name & instance */
864 code =
865 karead(tt, ntohl(okeys.entry)(__builtin_constant_p(okeys.entry) ? ((((__uint32_t)(okeys.entry
)) >> 24) | ((((__uint32_t)(okeys.entry)) & (0xff <<
16)) >> 8) | ((((__uint32_t)(okeys.entry)) & (0xff
<< 8)) << 8) | (((__uint32_t)(okeys.entry)) <<
24)) : __bswap32_var(okeys.entry))
, (char *)&tentry, sizeof(tentry));
866 if (code)
867 return KAIO(180482L);
868
869 /* get all the old keys in this block */
870 for (i = 0; i < NOLDKEYS((200 -3*sizeof(afs_int32))/sizeof(struct kaOldKey)); i++)
871 if (okeys.keys[i].superseded) {
872 code =
873 ka_LookupKvno(tt, tentry.userID.name,
874 tentry.userID.instance,
875 ntohl(okeys.keys[i].version)(__builtin_constant_p(okeys.keys[i].version) ? ((((__uint32_t
)(okeys.keys[i].version)) >> 24) | ((((__uint32_t)(okeys
.keys[i].version)) & (0xff << 16)) >> 8) | ((
((__uint32_t)(okeys.keys[i].version)) & (0xff << 8)
) << 8) | (((__uint32_t)(okeys.keys[i].version)) <<
24)) : __bswap32_var(okeys.keys[i].version))
, &k);
876 if (code)
877 return code;
878 }
879 }
880 if (++nfound > maxCachedKeys)
881 return KADATABASEINCONSISTENT(180480L);
882 return 0;
883}
884
885afs_int32
886update_admin_count(struct ubik_trans *tt, int delta)
887{
888 afs_int32 to;
889 afs_int32 code;
890
891 cheader.admin_accounts = htonl(ntohl(cheader.admin_accounts) + delta)(__builtin_constant_p((__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)) + delta
) ? ((((__uint32_t)((__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)) + delta
)) >> 24) | ((((__uint32_t)((__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)) + delta
)) & (0xff << 16)) >> 8) | ((((__uint32_t)((__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
)) + delta)) & (0xff << 8)) << 8) | (((__uint32_t
)((__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)) + delta)) <<
24)) : __bswap32_var((__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)) + delta
))
;
892 to = DOFFSET(0, &cheader, &cheader.admin_accounts)((0)+(((char *)(&cheader.admin_accounts)) - ((char *)(&
cheader))))
;
893 code =
894 kawrite(tt, to, (char *)&cheader.admin_accounts, sizeof(afs_int32));
895 if (code)
896 return KAIO(180482L);
897 return 0;
898}
899
900static int
901index_OK(afs_int32 index)
902{
903 if ((index < sizeof(cheader)) || (index >= 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))
)
904 || ((index - sizeof(cheader)) % sizeof(kaentry) != 0))
905 return 0;
906 return 1;
907}
908
909#define LEGALCHARS".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" ".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
910
911int
912name_instance_legal(char *name, char *instance)
913{
914 int code;
915
916/* No string checks apply anymore. The international people want to use full 8
917 bit ascii without problems. */
918#if 1
919 code = (strlen(name) < MAXKTCNAMELEN64)
920 && (strlen(instance) < MAXKTCNAMELEN64);
921#else
922 map = LEGALCHARS".ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; /* permitted chars, instance allows <period> */
923 code = (strlen(name) > 0) && string_legal(instance, map)
924 && string_legal(name, map + 1);
925#endif
926 if (!code)
927 dynamic_statistics.string_checks++;
928 return code;
929}
930
931#if 0
932static int
933string_legal(char *str, char *map)
934{
935 int slen;
936
937 slen = strlen(str);
938 if (slen >= MAXKTCNAMELEN64)
939 return 0; /* with trailing null must fit in data base */
940 return (slen == strspn(str, map)); /* strspn returns length(str) if all chars in map */
941}
942#endif
943