8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libc / port / gen / getspent_r.c
blobae45338b8b924d1926b6b9422565deb9bc9ad232
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright (c) 2016 by Delphix. All rights reserved.
28 #pragma ident "%Z%%M% %I% %E% SMI"
30 #include "lint.h"
31 #include <mtlib.h>
32 #include <sys/types.h>
33 #include <shadow.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <nss_dbdefs.h>
37 #include <stdio.h>
38 #include <synch.h>
40 int str2spwd(const char *, int, void *,
41 char *, int);
43 static DEFINE_NSS_DB_ROOT(db_root);
44 static DEFINE_NSS_GETENT(context);
46 void
47 _nss_initf_shadow(nss_db_params_t *p)
49 p->name = NSS_DBNAM_SHADOW;
50 p->config_name = NSS_DBNAM_PASSWD; /* Use config for "passwd" */
51 p->default_config = NSS_DEFCONF_PASSWD;
54 struct spwd *
55 getspnam_r(const char *name, struct spwd *result, char *buffer, int buflen)
57 nss_XbyY_args_t arg;
59 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2spwd);
60 arg.key.name = name;
61 (void) nss_search(&db_root, _nss_initf_shadow,
62 NSS_DBOP_SHADOW_BYNAME, &arg);
63 return ((struct spwd *)NSS_XbyY_FINI(&arg));
66 void
67 setspent(void)
69 nss_setent(&db_root, _nss_initf_shadow, &context);
72 void
73 endspent(void)
75 nss_endent(&db_root, _nss_initf_shadow, &context);
76 nss_delete(&db_root);
79 struct spwd *
80 getspent_r(struct spwd *result, char *buffer, int buflen)
82 nss_XbyY_args_t arg;
83 char *nam;
85 /* In getXXent_r(), protect the unsuspecting caller from +/- entries */
87 do {
88 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2spwd);
89 /* No key to fill in */
90 (void) nss_getent(&db_root, _nss_initf_shadow, &context, &arg);
91 } while (arg.returnval != 0 &&
92 (nam = ((struct spwd *)arg.returnval)->sp_namp) != 0 &&
93 (*nam == '+' || *nam == '-'));
95 return (struct spwd *)NSS_XbyY_FINI(&arg);
98 struct spwd *
99 fgetspent_r(FILE *f, struct spwd *result, char *buffer, int buflen)
101 extern void _nss_XbyY_fgets(FILE *, nss_XbyY_args_t *);
102 nss_XbyY_args_t arg;
104 /* ... but in fgetXXent_r, the caller deserves any +/- entry it gets */
106 /* No key to fill in */
107 NSS_XbyY_INIT(&arg, result, buffer, buflen, str2spwd);
108 _nss_XbyY_fgets(f, &arg);
109 return (struct spwd *)NSS_XbyY_FINI(&arg);
112 typedef const char *constp;
114 static int /* 1 means success and more input, 0 means error or no more */
115 getfield(constp *nextp, constp limit, int uns, void *valp)
117 constp p = *nextp;
118 char *endfield;
119 char numbuf[12]; /* Holds -2^31 and trailing ':' */
120 size_t len;
122 if (p == 0 || p >= limit) {
123 return (0);
125 if (*p == ':') {
126 p++;
127 *nextp = p;
128 return (p < limit);
130 if ((len = limit - p) > sizeof (numbuf) - 1) {
131 len = sizeof (numbuf) - 1;
134 * We want to use strtol() and we have a readonly non-zero-terminated
135 * string, so first we copy and terminate the interesting bit.
136 * Ugh. (It's convenient to terminate with a colon rather than \0).
138 if ((endfield = memccpy(numbuf, p, ':', len)) == 0) {
139 if (len != limit - p) {
140 /* Error -- field is too big to be a legit number */
141 return (0);
143 numbuf[len] = ':';
144 p = limit;
145 } else {
146 p += (endfield - numbuf);
148 if (uns) {
149 unsigned long ux = strtoul(numbuf, &endfield, 10);
150 if (*endfield != ':') {
151 /* Error -- expected <integer><colon> */
152 return (0);
154 *((unsigned int *)valp) = (unsigned int)ux;
155 } else {
156 long x = strtol(numbuf, &endfield, 10);
157 if (*endfield != ':') {
158 /* Error -- expected <integer><colon> */
159 return (0);
161 *((int *)valp) = (int)x;
163 *nextp = p;
164 return (p < limit);
168 * str2spwd() -- convert a string to a shadow passwd entry. The parser is
169 * more liberal than the passwd or group parsers; since it's legitimate
170 * for almost all the fields here to be blank, the parser lets one omit
171 * any number of blank fields at the end of the entry. The acceptable
172 * forms for '+' and '-' entries are the same as those for normal entries.
173 * === Is this likely to do more harm than good?
175 * Return values: 0 = success, 1 = parse error, 2 = erange ...
176 * The structure pointer passed in is a structure in the caller's space
177 * wherein the field pointers would be set to areas in the buffer if
178 * need be. instring and buffer should be separate areas.
181 str2spwd(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
183 struct spwd *shadow = (struct spwd *)ent;
184 const char *p = instr, *limit;
185 char *bufp;
186 int black_magic;
187 size_t lencopy;
189 limit = p + lenstr;
190 if ((p = memchr(instr, ':', lenstr)) == 0 ||
191 ++p >= limit ||
192 (p = memchr(p, ':', limit - p)) == 0) {
193 lencopy = (size_t)lenstr;
194 p = 0;
195 } else {
196 lencopy = p - instr;
197 p++;
199 if (lencopy + 1 > buflen) {
200 return (NSS_STR_PARSE_ERANGE);
203 if (instr != buffer) {
204 /* Overlapping buffer copies are OK */
205 (void) memmove(buffer, instr, lencopy);
206 buffer[lencopy] = 0;
209 /* quick exit do not entry fill if not needed */
210 if (ent == (void *)NULL)
211 return (NSS_STR_PARSE_SUCCESS);
213 black_magic = (*instr == '+' || *instr == '-');
214 shadow->sp_namp = bufp = buffer;
215 shadow->sp_pwdp = 0;
216 shadow->sp_lstchg = -1;
217 shadow->sp_min = -1;
218 shadow->sp_max = -1;
219 shadow->sp_warn = -1;
220 shadow->sp_inact = -1;
221 shadow->sp_expire = -1;
222 shadow->sp_flag = 0;
224 if ((bufp = strchr(bufp, ':')) == 0) {
225 if (black_magic)
226 return (NSS_STR_PARSE_SUCCESS);
227 else
228 return (NSS_STR_PARSE_PARSE);
230 *bufp++ = '\0';
232 shadow->sp_pwdp = bufp;
233 if (instr == 0) {
234 if ((bufp = strchr(bufp, ':')) == 0) {
235 if (black_magic)
236 return (NSS_STR_PARSE_SUCCESS);
237 else
238 return (NSS_STR_PARSE_PARSE);
240 *bufp++ = '\0';
241 p = bufp;
242 } /* else p was set when we copied name and passwd into the buffer */
244 if (!getfield(&p, limit, 0, &shadow->sp_lstchg))
245 return (NSS_STR_PARSE_SUCCESS);
246 if (!getfield(&p, limit, 0, &shadow->sp_min))
247 return (NSS_STR_PARSE_SUCCESS);
248 if (!getfield(&p, limit, 0, &shadow->sp_max))
249 return (NSS_STR_PARSE_SUCCESS);
250 if (!getfield(&p, limit, 0, &shadow->sp_warn))
251 return (NSS_STR_PARSE_SUCCESS);
252 if (!getfield(&p, limit, 0, &shadow->sp_inact))
253 return (NSS_STR_PARSE_SUCCESS);
254 if (!getfield(&p, limit, 0, &shadow->sp_expire))
255 return (NSS_STR_PARSE_SUCCESS);
256 if (!getfield(&p, limit, 1, &shadow->sp_flag))
257 return (NSS_STR_PARSE_SUCCESS);
258 if (p != limit) {
259 /* Syntax error -- garbage at end of line */
260 return (NSS_STR_PARSE_PARSE);
262 return (NSS_STR_PARSE_SUCCESS);