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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <sys/types.h>
34 #include <nss_dbdefs.h>
36 #include "passwdutil.h"
38 /* from files_attr.c */
39 struct passwd
*private_getpwnam_r(const char *name
, struct passwd
*result
,
40 char *buffer
, int buflen
);
42 int nss_getattr(char *name
, attrlist
*item
, pwu_repository_t
*rep
);
43 int nss_getpwnam(char *name
, attrlist
*items
, pwu_repository_t
*rep
,
47 * nss function pointer table, used by passwdutil_init to initialize
48 * the global Repository-OPerations table "rops"
50 struct repops nss_repops
= {
51 NULL
, /* checkhistory */
56 NULL
, /* user_to_authenticate */
62 * this structure defines the buffer used to keep state between
63 * get/update/put calls
74 * We should use sysconf, but there is no sysconf name for SHADOW
75 * so we use these from nss_dbdefs
77 #define PWD_SCRATCH_SIZE NSS_LINELEN_PASSWD
78 #define SPW_SCRATCH_SIZE NSS_LINELEN_SHADOW
82 * nss_getpwnam(name, items, rep, buf)
87 nss_getpwnam(char *name
, attrlist
*items
, pwu_repository_t
*rep
, void **buf
)
91 int repositories
= REP_ERANGE
; /* changed if ATTR_REP_NAME is set */
92 int err
= PWU_SUCCESS
;
94 *buf
= calloc(1, sizeof (struct pwbuf
));
95 pwbuf
= (struct pwbuf
*)*buf
;
100 * determine which password structure (/etc/passwd or /etc/shadow)
101 * we need for the items we need to update
103 for (p
= items
; p
!= NULL
; p
= p
->next
) {
113 if (pwbuf
->pwd
== NULL
)
114 pwbuf
->pwd
= (struct passwd
*)
115 malloc(sizeof (struct passwd
));
116 if (pwbuf
->pwd
== NULL
) {
124 case ATTR_PASSWD_SERVER_POLICY
:
132 case ATTR_LOCK_ACCOUNT
:
133 case ATTR_EXPIRE_PASSWORD
:
134 case ATTR_FAILED_LOGINS
:
135 if (pwbuf
->spwd
== NULL
)
136 pwbuf
->spwd
= (struct spwd
*)
137 malloc(sizeof (struct spwd
));
138 if (pwbuf
->spwd
== NULL
) {
146 /* get the compat names (REP_COMPAT_*) */
147 repositories
= get_ns(rep
, PWU_READ
);
151 * Some other repository might have different values
152 * so we ignore those.
159 if ((pwbuf
->pwd_scratch
= malloc(PWD_SCRATCH_SIZE
)) == NULL
) {
163 if (getpwnam_r(name
, pwbuf
->pwd
, pwbuf
->pwd_scratch
,
164 PWD_SCRATCH_SIZE
) == NULL
) {
171 if ((pwbuf
->spwd_scratch
= malloc(SPW_SCRATCH_SIZE
)) == NULL
) {
175 if (getspnam_r(name
, pwbuf
->spwd
, pwbuf
->spwd_scratch
,
176 SPW_SCRATCH_SIZE
) == NULL
) {
182 /* pwbuf->rep_name tells us where the user in fact comes from */
183 if (repositories
!= REP_ERANGE
) {
185 char pwd_scratch
[PWD_SCRATCH_SIZE
];
187 /* can we find the user locally? */
188 if (private_getpwnam_r(name
, &pwd
, pwd_scratch
,
189 PWD_SCRATCH_SIZE
) != NULL
)
190 pwbuf
->rep_name
= "files";
191 else if (repositories
& REP_COMPAT_LDAP
)
192 pwbuf
->rep_name
= "ldap";
193 else if (repositories
& REP_COMPAT_NIS
)
194 pwbuf
->rep_name
= "nis";
196 pwbuf
->rep_name
= "nss";
198 pwbuf
->rep_name
= "nss";
200 return (PWU_SUCCESS
);
202 if (pwbuf
->pwd
) free(pwbuf
->pwd
);
203 if (pwbuf
->pwd_scratch
) free(pwbuf
->pwd_scratch
);
204 if (pwbuf
->spwd
) free(pwbuf
->spwd
);
205 if (pwbuf
->spwd_scratch
) free(pwbuf
->spwd_scratch
);
214 * nss_getattr(name, items, rep)
216 * Get attributes specified in list 'items'
219 nss_getattr(char *name
, attrlist
*items
, pwu_repository_t
*rep
)
227 res
= nss_getpwnam(name
, items
, rep
, (void **)&pwbuf
);
228 if (res
!= PWU_SUCCESS
)
234 for (w
= items
; res
== PWU_SUCCESS
&& w
!= NULL
; w
= w
->next
) {
237 if ((w
->data
.val_s
= strdup(pw
->pw_name
)) == NULL
)
241 if ((w
->data
.val_s
= strdup(pw
->pw_comment
)) == NULL
)
245 if ((w
->data
.val_s
= strdup(pw
->pw_gecos
)) == NULL
)
249 if ((w
->data
.val_s
= strdup(pw
->pw_dir
)) == NULL
)
253 if ((w
->data
.val_s
= strdup(pw
->pw_shell
)) == NULL
)
257 * Nothing special needs to be done for
261 case ATTR_PASSWD_SERVER_POLICY
:
262 if ((w
->data
.val_s
= strdup(spw
->sp_pwdp
)) == NULL
)
266 if ((w
->data
.val_s
= strdup(pw
->pw_age
)) == NULL
)
270 if ((w
->data
.val_s
= strdup(pwbuf
->rep_name
)) == NULL
)
276 w
->data
.val_i
= pw
->pw_uid
;
279 w
->data
.val_i
= pw
->pw_gid
;
282 w
->data
.val_i
= spw
->sp_lstchg
;
285 w
->data
.val_i
= spw
->sp_min
;
288 w
->data
.val_i
= spw
->sp_max
;
291 w
->data
.val_i
= spw
->sp_warn
;
294 w
->data
.val_i
= spw
->sp_inact
;
297 w
->data
.val_i
= spw
->sp_expire
;
300 w
->data
.val_i
= spw
->sp_flag
;
302 case ATTR_FAILED_LOGINS
:
303 w
->data
.val_i
= spw
->sp_flag
& FAILCOUNT_MASK
;
310 if (pwbuf
->pwd
) free(pwbuf
->pwd
);
311 if (pwbuf
->pwd_scratch
) free(pwbuf
->pwd_scratch
);
312 if (pwbuf
->spwd
) free(pwbuf
->spwd
);
313 if (pwbuf
->spwd_scratch
) free(pwbuf
->spwd_scratch
);