2 * Copyright (c) 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University 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 REGENTS 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 REGENTS 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
35 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
36 * Portions Copyright (c) 1996,1999 by Internet Software Consortium.
38 * Permission to use, copy, modify, and distribute this software for any
39 * purpose with or without fee is hereby granted, provided that the above
40 * copyright notice and this permission notice appear in all copies.
42 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
43 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
44 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
45 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
46 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
47 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
48 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
51 #if defined(LIBC_SCCS) && !defined(lint)
52 static const char rcsid
[] = "$Id: lcl_pw.c,v 1.3 2005/04/27 04:56:31 sra Exp $";
53 #endif /* LIBC_SCCS and not lint */
57 #include "port_before.h"
60 static int __bind_irs_pw_unneeded
;
63 #include <sys/param.h>
64 #include <sys/types.h>
65 #include <netinet/in.h>
66 #include <arpa/nameser.h>
80 #include <isc/memcluster.h>
83 #include "port_after.h"
90 * The lookup techniques and data extraction code here must be kept
91 * in sync with that in `pwd_mkdb'.
98 struct passwd passwd
; /*%< password structure */
99 DB
*pw_db
; /*%< password database */
100 int pw_keynum
; /*%< key counter */
108 static void pw_close(struct irs_pw
*);
109 static struct passwd
* pw_next(struct irs_pw
*);
110 static struct passwd
* pw_byname(struct irs_pw
*, const char *);
111 static struct passwd
* pw_byuid(struct irs_pw
*, uid_t
);
112 static void pw_rewind(struct irs_pw
*);
113 static void pw_minimize(struct irs_pw
*);
115 static int initdb(struct pvt
*);
116 static int hashpw(struct irs_pw
*, DBT
*);
120 irs_lcl_pw(struct irs_acc
*this) {
126 if (!(pw
= memget(sizeof *pw
))) {
130 memset(pw
, 0x5e, sizeof *pw
);
131 if (!(pvt
= memget(sizeof *pvt
))) {
136 memset(pvt
, 0, sizeof *pvt
);
138 pw
->close
= pw_close
;
140 pw
->byname
= pw_byname
;
141 pw
->byuid
= pw_byuid
;
142 pw
->rewind
= pw_rewind
;
143 pw
->minimize
= pw_minimize
;
152 pw_close(struct irs_pw
*this) {
153 struct pvt
*pvt
= (struct pvt
*)this->private;
156 (void)(pvt
->pw_db
->close
)(pvt
->pw_db
);
160 memput(pvt
->line
, pvt
->max
);
161 memput(pvt
, sizeof *pvt
);
162 memput(this, sizeof *this);
165 static struct passwd
*
166 pw_next(struct irs_pw
*this) {
167 struct pvt
*pvt
= (struct pvt
*)this->private;
170 char bf
[sizeof(pvt
->pw_keynum
) + 1];
176 bf
[0] = _PW_KEYBYNUM
;
177 memcpy(bf
+ 1, (char *)&pvt
->pw_keynum
, sizeof(pvt
->pw_keynum
));
178 key
.data
= (u_char
*)bf
;
179 key
.size
= sizeof(pvt
->pw_keynum
) + 1;
180 return (hashpw(this, &key
) ? &pvt
->passwd
: NULL
);
183 static struct passwd
*
184 pw_byname(struct irs_pw
*this, const char *name
) {
185 struct pvt
*pvt
= (struct pvt
*)this->private;
188 char bf
[UT_NAMESIZE
+ 1];
193 bf
[0] = _PW_KEYBYNAME
;
195 memcpy(bf
+ 1, name
, MIN(len
, UT_NAMESIZE
));
196 key
.data
= (u_char
*)bf
;
198 rval
= hashpw(this, &key
);
200 return (rval
? &pvt
->passwd
: NULL
);
204 static struct passwd
*
205 pw_byuid(struct irs_pw
*this, uid_t uid
) {
206 struct pvt
*pvt
= (struct pvt
*)this->private;
209 char bf
[sizeof(keyuid
) + 1];
214 bf
[0] = _PW_KEYBYUID
;
216 memcpy(bf
+ 1, &keyuid
, sizeof(keyuid
));
217 key
.data
= (u_char
*)bf
;
218 key
.size
= sizeof(keyuid
) + 1;
219 rval
= hashpw(this, &key
);
221 return (rval
? &pvt
->passwd
: NULL
);
225 pw_rewind(struct irs_pw
*this) {
226 struct pvt
*pvt
= (struct pvt
*)this->private;
232 pw_minimize(struct irs_pw
*this) {
233 struct pvt
*pvt
= (struct pvt
*)this->private;
235 if (pvt
->pw_db
!= NULL
) {
236 (void) (*pvt
->pw_db
->close
)(pvt
->pw_db
);
244 initdb(struct pvt
*pvt
) {
248 if (lseek((*pvt
->pw_db
->fd
)(pvt
->pw_db
), 0L, SEEK_CUR
) >= 0L)
251 (void) (*pvt
->pw_db
->close
)(pvt
->pw_db
);
253 pvt
->pw_db
= dbopen((p
= _PATH_SMP_DB
), O_RDONLY
, 0, DB_HASH
, NULL
);
255 pvt
->pw_db
= dbopen((p
=_PATH_MP_DB
), O_RDONLY
,
260 syslog(LOG_ERR
, "%s: %m", p
);
267 hashpw(struct irs_pw
*this, DBT
*key
) {
268 struct pvt
*pvt
= (struct pvt
*)this->private;
272 if ((pvt
->pw_db
->get
)(pvt
->pw_db
, key
, &data
, 0))
274 p
= (char *)data
.data
;
275 if (data
.size
> pvt
->max
) {
276 size_t newlen
= pvt
->max
+ 1024;
277 char *p
= memget(newlen
);
281 if (pvt
->line
!= NULL
) {
282 memcpy(p
, pvt
->line
, pvt
->max
);
283 memput(pvt
->line
, pvt
->max
);
289 /* THIS CODE MUST MATCH THAT IN pwd_mkdb. */
291 l
= pvt
->line
+ pvt
->max
;
292 #define EXPAND(e) if ((e = t) == NULL) return (0); else \
293 do if (t >= l) return (0); while ((*t++ = *p++) != '\0')
294 #define SCALAR(v) if (t + sizeof v >= l) return (0); else \
295 (memmove(&(v), p, sizeof v), p += sizeof v)
296 EXPAND(pvt
->passwd
.pw_name
);
297 EXPAND(pvt
->passwd
.pw_passwd
);
298 SCALAR(pvt
->passwd
.pw_uid
);
299 SCALAR(pvt
->passwd
.pw_gid
);
300 SCALAR(pvt
->passwd
.pw_change
);
301 EXPAND(pvt
->passwd
.pw_class
);
302 EXPAND(pvt
->passwd
.pw_gecos
);
303 EXPAND(pvt
->passwd
.pw_dir
);
304 EXPAND(pvt
->passwd
.pw_shell
);
305 SCALAR(pvt
->passwd
.pw_expire
);
309 #endif /* WANT_IRS_PW */