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