No empty .Rs/.Re
[netbsd-mini2440.git] / crypto / dist / heimdal / lib / otp / otp_db.c
blobfdc4911f3fe461fb8c7ff5314a2f1ce5c7af49a9
1 /*
2 * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 __RCSID("$Heimdal: otp_db.c 12050 2003-04-16 16:28:03Z lha $"
37 "$NetBSD$");
38 #endif
40 #include "otp_locl.h"
42 #if !defined(HAVE_NDBM) && !defined(HAVE_DB_NDBM)
43 #include "ndbm_wrap.h"
44 #endif
46 #define RETRIES 5
48 void *
49 otp_db_open (void)
51 int lock;
52 int i;
53 void *ret;
55 for(i = 0; i < RETRIES; ++i) {
56 struct stat statbuf;
58 lock = open (OTP_DB_LOCK, O_WRONLY | O_CREAT | O_EXCL, 0666);
59 if (lock >= 0) {
60 close(lock);
61 break;
63 if (stat (OTP_DB_LOCK, &statbuf) == 0) {
64 if (time(NULL) - statbuf.st_mtime > OTP_DB_TIMEOUT)
65 unlink (OTP_DB_LOCK);
66 else
67 sleep (1);
70 if (i == RETRIES)
71 return NULL;
72 ret = dbm_open (OTP_DB, O_RDWR | O_CREAT, 0600);
73 if (ret == NULL)
74 unlink (OTP_DB_LOCK);
75 return ret;
78 void
79 otp_db_close (void *dbm)
81 dbm_close ((DBM *)dbm);
82 unlink (OTP_DB_LOCK);
86 * Remove this entry from the database.
87 * return 0 if ok.
90 int
91 otp_delete (void *v, OtpContext *ctx)
93 DBM *dbm = (DBM *)v;
94 datum key;
96 key.dsize = strlen(ctx->user);
97 key.dptr = ctx->user;
99 return dbm_delete(dbm, key);
103 * Read this entry from the database and lock it if lockp.
106 static int
107 otp_get_internal (void *v, OtpContext *ctx, int lockp)
109 DBM *dbm = (DBM *)v;
110 datum dat, key;
111 char *p;
112 time_t now, then;
114 key.dsize = strlen(ctx->user);
115 key.dptr = ctx->user;
117 dat = dbm_fetch (dbm, key);
118 if (dat.dptr == NULL) {
119 ctx->err = "Entry not found";
120 return -1;
122 p = dat.dptr;
124 memcpy (&then, p, sizeof(then));
125 ctx->lock_time = then;
126 if (lockp) {
127 time(&now);
128 if (then && now - then < OTP_USER_TIMEOUT) {
129 ctx->err = "Entry locked";
130 return -1;
132 memcpy (p, &now, sizeof(now));
134 p += sizeof(now);
135 ctx->alg = otp_find_alg (p);
136 if (ctx->alg == NULL) {
137 ctx->err = "Bad algorithm";
138 return -1;
140 p += strlen(p) + 1;
142 unsigned char *up = (unsigned char *)p;
143 ctx->n = (up[0] << 24) | (up[1] << 16) | (up[2] << 8) | up[3];
145 p += 4;
146 memcpy (ctx->key, p, OTPKEYSIZE);
147 p += OTPKEYSIZE;
148 strlcpy (ctx->seed, p, sizeof(ctx->seed));
149 if (lockp)
150 return dbm_store (dbm, key, dat, DBM_REPLACE);
151 else
152 return 0;
156 * Get and lock.
160 otp_get (void *v, OtpContext *ctx)
162 return otp_get_internal (v, ctx, 1);
166 * Get and don't lock.
170 otp_simple_get (void *v, OtpContext *ctx)
172 return otp_get_internal (v, ctx, 0);
176 * Write this entry to the database.
180 otp_put (void *v, OtpContext *ctx)
182 DBM *dbm = (DBM *)v;
183 datum dat, key;
184 char buf[1024], *p;
185 time_t zero = 0;
186 size_t len, rem;
188 key.dsize = strlen(ctx->user);
189 key.dptr = ctx->user;
191 p = buf;
192 rem = sizeof(buf);
194 if (rem < sizeof(zero))
195 return -1;
196 memcpy (p, &zero, sizeof(zero));
197 p += sizeof(zero);
198 rem -= sizeof(zero);
199 len = strlen(ctx->alg->name) + 1;
201 if (rem < len)
202 return -1;
203 strlcpy (p, ctx->alg->name, rem);
204 p += len;
205 rem -= len;
207 if (rem < 4)
208 return -1;
210 unsigned char *up = (unsigned char *)p;
211 *up++ = (ctx->n >> 24) & 0xFF;
212 *up++ = (ctx->n >> 16) & 0xFF;
213 *up++ = (ctx->n >> 8) & 0xFF;
214 *up++ = (ctx->n >> 0) & 0xFF;
216 p += 4;
217 rem -= 4;
219 if (rem < OTPKEYSIZE)
220 return -1;
221 memcpy (p, ctx->key, OTPKEYSIZE);
222 p += OTPKEYSIZE;
223 rem -= OTPKEYSIZE;
225 len = strlen(ctx->seed) + 1;
226 if (rem < len)
227 return -1;
228 strlcpy (p, ctx->seed, rem);
229 p += len;
230 rem -= len;
231 dat.dptr = buf;
232 dat.dsize = p - buf;
233 return dbm_store (dbm, key, dat, DBM_REPLACE);