No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / libbind / dist / irs / nis_pw.c
blob7e104f1a2e154f096b711ce297aff929cafbe4b2
1 /* $NetBSD$ */
3 /*
4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1996,1999 by Internet Software Consortium.
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static const char rcsid[] = "Id: nis_pw.c,v 1.4 2005/04/27 04:56:33 sra Exp";
22 #endif /* LIBC_SCCS and not lint */
24 /* Imports */
26 #include "port_before.h"
28 #if !defined(WANT_IRS_PW) || !defined(WANT_IRS_NIS)
29 static int __bind_irs_pw_unneeded;
30 #else
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <netinet/in.h>
35 #include <arpa/nameser.h>
36 #include <resolv.h>
37 #include <isc/memcluster.h>
38 #include <rpc/rpc.h>
39 #include <rpc/xdr.h>
40 #include <rpcsvc/yp_prot.h>
41 #include <rpcsvc/ypclnt.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <pwd.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <unistd.h>
51 #include <isc/memcluster.h>
53 #include <irs.h>
55 #include "port_after.h"
57 #include "irs_p.h"
58 #include "nis_p.h"
60 /* Definitions */
62 struct pvt {
63 int needrewind;
64 char * nis_domain;
65 char * curkey_data;
66 int curkey_len;
67 char * curval_data;
68 int curval_len;
69 struct passwd passwd;
70 char * pwbuf;
73 enum do_what { do_none = 0x0, do_key = 0x1, do_val = 0x2, do_all = 0x3 };
75 static /*const*/ char passwd_byname[] = "passwd.byname";
76 static /*const*/ char passwd_byuid[] = "passwd.byuid";
78 /* Forward */
80 static void pw_close(struct irs_pw *);
81 static struct passwd * pw_next(struct irs_pw *);
82 static struct passwd * pw_byname(struct irs_pw *, const char *);
83 static struct passwd * pw_byuid(struct irs_pw *, uid_t);
84 static void pw_rewind(struct irs_pw *);
85 static void pw_minimize(struct irs_pw *);
87 static struct passwd * makepasswdent(struct irs_pw *);
88 static void nisfree(struct pvt *, enum do_what);
90 /* Public */
92 struct irs_pw *
93 irs_nis_pw(struct irs_acc *this) {
94 struct irs_pw *pw;
95 struct pvt *pvt;
97 if (!(pw = memget(sizeof *pw))) {
98 errno = ENOMEM;
99 return (NULL);
101 memset(pw, 0x5e, sizeof *pw);
102 if (!(pvt = memget(sizeof *pvt))) {
103 memput(pw, sizeof *pw);
104 errno = ENOMEM;
105 return (NULL);
107 memset(pvt, 0, sizeof *pvt);
108 pvt->needrewind = 1;
109 pvt->nis_domain = ((struct nis_p *)this->private)->domain;
110 pw->private = pvt;
111 pw->close = pw_close;
112 pw->next = pw_next;
113 pw->byname = pw_byname;
114 pw->byuid = pw_byuid;
115 pw->rewind = pw_rewind;
116 pw->minimize = pw_minimize;
117 pw->res_get = NULL;
118 pw->res_set = NULL;
119 return (pw);
122 /* Methods */
124 static void
125 pw_close(struct irs_pw *this) {
126 struct pvt *pvt = (struct pvt *)this->private;
128 if (pvt->pwbuf)
129 free(pvt->pwbuf);
130 nisfree(pvt, do_all);
131 memput(pvt, sizeof *pvt);
132 memput(this, sizeof *this);
135 static struct passwd *
136 pw_next(struct irs_pw *this) {
137 struct pvt *pvt = (struct pvt *)this->private;
138 struct passwd *rval;
139 int r;
141 do {
142 if (pvt->needrewind) {
143 nisfree(pvt, do_all);
144 r = yp_first(pvt->nis_domain, passwd_byname,
145 &pvt->curkey_data, &pvt->curkey_len,
146 &pvt->curval_data, &pvt->curval_len);
147 pvt->needrewind = 0;
148 } else {
149 char *newkey_data;
150 int newkey_len;
152 nisfree(pvt, do_val);
153 r = yp_next(pvt->nis_domain, passwd_byname,
154 pvt->curkey_data, pvt->curkey_len,
155 &newkey_data, &newkey_len,
156 &pvt->curval_data, &pvt->curval_len);
157 nisfree(pvt, do_key);
158 pvt->curkey_data = newkey_data;
159 pvt->curkey_len = newkey_len;
161 if (r != 0) {
162 errno = ENOENT;
163 return (NULL);
165 rval = makepasswdent(this);
166 } while (rval == NULL);
167 return (rval);
170 static struct passwd *
171 pw_byname(struct irs_pw *this, const char *name) {
172 struct pvt *pvt = (struct pvt *)this->private;
173 int r;
174 char *tmp;
176 nisfree(pvt, do_val);
177 DE_CONST(name, tmp);
178 r = yp_match(pvt->nis_domain, passwd_byname, tmp, strlen(tmp),
179 &pvt->curval_data, &pvt->curval_len);
180 if (r != 0) {
181 errno = ENOENT;
182 return (NULL);
184 return (makepasswdent(this));
187 static struct passwd *
188 pw_byuid(struct irs_pw *this, uid_t uid) {
189 struct pvt *pvt = (struct pvt *)this->private;
190 char tmp[sizeof "4294967295"];
191 int r;
193 nisfree(pvt, do_val);
194 (void) sprintf(tmp, "%u", (unsigned int)uid);
195 r = yp_match(pvt->nis_domain, passwd_byuid, tmp, strlen(tmp),
196 &pvt->curval_data, &pvt->curval_len);
197 if (r != 0) {
198 errno = ENOENT;
199 return (NULL);
201 return (makepasswdent(this));
204 static void
205 pw_rewind(struct irs_pw *this) {
206 struct pvt *pvt = (struct pvt *)this->private;
208 pvt->needrewind = 1;
211 static void
212 pw_minimize(struct irs_pw *this) {
213 UNUSED(this);
214 /* NOOP */
217 /* Private */
219 static struct passwd *
220 makepasswdent(struct irs_pw *this) {
221 struct pvt *pvt = (struct pvt *)this->private;
222 char *cp;
224 memset(&pvt->passwd, 0, sizeof pvt->passwd);
225 if (pvt->pwbuf)
226 free(pvt->pwbuf);
227 pvt->pwbuf = pvt->curval_data;
228 pvt->curval_data = NULL;
230 cp = pvt->pwbuf;
231 pvt->passwd.pw_name = cp;
232 if (!(cp = strchr(cp, ':')))
233 goto cleanup;
234 #ifdef HAS_PW_CLASS
235 pvt->passwd.pw_class = cp; /*%< Needs to point at a \0. */
236 #endif
237 *cp++ = '\0';
239 pvt->passwd.pw_passwd = cp;
240 if (!(cp = strchr(cp, ':')))
241 goto cleanup;
242 *cp++ = '\0';
244 pvt->passwd.pw_uid = atoi(cp);
245 if (!(cp = strchr(cp, ':')))
246 goto cleanup;
247 *cp++ = '\0';
249 pvt->passwd.pw_gid = atoi(cp);
250 if (!(cp = strchr(cp, ':')))
251 goto cleanup;
252 *cp++ = '\0';
254 pvt->passwd.pw_gecos = cp;
255 if (!(cp = strchr(cp, ':')))
256 goto cleanup;
257 *cp++ = '\0';
259 pvt->passwd.pw_dir = cp;
260 if (!(cp = strchr(cp, ':')))
261 goto cleanup;
262 *cp++ = '\0';
264 pvt->passwd.pw_shell = cp;
266 if ((cp = strchr(cp, '\n')) != NULL)
267 *cp = '\0';
269 return (&pvt->passwd);
271 cleanup:
272 free(pvt->pwbuf);
273 pvt->pwbuf = NULL;
274 return (NULL);
277 static void
278 nisfree(struct pvt *pvt, enum do_what do_what) {
279 if ((do_what & do_key) && pvt->curkey_data) {
280 free(pvt->curkey_data);
281 pvt->curkey_data = NULL;
283 if ((do_what & do_val) && pvt->curval_data) {
284 free(pvt->curval_data);
285 pvt->curval_data = NULL;
289 #endif /* WANT_IRS_PW && WANT_IRS_NIS */
290 /*! \file */