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