xref: /illumos-gate/usr/src/lib/nsswitch/ad/common/getspent.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <shadow.h>
27 #include <stdlib.h>
28 #include "ad_common.h"
29 
30 static int
31 update_buffer(ad_backend_ptr be, nss_XbyY_args_t *argp,
32 		const char *name, const char *domain)
33 {
34 	int	buflen;
35 	char	*buffer;
36 
37 	/*
38 	 * The user password is not available in the AD object and therefore
39 	 * sp_pwdp will be "*NP*".
40 	 *
41 	 * nss_ad will leave aging fields empty (i.e. The front end
42 	 * marshaller will set sp_lstchgst, sp_min, sp_max, sp_warn,
43 	 * sp_inact, and sp_expire to -1 and sp_flag to 0) because shadow
44 	 * fields are irrevalent with AD and krb5.
45 	 */
46 
47 	buflen = snprintf(NULL, 0, "%s@%s:*NP*:::::::", name, domain) + 1;
48 
49 	if (argp->buf.result != NULL) {
50 		buffer = be->buffer = malloc(buflen);
51 		if (be->buffer == NULL)
52 			return (-1);
53 		be->buflen = buflen;
54 	} else {
55 		if (buflen > argp->buf.buflen)
56 			return (-1);
57 		buflen = argp->buf.buflen;
58 		buffer = argp->buf.buffer;
59 	}
60 
61 	buflen = snprintf(buffer, buflen, "%s@%s:*NP*:::::::",
62 	    name, domain) + 1;
63 	return (0);
64 }
65 
66 /*
67  * getbynam gets a shadow entry by winname. This function constructs an ldap
68  * search filter using the name invocation parameter and the getspnam search
69  * filter defined. Once the filter is constructed we search for a matching
70  * entry and marshal the data results into struct shadow for the frontend
71  * process. The function _nss_ad_shadow2ent performs the data marshaling.
72  */
73 static nss_status_t
74 getbynam(ad_backend_ptr be, void *a)
75 {
76 	nss_XbyY_args_t	*argp = (nss_XbyY_args_t *)a;
77 	char		name[SEARCHFILTERLEN + 1];
78 	char		*dname;
79 	nss_status_t	stat;
80 	idmap_stat	idmaprc;
81 	uid_t		uid;
82 	int		is_user, is_wuser;
83 	idmap_handle_t	*ih;
84 
85 	be->db_type = NSS_AD_DB_SHADOW_BYNAME;
86 
87 	/* Sanitize name so that it can be used in our LDAP filter */
88 	if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0)
89 		return ((nss_status_t)NSS_NOTFOUND);
90 
91 	if ((dname = strchr(name, '@')) == NULL)
92 		return ((nss_status_t)NSS_NOTFOUND);
93 
94 	*dname = '\0';
95 	dname++;
96 
97 	/*
98 	 * Use idmap service to verify that the given
99 	 * name is a valid Windows name.
100 	 */
101 	idmaprc = idmap_init(&ih);
102 	if (idmaprc != IDMAP_SUCCESS)
103 		return ((nss_status_t)NSS_NOTFOUND);
104 	is_wuser = -1;
105 	is_user = 1;
106 	idmaprc = idmap_get_w2u_mapping(ih, NULL, NULL, name, dname,
107 	    0, &is_user, &is_wuser, &uid, NULL, NULL, NULL);
108 	(void) idmap_fini(ih);
109 	if (idmaprc != IDMAP_SUCCESS) {
110 		RESET_ERRNO();
111 		return ((nss_status_t)NSS_NOTFOUND);
112 	}
113 
114 	/* Create shadow(4) style string */
115 	if (update_buffer(be, argp, name, dname) < 0)
116 		return ((nss_status_t)NSS_NOTFOUND);
117 
118 	/* Marshall the data, sanitize the return status and return */
119 	stat = _nss_ad_marshall_data(be, argp);
120 	return (_nss_ad_sanitize_status(be, argp, stat));
121 }
122 
123 static ad_backend_op_t sp_ops[] = {
124     _nss_ad_destr,
125     _nss_ad_endent,
126     _nss_ad_setent,
127     _nss_ad_getent,
128     getbynam
129 };
130 
131 
132 /*
133  * _nss_ad_passwd_constr is where life begins. This function calls the
134  * generic ldap constructor function to define and build the abstract
135  * data types required to support ldap operations.
136  */
137 /*ARGSUSED0*/
138 nss_backend_t *
139 _nss_ad_shadow_constr(const char *dummy1, const char *dummy2,
140 			const char *dummy3)
141 {
142 
143 	return ((nss_backend_t *)_nss_ad_constr(sp_ops,
144 	    sizeof (sp_ops)/sizeof (sp_ops[0]),
145 	    _SHADOW, NULL, NULL));
146 }
147