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
14 #include <afsconfig.h>
15 #include <afs/param.h>
28 #define UBIK_INTERNALS
37 /* Open the auxiliary database file containing failed authentication
38 * counters, and the times at which the last failures occurred.
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);
60 /* close that auxiliary database. Unneccessary, but here for symmetry.
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
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
)
86 *nfailures
= *lasttime
= 0;
92 ((to
- sizeof(struct kaheader
)) / ENTRYSIZE
) * (sizeof(int) +
94 /* can't get there from here */
95 if (offset
> lseek(fd
, offset
, SEEK_SET
))
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()");
110 kaux_write(afs_int32 to
, unsigned int nfailures
, afs_uint32 lasttime
)
118 ((to
- sizeof(struct kaheader
)) / ENTRYSIZE
) * (sizeof(int) +
120 /* can't get there from here */
121 if (offset
> lseek(fd
, offset
, SEEK_SET
))
124 if ((write(fd
, &nfailures
, sizeof(int)) != sizeof(int))
125 || (write(fd
, &lasttime
, sizeof(afs_int32
)) != sizeof(afs_int32
)))
126 perror("kaux_write()");
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
139 * locktime == 0 signifies that the ID should be locked indefinitely
142 kaux_inc(afs_int32 to
, afs_uint32 locktime
)
144 unsigned int nfailures
;
145 afs_uint32 lasttime
, now
;
149 kaux_read(to
, &nfailures
, &lasttime
);
151 if (locktime
&& lasttime
+ locktime
< now
)
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
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
;
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...
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
;
194 } else if ((nfailures
< myshare
)
195 || (locktime
&& lasttime
+ locktime
< time(0))) {
197 } else if (locktime
== 0) { /* infinite */
200 return (lasttime
+ locktime
);