Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / kauth / kaauxdb.c
blob77ae9bfa4a62d4807cd5cc376bc8b90083056e9c
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
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 */
11 * ALL RIGHTS RESERVED
14 #include <afsconfig.h>
15 #include <afs/param.h>
18 #ifdef AFS_NT40_ENV
19 #include <io.h>
20 #else
21 #include <sys/file.h>
22 #endif
23 #ifdef HAVE_FCNTL_H
24 #include <fcntl.h>
25 #endif
26 #include <string.h>
27 #include <rx/rxkad.h>
28 #define UBIK_INTERNALS
29 #include <ubik.h>
30 #include "ubik_int.h"
31 #include "kauth.h"
32 #include "kaserver.h"
35 static int fd = 0;
37 /* Open the auxiliary database file containing failed authentication
38 * counters, and the times at which the last failures occurred.
39 * Nothing fancy.
41 int
42 kaux_opendb(char *path)
44 char dbpathname[1024];
45 static char dbname[] = "auxdb";
47 if (strlen(path) < 1024 - strlen(dbname)) { /* bullet-proofing */
49 strcpy(dbpathname, path);
50 strcat(dbpathname, dbname);
52 fd = open(dbpathname, O_CREAT | O_RDWR, 0600);
53 if (fd < 0)
54 perror(dbpathname);
57 return fd;
60 /* close that auxiliary database. Unneccessary, but here for symmetry.
62 void
63 kaux_closedb(void)
66 if (fd > 0)
67 close(fd);
68 return;
73 * The read and write routines take as a parameter, the offset into
74 * the main database at which a particular user's entry resides. They
75 * then convert that into an offset into the auxiliary database. This
76 * makes the main code a little simpler, though it obscures a small
77 * detail.
79 int
80 kaux_read(afs_int32 to, /* this is the offset of the user id in the main database.
81 * we do the conversion here - probably a bad idea. */
82 unsigned int *nfailures, afs_uint32 * lasttime)
84 unsigned int offset;
86 *nfailures = *lasttime = 0;
88 if (fd <= 0 || !to)
89 return 0;
91 offset =
92 ((to - sizeof(struct kaheader)) / ENTRYSIZE) * (sizeof(int) +
93 sizeof(afs_int32));
94 /* can't get there from here */
95 if (offset > lseek(fd, offset, SEEK_SET))
96 return 0;
98 /* we should just end up with 0 for nfailures and lasttime if EOF is
99 * encountered here, I hope */
100 if ((0 > read(fd, nfailures, sizeof(int)))
101 || (0 > read(fd, lasttime, sizeof(afs_int32)))) {
102 *nfailures = *lasttime = 0;
103 perror("kaux_read()");
106 return 0;
110 kaux_write(afs_int32 to, unsigned int nfailures, afs_uint32 lasttime)
112 unsigned int offset;
114 if (fd <= 0 || !to)
115 return 0;
117 offset =
118 ((to - sizeof(struct kaheader)) / ENTRYSIZE) * (sizeof(int) +
119 sizeof(afs_int32));
120 /* can't get there from here */
121 if (offset > lseek(fd, offset, SEEK_SET))
122 return 0;
124 if ((write(fd, &nfailures, sizeof(int)) != sizeof(int))
125 || (write(fd, &lasttime, sizeof(afs_int32)) != sizeof(afs_int32)))
126 perror("kaux_write()");
127 return 0;
131 /* adjust this user's records to reflect a failure.
132 * locktime is the value stored in the main database that specifies
133 * how long a user's ID should be locked once the attempts limit has
134 * been exceeded. It also functions as the interval during which the
135 * permitted N-1 authentication failures plus the forbidden Nth
136 * failure must occur, in order for the ID to actually be locked. Ie,
137 * all failures which occurred more than _locktime_ seconds ago are
138 * forgiven.
139 * locktime == 0 signifies that the ID should be locked indefinitely
141 void
142 kaux_inc(afs_int32 to, afs_uint32 locktime)
144 unsigned int nfailures;
145 afs_uint32 lasttime, now;
147 now = time(0);
149 kaux_read(to, &nfailures, &lasttime);
151 if (locktime && lasttime + locktime < now)
152 nfailures = 1;
153 else
154 nfailures++;
156 kaux_write(to, nfailures, now);
161 * report on whether a particular id is locked or not...
162 * has to get some dirt from ubik.
163 * We multiply the actual number of permitted attempts by two because
164 * klog tries to authenticate twice when the password is bogus: once
165 * with the ka_string_to_key, and once with des_string_to_key, for
166 * Kerberos compatibility. It's easier to frob here than to explain
167 * to users/admins.
168 * RETURNS: time when the ID will be unlocked, or 0 if it's not locked.
171 kaux_islocked(afs_int32 to, u_int attempts, u_int locktime)
173 unsigned int nfailures, myshare;
174 afs_uint32 lasttime;
175 struct ubik_debug beaconinfo;
177 /* if attempts is 0, that means there's no limit, so the id
178 * can't ever be locked...
180 if (!attempts)
181 return 0;
183 kaux_read(to, &nfailures, &lasttime);
185 ubeacon_Debug(&beaconinfo);
186 attempts = attempts * 2;
188 myshare = attempts / beaconinfo.nServers;
189 if (ubeacon_AmSyncSite())
190 myshare += attempts % beaconinfo.nServers;
192 if (!myshare) {
193 return -1;
194 } else if ((nfailures < myshare)
195 || (locktime && lasttime + locktime < time(0))) {
196 return 0;
197 } else if (locktime == 0) { /* infinite */
198 return -1;
199 } else {
200 return (lasttime + locktime);