2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afs/param.h>
14 /* Need rx/rx.h to get working assert(), used by LOCK_GLOBAL_MUTEX */
18 #include <afs/pthread_glock.h>
19 #include <afs/afsutil.h>
21 #include "cellconfig.h"
25 /* called during opening of config file */
27 _afsconf_IntGetKeys(struct afsconf_dir *adir)
31 struct afsconf_keys *tstr;
35 /* NT client config dir has no KeyFile; don't risk attempting open
36 * because there might be a random file of this name if dir is shared.
38 if (_afsconf_IsClientConfigDirectory(adir->name)) {
39 adir->keystr = ((struct afsconf_keys *)
40 malloc(sizeof(struct afsconf_keys)));
41 adir->keystr->nkeys = 0;
44 #endif /* AFS_NT40_ENV */
47 /* compute the key name and other setup */
48 strcompose(tbuffer, 256, adir->name, "/", AFSDIR_KEY_FILE, NULL);
49 tstr = (struct afsconf_keys *)malloc(sizeof(struct afsconf_keys));
53 fd = open(tbuffer, O_RDONLY);
59 code = read(fd, tstr, sizeof(struct afsconf_keys));
61 if (code < sizeof(afs_int32)) {
67 /* convert key structure to host order */
68 tstr->nkeys = ntohl(tstr->nkeys);
70 if (code < sizeof(afs_int32) + (tstr->nkeys*sizeof(struct afsconf_key))) {
76 for (fd = 0; fd < tstr->nkeys; fd++)
77 tstr->key[fd].kvno = ntohl(tstr->key[fd].kvno);
83 /* get keys structure */
85 afsconf_GetKeys(struct afsconf_dir *adir, struct afsconf_keys *astr)
90 code = _afsconf_Check(adir);
93 return AFSCONF_FAILURE;
95 memcpy(astr, adir->keystr, sizeof(struct afsconf_keys));
102 afsconf_GetLatestKey(struct afsconf_dir * adir, afs_int32 * avno,
103 struct ktc_encryptionKey *akey)
107 struct afsconf_key *tk;
109 struct afsconf_key *bestk;
113 code = _afsconf_Check(adir);
116 return AFSCONF_FAILURE;
118 maxa = adir->keystr->nkeys;
120 best = -1; /* highest kvno we've seen yet */
121 bestk = (struct afsconf_key *)0; /* ptr to structure providing best */
122 for (tk = adir->keystr->key, i = 0; i < maxa; i++, tk++) {
124 continue; /* skip bcrypt keys */
125 if (tk->kvno > best) {
130 if (bestk) { /* found any */
132 memcpy(akey, bestk->key, 8); /* copy out latest key */
134 *avno = bestk->kvno; /* and kvno to caller */
139 return AFSCONF_NOTFOUND; /* didn't find any keys */
142 /* get a particular key */
144 afsconf_GetKey(void *rock, int avno, struct ktc_encryptionKey *akey)
146 struct afsconf_dir *adir = (struct afsconf_dir *) rock;
148 struct afsconf_key *tk;
152 code = _afsconf_Check(adir);
155 return AFSCONF_FAILURE;
157 maxa = adir->keystr->nkeys;
159 for (tk = adir->keystr->key, i = 0; i < maxa; i++, tk++) {
160 if (tk->kvno == avno) {
161 memcpy(akey, tk->key, 8);
168 return AFSCONF_NOTFOUND;
171 /* save the key structure in the appropriate file */
173 SaveKeys(struct afsconf_dir *adir)
175 struct afsconf_keys tkeys;
180 memcpy(&tkeys, adir->keystr, sizeof(struct afsconf_keys));
182 /* convert it to net byte order */
183 for (i = 0; i < tkeys.nkeys; i++)
184 tkeys.key[i].kvno = htonl(tkeys.key[i].kvno);
185 tkeys.nkeys = htonl(tkeys.nkeys);
187 /* rewrite keys file */
188 strcompose(tbuffer, 256, adir->name, "/", AFSDIR_KEY_FILE, NULL);
189 fd = open(tbuffer, O_RDWR | O_CREAT | O_TRUNC, 0600);
191 return AFSCONF_FAILURE;
192 i = write(fd, &tkeys, sizeof(tkeys));
193 if (i != sizeof(tkeys)) {
195 return AFSCONF_FAILURE;
198 return AFSCONF_FAILURE;
203 afsconf_AddKey(struct afsconf_dir *adir, afs_int32 akvno, char akey[8],
206 struct afsconf_keys *tk;
207 struct afsconf_key *tkey;
215 if (akvno < 0 || akvno > 255) {
221 for (i = 0, tkey = tk->key; i < tk->nkeys; i++, tkey++) {
222 if (tkey->kvno == akvno) {
225 return AFSCONF_KEYINUSE;
232 if (tk->nkeys >= AFSCONF_MAXKEYS) {
236 tkey = &tk->key[tk->nkeys++];
239 memcpy(tkey->key, akey, 8);
241 _afsconf_Touch(adir);
246 /* this proc works by sliding the other guys down, rather than using a funny
247 kvno value, so that callers can count on getting a good key in key[0].
250 afsconf_DeleteKey(struct afsconf_dir *adir, afs_int32 akvno)
252 struct afsconf_keys *tk;
253 struct afsconf_key *tkey;
260 for (i = 0, tkey = tk->key; i < tk->nkeys; i++, tkey++) {
261 if (tkey->kvno == akvno) {
268 return AFSCONF_NOTFOUND;
271 /* otherwise slide the others down. i and tkey point at the guy to delete */
272 for (; i < tk->nkeys - 1; i++, tkey++) {
273 tkey->kvno = (tkey + 1)->kvno;
274 memcpy(tkey->key, (tkey + 1)->key, 8);
278 _afsconf_Touch(adir);