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]
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"
32 #include <sys/types.h>
36 #include <nss_dbdefs.h>
40 int str2spwd(const char *, int, void *,
43 static DEFINE_NSS_DB_ROOT(db_root
);
44 static DEFINE_NSS_GETENT(context
);
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
;
55 getspnam_r(const char *name
, struct spwd
*result
, char *buffer
, int buflen
)
59 NSS_XbyY_INIT(&arg
, result
, buffer
, buflen
, str2spwd
);
61 (void) nss_search(&db_root
, _nss_initf_shadow
,
62 NSS_DBOP_SHADOW_BYNAME
, &arg
);
63 return ((struct spwd
*)NSS_XbyY_FINI(&arg
));
69 nss_setent(&db_root
, _nss_initf_shadow
, &context
);
75 nss_endent(&db_root
, _nss_initf_shadow
, &context
);
80 getspent_r(struct spwd
*result
, char *buffer
, int buflen
)
85 NSS_XbyY_INIT(&arg
, result
, buffer
, buflen
, str2spwd
);
86 /* No key to fill in */
87 (void) nss_getent(&db_root
, _nss_initf_shadow
, &context
, &arg
);
89 return (struct spwd
*)NSS_XbyY_FINI(&arg
);
93 fgetspent_r(FILE *f
, struct spwd
*result
, char *buffer
, int buflen
)
95 extern void _nss_XbyY_fgets(FILE *, nss_XbyY_args_t
*);
98 /* No key to fill in */
99 NSS_XbyY_INIT(&arg
, result
, buffer
, buflen
, str2spwd
);
100 _nss_XbyY_fgets(f
, &arg
);
101 return (struct spwd
*)NSS_XbyY_FINI(&arg
);
104 typedef const char *constp
;
106 static int /* 1 means success and more input, 0 means error or no more */
107 getfield(constp
*nextp
, constp limit
, int uns
, void *valp
)
111 char numbuf
[12]; /* Holds -2^31 and trailing ':' */
114 if (p
== 0 || p
>= limit
) {
122 if ((len
= limit
- p
) > sizeof (numbuf
) - 1) {
123 len
= sizeof (numbuf
) - 1;
126 * We want to use strtol() and we have a readonly non-zero-terminated
127 * string, so first we copy and terminate the interesting bit.
128 * Ugh. (It's convenient to terminate with a colon rather than \0).
130 if ((endfield
= memccpy(numbuf
, p
, ':', len
)) == 0) {
131 if (len
!= limit
- p
) {
132 /* Error -- field is too big to be a legit number */
138 p
+= (endfield
- numbuf
);
141 unsigned long ux
= strtoul(numbuf
, &endfield
, 10);
142 if (*endfield
!= ':') {
143 /* Error -- expected <integer><colon> */
146 *((unsigned int *)valp
) = (unsigned int)ux
;
148 long x
= strtol(numbuf
, &endfield
, 10);
149 if (*endfield
!= ':') {
150 /* Error -- expected <integer><colon> */
153 *((int *)valp
) = (int)x
;
160 * str2spwd() -- convert a string to a shadow passwd entry. The parser is
161 * more liberal than the passwd or group parsers; since it's legitimate
162 * for almost all the fields here to be blank, the parser lets one omit
163 * any number of blank fields at the end of the entry.
164 * === Is this likely to do more harm than good?
166 * Return values: 0 = success, 1 = parse error, 2 = erange ...
167 * The structure pointer passed in is a structure in the caller's space
168 * wherein the field pointers would be set to areas in the buffer if
169 * need be. instring and buffer should be separate areas.
172 str2spwd(const char *instr
, int lenstr
, void *ent
, char *buffer
, int buflen
)
174 struct spwd
*shadow
= (struct spwd
*)ent
;
175 const char *p
= instr
, *limit
;
180 if ((p
= memchr(instr
, ':', lenstr
)) == 0 ||
182 (p
= memchr(p
, ':', limit
- p
)) == 0) {
183 lencopy
= (size_t)lenstr
;
189 if (lencopy
+ 1 > buflen
) {
190 return (NSS_STR_PARSE_ERANGE
);
193 if (instr
!= buffer
) {
194 /* Overlapping buffer copies are OK */
195 (void) memmove(buffer
, instr
, lencopy
);
199 /* quick exit do not entry fill if not needed */
201 return (NSS_STR_PARSE_SUCCESS
);
203 shadow
->sp_namp
= bufp
= buffer
;
205 shadow
->sp_lstchg
= -1;
208 shadow
->sp_warn
= -1;
209 shadow
->sp_inact
= -1;
210 shadow
->sp_expire
= -1;
213 if ((bufp
= strchr(bufp
, ':')) == 0)
214 return (NSS_STR_PARSE_PARSE
);
217 shadow
->sp_pwdp
= bufp
;
219 if ((bufp
= strchr(bufp
, ':')) == 0)
220 return (NSS_STR_PARSE_PARSE
);
223 } /* else p was set when we copied name and passwd into the buffer */
225 if (!getfield(&p
, limit
, 0, &shadow
->sp_lstchg
))
226 return (NSS_STR_PARSE_SUCCESS
);
227 if (!getfield(&p
, limit
, 0, &shadow
->sp_min
))
228 return (NSS_STR_PARSE_SUCCESS
);
229 if (!getfield(&p
, limit
, 0, &shadow
->sp_max
))
230 return (NSS_STR_PARSE_SUCCESS
);
231 if (!getfield(&p
, limit
, 0, &shadow
->sp_warn
))
232 return (NSS_STR_PARSE_SUCCESS
);
233 if (!getfield(&p
, limit
, 0, &shadow
->sp_inact
))
234 return (NSS_STR_PARSE_SUCCESS
);
235 if (!getfield(&p
, limit
, 0, &shadow
->sp_expire
))
236 return (NSS_STR_PARSE_SUCCESS
);
237 if (!getfield(&p
, limit
, 1, &shadow
->sp_flag
))
238 return (NSS_STR_PARSE_SUCCESS
);
240 /* Syntax error -- garbage at end of line */
241 return (NSS_STR_PARSE_PARSE
);
243 return (NSS_STR_PARSE_SUCCESS
);