1479ac375Sdm /*
2479ac375Sdm * CDDL HEADER START
3479ac375Sdm *
4479ac375Sdm * The contents of this file are subject to the terms of the
5479ac375Sdm * Common Development and Distribution License (the "License").
6479ac375Sdm * You may not use this file except in compliance with the License.
7479ac375Sdm *
8479ac375Sdm * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9479ac375Sdm * or http://www.opensolaris.org/os/licensing.
10479ac375Sdm * See the License for the specific language governing permissions
11479ac375Sdm * and limitations under the License.
12479ac375Sdm *
13479ac375Sdm * When distributing Covered Code, include this CDDL HEADER in each
14479ac375Sdm * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15479ac375Sdm * If applicable, add the following below this CDDL HEADER, with the
16479ac375Sdm * fields enclosed by brackets "[]" replaced with your own identifying
17479ac375Sdm * information: Portions Copyright [yyyy] [name of copyright owner]
18479ac375Sdm *
19479ac375Sdm * CDDL HEADER END
20479ac375Sdm */
21479ac375Sdm /*
22c5866007SKeyur Desai * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23b3700b07SGordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24479ac375Sdm */
25479ac375Sdm
26479ac375Sdm
27479ac375Sdm #include <errno.h>
28479ac375Sdm #include <ldap.h>
29479ac375Sdm #include <sasl/sasl.h>
30479ac375Sdm #include <libintl.h>
31479ac375Sdm #include <strings.h>
327a8a68f5SJulian Pullen #include <syslog.h>
33c5866007SKeyur Desai #include <stdarg.h>
34479ac375Sdm
357a8a68f5SJulian Pullen #include "addisc.h"
367a8a68f5SJulian Pullen #include "libadutils.h"
37c5866007SKeyur Desai #include "idmap_priv.h"
38479ac375Sdm #include "ns_sldap.h"
39c5866007SKeyur Desai #include "namemaps.h"
40479ac375Sdm
41479ac375Sdm /* From adutils.c: */
42479ac375Sdm
43479ac375Sdm /* A single DS */
4461b364a9Sjp struct idmap_nm_handle {
45479ac375Sdm LDAP *ad; /* LDAP connection */
46479ac375Sdm /* LDAP DS info */
47479ac375Sdm char *ad_host;
48479ac375Sdm int ad_port;
49479ac375Sdm
50479ac375Sdm /* hardwired to SASL GSSAPI only for now */
51479ac375Sdm char *saslmech;
52479ac375Sdm unsigned saslflags;
53479ac375Sdm char *windomain;
54479ac375Sdm char *ad_unixuser_attr;
55479ac375Sdm char *ad_unixgroup_attr;
56479ac375Sdm char *nldap_winname_attr;
57479ac375Sdm char *default_domain;
58479ac375Sdm bool_t is_nldap;
59479ac375Sdm bool_t is_ad;
6061b364a9Sjp int direction;
6161b364a9Sjp ns_cred_t nsc;
6261b364a9Sjp };
63479ac375Sdm
64c5866007SKeyur Desai /* PRINTFLIKE1 */
65c5866007SKeyur Desai static
66c5866007SKeyur Desai void
namemap_log(char * fmt,...)67c5866007SKeyur Desai namemap_log(char *fmt, ...)
68c5866007SKeyur Desai {
69c5866007SKeyur Desai va_list va;
70c5866007SKeyur Desai
71c5866007SKeyur Desai va_start(va, fmt);
72c5866007SKeyur Desai (void) vfprintf(stderr, fmt, va);
73c5866007SKeyur Desai va_end(va);
74c5866007SKeyur Desai (void) fprintf(stderr, "\n");
75c5866007SKeyur Desai }
76c5866007SKeyur Desai
77479ac375Sdm static
78479ac375Sdm idmap_stat
string2auth(const char * from,ns_auth_t * na)79479ac375Sdm string2auth(const char *from, ns_auth_t *na)
80479ac375Sdm {
81479ac375Sdm if (from == NULL) {
82479ac375Sdm na->type = NS_LDAP_AUTH_SASL;
83479ac375Sdm na->tlstype = NS_LDAP_TLS_SASL;
84479ac375Sdm na->saslmech = NS_LDAP_SASL_GSSAPI;
85479ac375Sdm na->saslopt = NS_LDAP_SASLOPT_PRIV |
86479ac375Sdm NS_LDAP_SASLOPT_INT;
87479ac375Sdm return (IDMAP_SUCCESS);
88479ac375Sdm }
89479ac375Sdm
90479ac375Sdm if (strcasecmp(from, "simple") == 0) {
91479ac375Sdm na->type = NS_LDAP_AUTH_SIMPLE;
92479ac375Sdm na->tlstype = NS_LDAP_TLS_NONE;
93479ac375Sdm na->saslmech = NS_LDAP_SASL_NONE;
94479ac375Sdm na->saslopt = NS_LDAP_SASLOPT_NONE;
95479ac375Sdm } else if (strcasecmp(from, "sasl/CRAM-MD5") == 0) {
96479ac375Sdm na->type = NS_LDAP_AUTH_SASL;
97479ac375Sdm na->tlstype = NS_LDAP_TLS_SASL;
98479ac375Sdm na->saslmech = NS_LDAP_SASL_CRAM_MD5;
99479ac375Sdm na->saslopt = NS_LDAP_SASLOPT_NONE;
100479ac375Sdm } else if (strcasecmp(from, "sasl/DIGEST-MD5") == 0) {
101479ac375Sdm na->type = NS_LDAP_AUTH_SASL;
102479ac375Sdm na->tlstype = NS_LDAP_TLS_SASL;
103479ac375Sdm na->saslmech = NS_LDAP_SASL_DIGEST_MD5;
104479ac375Sdm na->saslopt = NS_LDAP_SASLOPT_NONE;
105479ac375Sdm } else if (strcasecmp(from, "sasl/GSSAPI") == 0) {
106479ac375Sdm na->type = NS_LDAP_AUTH_SASL;
107479ac375Sdm na->tlstype = NS_LDAP_TLS_SASL;
108479ac375Sdm na->saslmech = NS_LDAP_SASL_GSSAPI;
109479ac375Sdm na->saslopt = NS_LDAP_SASLOPT_PRIV |
110479ac375Sdm NS_LDAP_SASLOPT_INT;
111479ac375Sdm } else if (strcasecmp(from, "tls:simple") == 0) {
112479ac375Sdm na->type = NS_LDAP_AUTH_TLS;
113479ac375Sdm na->tlstype = NS_LDAP_TLS_SIMPLE;
114479ac375Sdm na->saslmech = NS_LDAP_SASL_NONE;
115479ac375Sdm na->saslopt = NS_LDAP_SASLOPT_NONE;
116479ac375Sdm } else if (strcasecmp(from, "tls:sasl/CRAM-MD5") == 0) {
117479ac375Sdm na->type = NS_LDAP_AUTH_TLS;
118479ac375Sdm na->tlstype = NS_LDAP_TLS_SASL;
119479ac375Sdm na->saslmech = NS_LDAP_SASL_CRAM_MD5;
120479ac375Sdm na->saslopt = NS_LDAP_SASLOPT_NONE;
121479ac375Sdm } else if (strcasecmp(from, "tls:sasl/DIGEST-MD5") == 0) {
122479ac375Sdm na->type = NS_LDAP_AUTH_TLS;
123479ac375Sdm na->tlstype = NS_LDAP_TLS_SASL;
124479ac375Sdm na->saslmech = NS_LDAP_SASL_DIGEST_MD5;
125479ac375Sdm na->saslopt = NS_LDAP_SASLOPT_NONE;
126479ac375Sdm } else {
127c5866007SKeyur Desai namemap_log(
128479ac375Sdm gettext("Invalid authentication method \"%s\" specified\n"),
129479ac375Sdm from);
130479ac375Sdm return (IDMAP_ERR_ARG);
131479ac375Sdm }
132479ac375Sdm
133479ac375Sdm return (IDMAP_SUCCESS);
134479ac375Sdm }
135479ac375Sdm
136479ac375Sdm
137479ac375Sdm
138479ac375Sdm static
139479ac375Sdm idmap_stat
strings2cred(ns_cred_t * nsc,char * user,char * passwd,char * auth)140479ac375Sdm strings2cred(ns_cred_t *nsc, char *user, char *passwd, char *auth)
141479ac375Sdm {
142479ac375Sdm idmap_stat rc;
143479ac375Sdm (void) memset(nsc, 0, sizeof (ns_cred_t));
144479ac375Sdm
145479ac375Sdm if ((rc = string2auth(auth, &nsc->auth)) != IDMAP_SUCCESS)
146479ac375Sdm return (rc);
147479ac375Sdm
14861b364a9Sjp if (user != NULL) {
14961b364a9Sjp nsc->cred.unix_cred.userID = strdup(user);
15061b364a9Sjp if (nsc->cred.unix_cred.userID == NULL)
15161b364a9Sjp return (IDMAP_ERR_MEMORY);
15261b364a9Sjp }
15361b364a9Sjp
15461b364a9Sjp if (passwd != NULL) {
15561b364a9Sjp nsc->cred.unix_cred.passwd = strdup(passwd);
15661b364a9Sjp if (nsc->cred.unix_cred.passwd == NULL) {
15761b364a9Sjp free(nsc->cred.unix_cred.userID);
15861b364a9Sjp return (IDMAP_ERR_MEMORY);
15961b364a9Sjp }
16061b364a9Sjp }
161479ac375Sdm
162479ac375Sdm return (IDMAP_SUCCESS);
163479ac375Sdm }
164479ac375Sdm
165479ac375Sdm
166479ac375Sdm
167479ac375Sdm
168479ac375Sdm
169479ac375Sdm /*ARGSUSED*/
170479ac375Sdm static int
idmap_saslcallback(LDAP * ld,unsigned flags,void * defaults,void * prompts)171479ac375Sdm idmap_saslcallback(LDAP *ld, unsigned flags, void *defaults, void *prompts)
172479ac375Sdm {
173479ac375Sdm sasl_interact_t *interact;
174479ac375Sdm
175479ac375Sdm if (prompts == NULL || flags != LDAP_SASL_INTERACTIVE)
176479ac375Sdm return (LDAP_PARAM_ERROR);
177479ac375Sdm
178479ac375Sdm /* There should be no extra arguemnts for SASL/GSSAPI authentication */
179479ac375Sdm for (interact = prompts; interact->id != SASL_CB_LIST_END;
180479ac375Sdm interact++) {
181479ac375Sdm interact->result = NULL;
182479ac375Sdm interact->len = 0;
183479ac375Sdm }
184479ac375Sdm return (LDAP_SUCCESS);
185479ac375Sdm }
186479ac375Sdm
187479ac375Sdm static
188479ac375Sdm idmap_stat
idmap_open_ad_conn(idmap_nm_handle_t * adh)18961b364a9Sjp idmap_open_ad_conn(idmap_nm_handle_t *adh)
190479ac375Sdm {
191479ac375Sdm int zero = 0;
192479ac375Sdm int timeoutms = 30 * 1000;
193479ac375Sdm int ldversion, ldap_rc;
194479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
195479ac375Sdm
196479ac375Sdm /* Open and bind an LDAP connection */
197479ac375Sdm adh->ad = ldap_init(adh->ad_host, adh->ad_port);
198479ac375Sdm if (adh->ad == NULL) {
199c5866007SKeyur Desai namemap_log(
200c5866007SKeyur Desai gettext("ldap_init() to server %s port %d failed. (%s)"),
201c5866007SKeyur Desai CHECK_NULL(adh->ad_host),
202479ac375Sdm adh->ad_port, strerror(errno));
203479ac375Sdm rc = IDMAP_ERR_INTERNAL;
204479ac375Sdm goto out;
205479ac375Sdm }
206479ac375Sdm ldversion = LDAP_VERSION3;
207479ac375Sdm (void) ldap_set_option(adh->ad, LDAP_OPT_PROTOCOL_VERSION, &ldversion);
208479ac375Sdm (void) ldap_set_option(adh->ad, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
209479ac375Sdm (void) ldap_set_option(adh->ad, LDAP_OPT_TIMELIMIT, &zero);
210479ac375Sdm (void) ldap_set_option(adh->ad, LDAP_OPT_SIZELIMIT, &zero);
211479ac375Sdm (void) ldap_set_option(adh->ad, LDAP_X_OPT_CONNECT_TIMEOUT, &timeoutms);
212479ac375Sdm (void) ldap_set_option(adh->ad, LDAP_OPT_RESTART, LDAP_OPT_ON);
213479ac375Sdm ldap_rc = ldap_sasl_interactive_bind_s(adh->ad, "" /* binddn */,
214479ac375Sdm adh->saslmech, NULL, NULL, adh->saslflags, &idmap_saslcallback,
215479ac375Sdm NULL);
216479ac375Sdm
217479ac375Sdm if (ldap_rc != LDAP_SUCCESS) {
218479ac375Sdm (void) ldap_unbind(adh->ad);
219479ac375Sdm adh->ad = NULL;
220c5866007SKeyur Desai namemap_log(
221c5866007SKeyur Desai gettext("ldap_sasl_interactive_bind_s() to server "
222c5866007SKeyur Desai "%s port %d failed. (%s)"), CHECK_NULL(adh->ad_host),
22361b364a9Sjp adh->ad_port, ldap_err2string(ldap_rc));
224479ac375Sdm rc = IDMAP_ERR_INTERNAL;
225479ac375Sdm }
226479ac375Sdm
227479ac375Sdm out:
228479ac375Sdm return (rc);
229479ac375Sdm }
230479ac375Sdm
231479ac375Sdm static
232479ac375Sdm idmap_stat
idmap_init_nldap(idmap_nm_handle_t * p)23361b364a9Sjp idmap_init_nldap(idmap_nm_handle_t *p)
234479ac375Sdm {
23561b364a9Sjp /*
23661b364a9Sjp * For now, there is nothing to initialize in nldap. This is just to
23761b364a9Sjp * make it future-proof, especially standalone libsldap-proof
23861b364a9Sjp */
23961b364a9Sjp p->is_nldap = TRUE;
24061b364a9Sjp return (0);
241479ac375Sdm }
242479ac375Sdm
243479ac375Sdm static
244479ac375Sdm idmap_stat
idmap_init_ad(idmap_nm_handle_t * p)24561b364a9Sjp idmap_init_ad(idmap_nm_handle_t *p)
246479ac375Sdm {
247479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
248b3700b07SGordon Ross ad_disc_ds_t *dc = NULL;
249479ac375Sdm ad_disc_t ad_ctx;
250479ac375Sdm
251479ac375Sdm ad_ctx = ad_disc_init();
252479ac375Sdm if (ad_ctx == NULL) {
253c5866007SKeyur Desai namemap_log(
254479ac375Sdm gettext("AD autodiscovery initialization failed"));
255479ac375Sdm return (IDMAP_ERR_INTERNAL);
256479ac375Sdm }
257479ac375Sdm ad_disc_refresh(ad_ctx);
258479ac375Sdm
259479ac375Sdm
260479ac375Sdm /* Based on the supplied or default domain, find the proper AD: */
26161b364a9Sjp if (ad_disc_set_DomainName(ad_ctx, p->windomain)) {
262479ac375Sdm rc = IDMAP_ERR_INTERNAL;
263c5866007SKeyur Desai namemap_log(
264479ac375Sdm gettext("Setting a domain name \"%s\" for autodiscovery"
26561b364a9Sjp " failed, most likely not enough memory"), p->windomain);
266479ac375Sdm goto cleanup;
267479ac375Sdm }
268479ac375Sdm
2694d61c878SJulian Pullen dc = ad_disc_get_DomainController(ad_ctx, AD_DISC_GLOBAL, NULL);
270479ac375Sdm if (dc == NULL) {
271479ac375Sdm rc = IDMAP_ERR_ARG;
272c5866007SKeyur Desai namemap_log(
273479ac375Sdm gettext("A domain controller for the "
27461b364a9Sjp "domain \"%s\" not found."), p->windomain);
275479ac375Sdm goto cleanup;
276479ac375Sdm }
277479ac375Sdm
278479ac375Sdm
279479ac375Sdm p->ad_port = dc->port;
280479ac375Sdm p->ad_host = strdup(dc->host);
281479ac375Sdm
282479ac375Sdm if (p->ad_host == NULL) {
283479ac375Sdm rc = IDMAP_ERR_MEMORY;
284479ac375Sdm goto cleanup;
285479ac375Sdm }
286479ac375Sdm
287479ac375Sdm p->saslflags = LDAP_SASL_INTERACTIVE;
288479ac375Sdm p->saslmech = strdup("GSSAPI");
289479ac375Sdm
290479ac375Sdm if (p->saslmech == NULL) {
291479ac375Sdm rc = IDMAP_ERR_MEMORY;
292479ac375Sdm goto cleanup;
293479ac375Sdm }
294479ac375Sdm
295479ac375Sdm rc = idmap_open_ad_conn(p);
296479ac375Sdm
297479ac375Sdm if (rc != IDMAP_SUCCESS)
298479ac375Sdm goto cleanup;
299479ac375Sdm
30061b364a9Sjp p->is_ad = TRUE;
301479ac375Sdm
302479ac375Sdm cleanup:
303479ac375Sdm ad_disc_fini(ad_ctx);
304479ac375Sdm free(dc);
305479ac375Sdm return (rc);
306479ac375Sdm }
307479ac375Sdm
30861b364a9Sjp void
idmap_fini_namemaps(idmap_nm_handle_t * p)30961b364a9Sjp idmap_fini_namemaps(idmap_nm_handle_t *p)
310479ac375Sdm {
31161b364a9Sjp if (p == NULL)
31261b364a9Sjp return;
313479ac375Sdm
31461b364a9Sjp if (p->ad_unixgroup_attr != NULL)
31561b364a9Sjp free(p->ad_unixgroup_attr);
316479ac375Sdm
31761b364a9Sjp if (p->ad_unixuser_attr != NULL)
31861b364a9Sjp free(p->ad_unixuser_attr);
31961b364a9Sjp
32061b364a9Sjp if (p->nldap_winname_attr)
32161b364a9Sjp free(p->nldap_winname_attr);
32261b364a9Sjp
32361b364a9Sjp if (p->windomain != NULL)
32461b364a9Sjp free(p->windomain);
32561b364a9Sjp
32661b364a9Sjp if (p->default_domain != NULL)
32761b364a9Sjp free(p->default_domain);
32861b364a9Sjp
32961b364a9Sjp if (p->saslmech != NULL)
33061b364a9Sjp free(p->saslmech);
33161b364a9Sjp
33261b364a9Sjp if (p->ad_host != NULL)
33361b364a9Sjp free(p->ad_host);
33461b364a9Sjp
33561b364a9Sjp if (p->nsc.cred.unix_cred.userID != NULL) {
33661b364a9Sjp free(p->nsc.cred.unix_cred.userID);
337479ac375Sdm }
338479ac375Sdm
33961b364a9Sjp if (p->nsc.cred.unix_cred.passwd != NULL) {
34061b364a9Sjp /* No archeology: */
34161b364a9Sjp (void) memset(p->nsc.cred.unix_cred.passwd, 0,
34261b364a9Sjp strlen(p->nsc.cred.unix_cred.passwd));
34361b364a9Sjp free(p->nsc.cred.unix_cred.passwd);
34461b364a9Sjp }
345479ac375Sdm
346479ac375Sdm if (p->ad)
347479ac375Sdm (void) ldap_unbind(p->ad);
348479ac375Sdm free(p);
349479ac375Sdm
350479ac375Sdm }
351479ac375Sdm
352479ac375Sdm
35361b364a9Sjp
35461b364a9Sjp idmap_stat
idmap_init_namemaps(idmap_nm_handle_t ** adh,char * user,char * passwd,char * auth,char * windomain,int direction)3551fdeec65Sjoyce mcintosh idmap_init_namemaps(idmap_nm_handle_t **adh,
35661b364a9Sjp char *user, char *passwd, char *auth, char *windomain,
35761b364a9Sjp int direction)
35861b364a9Sjp {
35961b364a9Sjp idmap_stat rc;
36061b364a9Sjp idmap_nm_handle_t *p;
36161b364a9Sjp
36261b364a9Sjp p = (idmap_nm_handle_t *)calloc(1, sizeof (idmap_nm_handle_t));
36361b364a9Sjp if (p == NULL)
36461b364a9Sjp return (IDMAP_ERR_MEMORY);
36561b364a9Sjp
3661fdeec65Sjoyce mcintosh rc = idmap_get_prop_str(PROP_DEFAULT_DOMAIN,
36761b364a9Sjp &p->default_domain);
36861b364a9Sjp if (rc != IDMAP_SUCCESS) {
369c5866007SKeyur Desai namemap_log(
37061b364a9Sjp gettext("Error obtaining default domain from idmapd (%s)"),
3711fdeec65Sjoyce mcintosh idmap_stat2string(rc));
37261b364a9Sjp goto cleanup;
37361b364a9Sjp }
37461b364a9Sjp
3751fdeec65Sjoyce mcintosh rc = idmap_get_prop_str(PROP_AD_UNIXUSER_ATTR,
37661b364a9Sjp &p->ad_unixuser_attr);
37761b364a9Sjp if (rc != IDMAP_SUCCESS) {
378c5866007SKeyur Desai namemap_log(
37961b364a9Sjp gettext("Error obtaining AD unixuser attribute (%s)"),
3801fdeec65Sjoyce mcintosh idmap_stat2string(rc));
38161b364a9Sjp goto cleanup;
38261b364a9Sjp }
38361b364a9Sjp
3841fdeec65Sjoyce mcintosh rc = idmap_get_prop_str(PROP_AD_UNIXGROUP_ATTR,
38561b364a9Sjp &p->ad_unixgroup_attr);
38661b364a9Sjp if (rc != IDMAP_SUCCESS) {
387c5866007SKeyur Desai namemap_log(
38861b364a9Sjp gettext("Error obtaining AD unixgroup attribute (%s)"),
3891fdeec65Sjoyce mcintosh idmap_stat2string(rc));
39061b364a9Sjp goto cleanup;
39161b364a9Sjp }
39261b364a9Sjp
39361b364a9Sjp
3941fdeec65Sjoyce mcintosh rc = idmap_get_prop_str(PROP_NLDAP_WINNAME_ATTR,
39561b364a9Sjp &p->nldap_winname_attr);
39661b364a9Sjp if (rc != IDMAP_SUCCESS) {
397c5866007SKeyur Desai namemap_log(
39861b364a9Sjp gettext("Error obtaining AD unixgroup attribute (%s)"),
3991fdeec65Sjoyce mcintosh idmap_stat2string(rc));
40061b364a9Sjp goto cleanup;
40161b364a9Sjp }
40261b364a9Sjp
40361b364a9Sjp if (windomain != NULL) {
40461b364a9Sjp p->windomain = strdup(windomain);
40561b364a9Sjp if (p->windomain == NULL) {
40661b364a9Sjp rc = IDMAP_ERR_MEMORY;
40761b364a9Sjp goto cleanup;
40861b364a9Sjp }
40961b364a9Sjp } else if (!EMPTY_STRING(p->default_domain)) {
41061b364a9Sjp p->windomain = strdup(p->default_domain);
41161b364a9Sjp if (p->windomain == NULL) {
41261b364a9Sjp rc = IDMAP_ERR_MEMORY;
41361b364a9Sjp goto cleanup;
41461b364a9Sjp }
41561b364a9Sjp } else if (direction == IDMAP_DIRECTION_W2U) {
416c5866007SKeyur Desai namemap_log(
41761b364a9Sjp gettext("Windows domain not given and idmapd daemon"
41861b364a9Sjp " didn't provide a default one"));
41961b364a9Sjp rc = IDMAP_ERR_ARG;
42061b364a9Sjp goto cleanup;
42161b364a9Sjp }
42261b364a9Sjp
42361b364a9Sjp p->direction = direction;
42461b364a9Sjp
42561b364a9Sjp if ((p->ad_unixuser_attr != NULL || p->ad_unixgroup_attr != NULL) &&
42661b364a9Sjp direction != IDMAP_DIRECTION_U2W) {
42761b364a9Sjp rc = idmap_init_ad(p);
42861b364a9Sjp if (rc != IDMAP_SUCCESS) {
42961b364a9Sjp goto cleanup;
43061b364a9Sjp }
43161b364a9Sjp }
43261b364a9Sjp
43361b364a9Sjp if (p->nldap_winname_attr != NULL && direction != IDMAP_DIRECTION_W2U) {
43461b364a9Sjp rc = idmap_init_nldap(p);
43561b364a9Sjp if (rc != IDMAP_SUCCESS) {
43661b364a9Sjp goto cleanup;
43761b364a9Sjp }
43861b364a9Sjp
43961b364a9Sjp rc = strings2cred(&p->nsc, user, passwd, auth);
44061b364a9Sjp if (rc != IDMAP_SUCCESS) {
44161b364a9Sjp goto cleanup;
44261b364a9Sjp }
44361b364a9Sjp }
44461b364a9Sjp
44561b364a9Sjp cleanup:
44661b364a9Sjp
44761b364a9Sjp if (rc == IDMAP_SUCCESS) {
44861b364a9Sjp *adh = p;
44961b364a9Sjp return (IDMAP_SUCCESS);
45061b364a9Sjp }
45161b364a9Sjp
45261b364a9Sjp /* There was an error: */
45361b364a9Sjp idmap_fini_namemaps(*adh);
45461b364a9Sjp return (rc);
45561b364a9Sjp }
45661b364a9Sjp
457479ac375Sdm static
458479ac375Sdm char *
dns2dn(const char * dns,const char * prefix)459479ac375Sdm dns2dn(const char *dns, const char *prefix)
460479ac375Sdm {
461479ac375Sdm int num_lvl = 1;
462479ac375Sdm char *buf;
463479ac375Sdm const char *it, *new_it;
464479ac375Sdm
465479ac375Sdm for (it = dns; it != NULL; it = strchr(it, '.')) {
466479ac375Sdm it ++;
467479ac375Sdm num_lvl ++;
468479ac375Sdm }
469479ac375Sdm
470479ac375Sdm buf = (char *)malloc(strlen(prefix) + strlen(dns) + 4 * num_lvl);
471479ac375Sdm (void) strcpy(buf, prefix);
472479ac375Sdm
473479ac375Sdm
474479ac375Sdm it = dns;
475479ac375Sdm for (;;) {
476479ac375Sdm new_it = strchr(it, '.');
477479ac375Sdm (void) strcat(buf, "DC=");
478479ac375Sdm if (new_it == NULL) {
479479ac375Sdm (void) strcat(buf, it);
480479ac375Sdm break;
481479ac375Sdm } else {
482479ac375Sdm (void) strncat(buf, it, new_it - it);
483479ac375Sdm (void) strcat(buf, ",");
484479ac375Sdm }
485479ac375Sdm
486479ac375Sdm it = new_it + 1;
487479ac375Sdm }
488479ac375Sdm
489479ac375Sdm return (buf);
490479ac375Sdm }
491479ac375Sdm
492479ac375Sdm
493479ac375Sdm static
494479ac375Sdm idmap_stat
extract_attribute(idmap_nm_handle_t * p,LDAPMessage * entry,char * name,char ** value)49561b364a9Sjp extract_attribute(idmap_nm_handle_t *p, LDAPMessage *entry, char *name,
49661b364a9Sjp char **value)
497479ac375Sdm {
498479ac375Sdm char **values = NULL;
499479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
500479ac375Sdm /* No value means it is not requested */
501479ac375Sdm if (value == NULL)
502479ac375Sdm return (IDMAP_SUCCESS);
503479ac375Sdm
504479ac375Sdm values = ldap_get_values(p->ad, entry, name);
505479ac375Sdm if (values == NULL || values[0] == NULL)
506479ac375Sdm *value = NULL;
507479ac375Sdm else {
508479ac375Sdm *value = strdup(values[0]);
509479ac375Sdm if (*value == NULL)
510479ac375Sdm rc = IDMAP_ERR_MEMORY;
511479ac375Sdm }
512479ac375Sdm errout:
513479ac375Sdm ldap_value_free(values);
514479ac375Sdm return (rc);
515479ac375Sdm }
516479ac375Sdm
517479ac375Sdm
518479ac375Sdm /* Split winname to its name and domain part */
519479ac375Sdm static
520479ac375Sdm idmap_stat
split_fqwn(char * fqwn,char ** name,char ** domain)521479ac375Sdm split_fqwn(char *fqwn, char **name, char **domain)
522479ac375Sdm {
523479ac375Sdm char *at;
524479ac375Sdm
525479ac375Sdm *name = NULL;
526479ac375Sdm *domain = NULL;
527479ac375Sdm
528479ac375Sdm at = strchr(fqwn, '@');
529479ac375Sdm if (at == NULL) {
530479ac375Sdm at = strchr(fqwn, '\\');
531479ac375Sdm }
532479ac375Sdm if (at == NULL) {
533479ac375Sdm /* There is no domain - leave domain NULL */
534479ac375Sdm *name = strdup(fqwn);
535479ac375Sdm if (*name == NULL)
536479ac375Sdm goto errout;
537479ac375Sdm return (IDMAP_SUCCESS);
538479ac375Sdm }
539479ac375Sdm
540479ac375Sdm
541479ac375Sdm *domain = strdup(at+1);
542479ac375Sdm if (*domain == NULL)
543479ac375Sdm goto errout;
544479ac375Sdm *name = (char *)malloc(at - fqwn + 1);
545479ac375Sdm if (*name == NULL)
546479ac375Sdm goto errout;
547479ac375Sdm (void) strlcpy(*name, fqwn, at - fqwn + 1);
548479ac375Sdm
549479ac375Sdm if (*at == '\\') {
550479ac375Sdm char *it = *name;
551479ac375Sdm *name = *domain;
552479ac375Sdm *domain = it;
553479ac375Sdm }
554479ac375Sdm
555479ac375Sdm return (IDMAP_SUCCESS);
556479ac375Sdm
557479ac375Sdm
558479ac375Sdm errout:
559479ac375Sdm free(*name);
560479ac375Sdm *name = NULL;
561479ac375Sdm free(*domain);
562479ac375Sdm *domain = NULL;
563479ac375Sdm return (IDMAP_ERR_MEMORY);
564479ac375Sdm }
565479ac375Sdm
566479ac375Sdm static
567479ac375Sdm idmap_stat
unixname2dn(idmap_nm_handle_t * p,char * unixname,int is_user,char ** dn,char ** winname,char ** windomain)56861b364a9Sjp unixname2dn(idmap_nm_handle_t *p, char *unixname, int is_user, char **dn,
569479ac375Sdm char **winname, char **windomain)
570479ac375Sdm {
571479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
572479ac375Sdm int rc_ns;
573479ac375Sdm
574479ac375Sdm
575479ac375Sdm char filter[255];
576479ac375Sdm static const char *attribs[3];
577479ac375Sdm ns_ldap_result_t *res;
578479ac375Sdm ns_ldap_error_t *errorp = NULL;
579479ac375Sdm char **attrs;
580479ac375Sdm
581479ac375Sdm
582479ac375Sdm attribs[0] = p->nldap_winname_attr;
583479ac375Sdm attribs[1] = "dn";
584479ac375Sdm attribs[2] = NULL;
585479ac375Sdm
586479ac375Sdm (void) snprintf(filter, sizeof (filter), is_user ? "uid=%s" : "cn=%s",
587479ac375Sdm unixname);
588479ac375Sdm
589479ac375Sdm rc_ns = __ns_ldap_list(is_user ? "passwd" : "group",
590479ac375Sdm filter, NULL, attribs, NULL, 0, &res, &errorp, NULL, NULL);
591479ac375Sdm
592479ac375Sdm
593479ac375Sdm if (rc_ns == NS_LDAP_NOTFOUND) {
594c5866007SKeyur Desai namemap_log(is_user ? gettext("User %s not found.")
595479ac375Sdm : gettext("Group %s not found."), unixname);
596479ac375Sdm return (IDMAP_ERR_NOTFOUND);
597479ac375Sdm } else if (rc_ns != NS_LDAP_SUCCESS) {
598479ac375Sdm char *msg = "Cause unidentified";
599479ac375Sdm if (errorp != NULL) {
600479ac375Sdm (void) __ns_ldap_err2str(errorp->status, &msg);
601479ac375Sdm }
602c5866007SKeyur Desai namemap_log(gettext("Ldap list failed (%s)."), msg);
603479ac375Sdm return (IDMAP_ERR_ARG);
604479ac375Sdm }
605479ac375Sdm
606479ac375Sdm if (res == NULL) {
607c5866007SKeyur Desai namemap_log(gettext("User %s not found"), unixname);
608479ac375Sdm return (IDMAP_ERR_ARG);
609479ac375Sdm }
610479ac375Sdm
611479ac375Sdm if (winname != NULL && windomain != NULL) {
612479ac375Sdm attrs = __ns_ldap_getAttr(&res->entry[0],
613479ac375Sdm p->nldap_winname_attr);
614479ac375Sdm if (attrs != NULL && attrs[0] != NULL) {
615479ac375Sdm rc = split_fqwn(attrs[0], winname, windomain);
616479ac375Sdm } else {
617479ac375Sdm *winname = *windomain = NULL;
618479ac375Sdm }
619479ac375Sdm }
620479ac375Sdm
621479ac375Sdm if (dn != NULL) {
622479ac375Sdm attrs = __ns_ldap_getAttr(&res->entry[0], "dn");
623479ac375Sdm if (attrs == NULL || attrs[0] == NULL) {
624c5866007SKeyur Desai namemap_log(gettext("dn for %s not found"),
625479ac375Sdm unixname);
626479ac375Sdm return (IDMAP_ERR_ARG);
627479ac375Sdm }
628479ac375Sdm *dn = strdup(attrs[0]);
629479ac375Sdm }
630479ac375Sdm
631479ac375Sdm
632479ac375Sdm return (rc);
633479ac375Sdm
634479ac375Sdm }
635479ac375Sdm
636479ac375Sdm #define FILTER "(sAMAccountName=%s)"
637479ac375Sdm
638479ac375Sdm /* Puts the values of attributes to unixuser and unixgroup, unless NULL */
639479ac375Sdm
640479ac375Sdm static
641479ac375Sdm idmap_stat
winname2dn(idmap_nm_handle_t * p,char * winname,int * is_wuser,char ** dn,char ** unixuser,char ** unixgroup)64261b364a9Sjp winname2dn(idmap_nm_handle_t *p, char *winname,
643479ac375Sdm int *is_wuser, char **dn, char **unixuser, char **unixgroup)
644479ac375Sdm {
645479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
646479ac375Sdm char *base;
647479ac375Sdm char *filter;
648479ac375Sdm int flen;
649479ac375Sdm char *attribs[4];
650479ac375Sdm int i;
651479ac375Sdm LDAPMessage *results = NULL;
652479ac375Sdm LDAPMessage *entry;
653479ac375Sdm int ldap_rc;
654479ac375Sdm
655479ac375Sdm /* Query: */
656479ac375Sdm
657479ac375Sdm base = dns2dn(p->windomain, "");
658479ac375Sdm if (base == NULL) {
659479ac375Sdm return (IDMAP_ERR_MEMORY);
660479ac375Sdm }
661479ac375Sdm
662479ac375Sdm i = 0;
663479ac375Sdm attribs[i++] = "objectClass";
664479ac375Sdm if (unixuser != NULL)
665479ac375Sdm attribs[i++] = p->ad_unixuser_attr;
666479ac375Sdm if (unixgroup != NULL)
667479ac375Sdm attribs[i++] = p->ad_unixgroup_attr;
668479ac375Sdm attribs[i] = NULL;
669479ac375Sdm
670479ac375Sdm flen = snprintf(NULL, 0, FILTER, winname) + 1;
671479ac375Sdm if ((filter = (char *)malloc(flen)) == NULL) {
672479ac375Sdm free(base);
673479ac375Sdm return (IDMAP_ERR_MEMORY);
674479ac375Sdm }
675479ac375Sdm (void) snprintf(filter, flen, FILTER, winname);
676479ac375Sdm
677479ac375Sdm ldap_rc = ldap_search_s(p->ad, base, LDAP_SCOPE_SUBTREE, filter,
678479ac375Sdm attribs, 0, &results);
679479ac375Sdm
680479ac375Sdm free(base);
681479ac375Sdm free(filter);
682479ac375Sdm
683479ac375Sdm if (ldap_rc != LDAP_SUCCESS) {
684c5866007SKeyur Desai namemap_log(
685c5866007SKeyur Desai gettext("Ldap query to server %s port %d failed. (%s)"),
686479ac375Sdm p->ad_host, p->ad_port, ldap_err2string(ldap_rc));
687479ac375Sdm (void) ldap_msgfree(results);
688479ac375Sdm return (IDMAP_ERR_OTHER);
689479ac375Sdm }
690479ac375Sdm
691479ac375Sdm
692479ac375Sdm for (entry = ldap_first_entry(p->ad, results), *dn = NULL;
693479ac375Sdm entry != NULL;
694479ac375Sdm entry = ldap_next_entry(p->ad, entry)) {
695479ac375Sdm char **values = NULL;
696479ac375Sdm int i = 0;
697479ac375Sdm values = ldap_get_values(p->ad, entry, "objectClass");
698479ac375Sdm
699479ac375Sdm if (values == NULL) {
700479ac375Sdm (void) ldap_msgfree(results);
701479ac375Sdm return (IDMAP_ERR_MEMORY);
702479ac375Sdm }
703479ac375Sdm
704479ac375Sdm for (i = 0; i < ldap_count_values(values); i++) {
705479ac375Sdm /*
706479ac375Sdm * is_wuser can be IDMAP_UNKNOWN, in that case we accept
707479ac375Sdm * both User/Group
708479ac375Sdm */
709479ac375Sdm if (*is_wuser != IDMAP_NO &&
710479ac375Sdm strcasecmp(values[i], "User") == 0 ||
711479ac375Sdm *is_wuser != IDMAP_YES &&
712479ac375Sdm strcasecmp(values[i], "Group") == 0) {
713479ac375Sdm *dn = ldap_get_dn(p->ad, entry);
714479ac375Sdm if (*dn == NULL) {
715479ac375Sdm ldap_value_free(values);
716479ac375Sdm (void) ldap_msgfree(results);
717479ac375Sdm return (IDMAP_ERR_MEMORY);
718479ac375Sdm }
719479ac375Sdm *is_wuser = strcasecmp(values[i], "User") == 0
720479ac375Sdm ? IDMAP_YES : IDMAP_NO;
721479ac375Sdm break;
722479ac375Sdm }
723479ac375Sdm }
724479ac375Sdm
725479ac375Sdm ldap_value_free(values);
726479ac375Sdm if (*dn != NULL)
727479ac375Sdm break;
728479ac375Sdm }
729479ac375Sdm
730479ac375Sdm if (*dn == NULL) {
731c5866007SKeyur Desai namemap_log(
732479ac375Sdm *is_wuser == IDMAP_YES ? gettext("User %s@%s not found") :
733479ac375Sdm *is_wuser == IDMAP_NO ? gettext("Group %s@%s not found") :
734479ac375Sdm gettext("%s@%s not found"), winname, p->windomain);
735479ac375Sdm return (IDMAP_ERR_NOTFOUND);
736479ac375Sdm }
737479ac375Sdm
738479ac375Sdm if (unixuser != NULL)
739479ac375Sdm rc = extract_attribute(p, entry, p->ad_unixuser_attr,
740479ac375Sdm unixuser);
741479ac375Sdm
742479ac375Sdm if (rc == IDMAP_SUCCESS && unixgroup != NULL)
743479ac375Sdm rc = extract_attribute(p, entry, p->ad_unixgroup_attr,
744479ac375Sdm unixgroup);
745479ac375Sdm
746479ac375Sdm (void) ldap_msgfree(results);
747479ac375Sdm
748479ac375Sdm return (rc);
749479ac375Sdm }
750479ac375Sdm
751479ac375Sdm
752479ac375Sdm /* set the given attribute to the given value. If value is NULL, unset it */
753479ac375Sdm static
754479ac375Sdm idmap_stat
idmap_ad_set(idmap_nm_handle_t * p,char * dn,char * attr,char * value)75561b364a9Sjp idmap_ad_set(idmap_nm_handle_t *p, char *dn, char *attr, char *value)
756479ac375Sdm {
757479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
758479ac375Sdm int ldap_rc;
759479ac375Sdm char *new_values[2] = {NULL, NULL};
760479ac375Sdm LDAPMod *mods[2] = {NULL, NULL};
761479ac375Sdm
762479ac375Sdm mods[0] = (LDAPMod *)calloc(1, sizeof (LDAPMod));
763479ac375Sdm mods[0]->mod_type = strdup(attr);
764479ac375Sdm if (value != NULL) {
765479ac375Sdm mods[0]->mod_op = LDAP_MOD_REPLACE;
766479ac375Sdm new_values[0] = strdup(value);
767479ac375Sdm mods[0]->mod_values = new_values;
768479ac375Sdm } else {
769479ac375Sdm mods[0]->mod_op = LDAP_MOD_DELETE;
770479ac375Sdm mods[0]->mod_values = NULL;
771479ac375Sdm }
772479ac375Sdm
773479ac375Sdm ldap_rc = ldap_modify_s(p->ad, dn, mods);
774479ac375Sdm if (ldap_rc != LDAP_SUCCESS) {
775c5866007SKeyur Desai namemap_log(
776c5866007SKeyur Desai gettext("Ldap modify of %s, attribute %s failed. (%s)"),
777479ac375Sdm dn, attr, ldap_err2string(ldap_rc));
778479ac375Sdm rc = IDMAP_ERR_INTERNAL;
779479ac375Sdm }
780479ac375Sdm
781479ac375Sdm
782479ac375Sdm ldap_mods_free(mods, 0);
783479ac375Sdm return (rc);
784479ac375Sdm }
785479ac375Sdm
786479ac375Sdm
787479ac375Sdm /*
788479ac375Sdm * This function takes the p argument just for the beauty of the symmetry
789479ac375Sdm * with idmap_ad_set (and for future enhancements).
790479ac375Sdm */
791479ac375Sdm static
792479ac375Sdm idmap_stat
793479ac375Sdm /* LINTED E_FUNC_ARG_UNUSED */
idmap_nldap_set(idmap_nm_handle_t * p,ns_cred_t * nsc,char * dn,char * attr,char * value,bool_t is_new,int is_user)79461b364a9Sjp idmap_nldap_set(idmap_nm_handle_t *p, ns_cred_t *nsc, char *dn, char *attr,
795479ac375Sdm char *value, bool_t is_new, int is_user)
796479ac375Sdm {
797479ac375Sdm int ldaprc;
798479ac375Sdm ns_ldap_error_t *errorp = NULL;
799479ac375Sdm ns_ldap_attr_t *attrs[2];
800479ac375Sdm
801479ac375Sdm
802479ac375Sdm
803479ac375Sdm attrs[0] = (ns_ldap_attr_t *)malloc(sizeof (ns_ldap_attr_t));
804479ac375Sdm if (attrs == NULL)
805479ac375Sdm return (IDMAP_ERR_MEMORY);
806479ac375Sdm
807479ac375Sdm attrs[0]->attrname = attr;
808479ac375Sdm
809479ac375Sdm if (value != NULL) {
810479ac375Sdm char **newattr = (char **)calloc(2, sizeof (char *));
811479ac375Sdm if (newattr == NULL) {
812479ac375Sdm free(attrs[0]);
813479ac375Sdm return (IDMAP_ERR_MEMORY);
814479ac375Sdm }
815479ac375Sdm newattr[0] = value;
816479ac375Sdm newattr[1] = NULL;
817479ac375Sdm
818479ac375Sdm attrs[0]->attrvalue = newattr;
819479ac375Sdm attrs[0]->value_count = 1;
820479ac375Sdm } else {
821479ac375Sdm attrs[0]->attrvalue = NULL;
822479ac375Sdm attrs[0]->value_count = 0;
823479ac375Sdm }
824479ac375Sdm
825479ac375Sdm
826479ac375Sdm attrs[1] = NULL;
827479ac375Sdm
828479ac375Sdm if (value == NULL) {
829479ac375Sdm ldaprc = __ns_ldap_delAttr(
830479ac375Sdm is_user == IDMAP_YES ? "passwd": "group",
831479ac375Sdm dn, (const ns_ldap_attr_t * const *)attrs,
832479ac375Sdm nsc, 0, &errorp);
833479ac375Sdm } else if (is_new)
834479ac375Sdm ldaprc = __ns_ldap_addAttr(
835479ac375Sdm is_user == IDMAP_YES ? "passwd": "group",
836479ac375Sdm dn, (const ns_ldap_attr_t * const *)attrs,
837479ac375Sdm nsc, 0, &errorp);
838479ac375Sdm else
839479ac375Sdm ldaprc = __ns_ldap_repAttr(
840479ac375Sdm is_user == IDMAP_YES ? "passwd": "group",
841479ac375Sdm dn, (const ns_ldap_attr_t * const *)attrs,
842479ac375Sdm nsc, 0, &errorp);
843479ac375Sdm
844479ac375Sdm if (ldaprc != NS_LDAP_SUCCESS) {
845479ac375Sdm char *msg = "Cause unidentified";
846479ac375Sdm if (errorp != NULL) {
847479ac375Sdm (void) __ns_ldap_err2str(errorp->status, &msg);
848479ac375Sdm }
849c5866007SKeyur Desai namemap_log(
850c5866007SKeyur Desai gettext("__ns_ldap_addAttr/rep/delAttr failed (%s)"),
851c5866007SKeyur Desai msg);
852479ac375Sdm return (IDMAP_ERR_ARG);
853479ac375Sdm }
854479ac375Sdm
855479ac375Sdm return (IDMAP_SUCCESS);
856479ac375Sdm }
857479ac375Sdm
858479ac375Sdm idmap_stat
idmap_set_namemap(idmap_nm_handle_t * p,char * winname,char * unixname,int is_user,int is_wuser,int direction)85961b364a9Sjp idmap_set_namemap(idmap_nm_handle_t *p, char *winname, char *unixname,
86061b364a9Sjp int is_user, int is_wuser, int direction)
861479ac375Sdm {
862479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
863479ac375Sdm char *dn = NULL;
864479ac375Sdm char *oldwinname = NULL;
865479ac375Sdm char *oldwindomain = NULL;
866479ac375Sdm
86761b364a9Sjp if (direction == IDMAP_DIRECTION_W2U) {
86861b364a9Sjp if (!p->is_ad) {
86961b364a9Sjp rc = IDMAP_ERR_ARG;
870c5866007SKeyur Desai namemap_log(
87161b364a9Sjp gettext("AD namemaps aren't set up."));
872479ac375Sdm goto cleanup;
873479ac375Sdm }
874479ac375Sdm
875479ac375Sdm rc = winname2dn(p, winname, &is_wuser,
876479ac375Sdm &dn, NULL, NULL);
877479ac375Sdm if (rc != IDMAP_SUCCESS)
878479ac375Sdm goto cleanup;
879479ac375Sdm
880479ac375Sdm rc = idmap_ad_set(p, dn, is_user ? p->ad_unixuser_attr :
881479ac375Sdm p->ad_unixgroup_attr, unixname);
882479ac375Sdm if (rc != IDMAP_SUCCESS)
883479ac375Sdm goto cleanup;
884479ac375Sdm
885479ac375Sdm }
886479ac375Sdm
887479ac375Sdm
88861b364a9Sjp if (direction == IDMAP_DIRECTION_U2W) {
889479ac375Sdm char *fullname;
890479ac375Sdm
89161b364a9Sjp if (!p->is_nldap) {
89261b364a9Sjp rc = IDMAP_ERR_ARG;
893c5866007SKeyur Desai namemap_log(
89461b364a9Sjp gettext("Native ldap namemaps aren't set up."));
895479ac375Sdm goto cleanup;
896479ac375Sdm }
897479ac375Sdm
89861b364a9Sjp
899479ac375Sdm rc = unixname2dn(p, unixname, is_user, &dn,
900479ac375Sdm &oldwinname, &oldwindomain);
901479ac375Sdm if (rc != IDMAP_SUCCESS)
902479ac375Sdm goto cleanup;
903479ac375Sdm
904479ac375Sdm if (p->windomain == NULL) {
905479ac375Sdm fullname = strdup(winname);
9063ad44b67SToomas Soome if (fullname == NULL) {
907479ac375Sdm rc = IDMAP_ERR_MEMORY;
908479ac375Sdm goto cleanup;
9093ad44b67SToomas Soome }
910479ac375Sdm } else {
911479ac375Sdm fullname = malloc(strlen(winname) +
912479ac375Sdm strlen(p->windomain) + 2);
913479ac375Sdm if (fullname == NULL) {
914479ac375Sdm rc = IDMAP_ERR_MEMORY;
915479ac375Sdm goto cleanup;
916479ac375Sdm }
917479ac375Sdm
918479ac375Sdm (void) snprintf(fullname,
919479ac375Sdm strlen(winname) + strlen(p->windomain) + 2,
920479ac375Sdm "%s\\%s", p->windomain, winname);
921479ac375Sdm }
92261b364a9Sjp rc = idmap_nldap_set(p, &p->nsc, dn, p->nldap_winname_attr,
923479ac375Sdm fullname, oldwinname == NULL ? TRUE : FALSE, is_user);
924479ac375Sdm
925479ac375Sdm free(fullname);
926479ac375Sdm free(oldwindomain);
927479ac375Sdm free(oldwinname);
928479ac375Sdm
929479ac375Sdm if (rc != IDMAP_SUCCESS)
930479ac375Sdm goto cleanup;
931479ac375Sdm
932479ac375Sdm }
933479ac375Sdm
934479ac375Sdm cleanup:
93561b364a9Sjp if (dn != NULL)
93661b364a9Sjp free(dn);
93761b364a9Sjp
93861b364a9Sjp if (oldwindomain != NULL)
93961b364a9Sjp free(oldwindomain);
94061b364a9Sjp
94161b364a9Sjp if (oldwinname != NULL)
94261b364a9Sjp free(oldwinname);
94361b364a9Sjp
944479ac375Sdm return (rc);
945479ac375Sdm
946479ac375Sdm }
947479ac375Sdm
94861b364a9Sjp
949479ac375Sdm idmap_stat
idmap_unset_namemap(idmap_nm_handle_t * p,char * winname,char * unixname,int is_user,int is_wuser,int direction)95061b364a9Sjp idmap_unset_namemap(idmap_nm_handle_t *p, char *winname, char *unixname,
95161b364a9Sjp int is_user, int is_wuser, int direction)
952479ac375Sdm {
953479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
954479ac375Sdm char *dn = NULL;
955479ac375Sdm char *oldwinname = NULL;
956479ac375Sdm char *oldwindomain = NULL;
957479ac375Sdm
958479ac375Sdm if (direction == IDMAP_DIRECTION_W2U) {
959479ac375Sdm if (!p->is_ad) {
960479ac375Sdm rc = IDMAP_ERR_ARG;
961c5866007SKeyur Desai namemap_log(
962479ac375Sdm gettext("AD namemaps aren't set up."));
963479ac375Sdm goto cleanup;
964479ac375Sdm }
965479ac375Sdm
966479ac375Sdm rc = winname2dn(p, winname, &is_wuser,
967479ac375Sdm &dn, NULL, NULL);
968479ac375Sdm if (rc != IDMAP_SUCCESS)
969479ac375Sdm goto cleanup;
970479ac375Sdm
971479ac375Sdm rc = idmap_ad_set(p, dn, is_user ? p->ad_unixuser_attr :
972479ac375Sdm p->ad_unixgroup_attr, unixname);
973479ac375Sdm if (rc != IDMAP_SUCCESS)
974479ac375Sdm goto cleanup;
975479ac375Sdm
976479ac375Sdm } else { /* direction == IDMAP_DIRECTION_U2W */
977479ac375Sdm if (!p->is_nldap) {
978479ac375Sdm rc = IDMAP_ERR_ARG;
979c5866007SKeyur Desai namemap_log(
980479ac375Sdm gettext("Native ldap namemaps aren't set up."));
981479ac375Sdm goto cleanup;
982479ac375Sdm }
983479ac375Sdm
984479ac375Sdm rc = unixname2dn(p, unixname, is_user, &dn, NULL, NULL);
985479ac375Sdm if (rc != IDMAP_SUCCESS)
986479ac375Sdm goto cleanup;
987479ac375Sdm
98861b364a9Sjp rc = idmap_nldap_set(p, &p->nsc, dn, p->nldap_winname_attr,
98961b364a9Sjp NULL, TRUE, is_user);
990479ac375Sdm if (rc != IDMAP_SUCCESS)
991479ac375Sdm goto cleanup;
992479ac375Sdm
993479ac375Sdm }
994479ac375Sdm
995479ac375Sdm cleanup:
99661b364a9Sjp if (oldwindomain != NULL)
99761b364a9Sjp free(oldwindomain);
99861b364a9Sjp if (oldwinname != NULL)
99961b364a9Sjp free(oldwinname);
100061b364a9Sjp if (dn != NULL)
100161b364a9Sjp free(dn);
1002479ac375Sdm return (rc);
1003479ac375Sdm }
1004479ac375Sdm
1005479ac375Sdm idmap_stat
idmap_get_namemap(idmap_nm_handle_t * p,int * is_source_ad,char ** winname,char ** windomain,int * is_wuser,char ** unixuser,char ** unixgroup)100661b364a9Sjp idmap_get_namemap(idmap_nm_handle_t *p, int *is_source_ad, char **winname,
100761b364a9Sjp char **windomain, int *is_wuser, char **unixuser, char **unixgroup)
100861b364a9Sjp {
1009479ac375Sdm idmap_stat rc = IDMAP_SUCCESS;
1010479ac375Sdm char *dn = NULL;
1011479ac375Sdm
1012479ac375Sdm *is_source_ad = IDMAP_UNKNOWN;
101361b364a9Sjp if (*winname != NULL) {
1014479ac375Sdm *is_source_ad = IDMAP_YES;
1015479ac375Sdm
1016*ef826847SToomas Soome if (p->is_ad == FALSE) {
1017479ac375Sdm rc = IDMAP_ERR_ARG;
1018c5866007SKeyur Desai namemap_log(
101961b364a9Sjp gettext("AD namemaps are not active."));
1020479ac375Sdm goto cleanup;
102161b364a9Sjp /* In future maybe resolve winname and try nldap? */
1022479ac375Sdm }
1023479ac375Sdm
1024479ac375Sdm rc = winname2dn(p, *winname, is_wuser, &dn, unixuser,
1025479ac375Sdm unixgroup);
102661b364a9Sjp if (rc != IDMAP_SUCCESS) {
1027c5866007SKeyur Desai namemap_log(
102861b364a9Sjp gettext("Winname %s@%s not found in AD."),
102961b364a9Sjp *winname, p->windomain);
103061b364a9Sjp }
103161b364a9Sjp } else if (*unixuser != NULL || *unixgroup != NULL) {
1032479ac375Sdm char *unixname;
1033479ac375Sdm int is_user;
1034479ac375Sdm
1035479ac375Sdm *is_source_ad = IDMAP_NO;
1036479ac375Sdm
1037*ef826847SToomas Soome if (p->is_nldap == FALSE) {
103861b364a9Sjp rc = IDMAP_ERR_ARG;
1039c5866007SKeyur Desai namemap_log(
104061b364a9Sjp gettext("Native ldap namemaps aren't active."));
104161b364a9Sjp goto cleanup;
104261b364a9Sjp /* In future maybe resolve unixname and try AD? */
104361b364a9Sjp }
104461b364a9Sjp
1045479ac375Sdm if (*unixuser != NULL) {
1046479ac375Sdm is_user = IDMAP_YES;
1047479ac375Sdm unixname = *unixuser;
1048479ac375Sdm } else if (*unixgroup != NULL) {
1049479ac375Sdm is_user = IDMAP_NO;
1050479ac375Sdm unixname = *unixgroup;
1051479ac375Sdm }
1052479ac375Sdm
1053479ac375Sdm rc = unixname2dn(p, unixname, is_user, NULL, winname,
1054479ac375Sdm windomain);
105561b364a9Sjp if (rc != IDMAP_SUCCESS) {
1056c5866007SKeyur Desai namemap_log(
105761b364a9Sjp gettext("%s %s not found in native ldap."),
105861b364a9Sjp is_user == IDMAP_YES ? "UNIX user" : "UNIX group",
105961b364a9Sjp unixname);
1060479ac375Sdm goto cleanup;
106161b364a9Sjp }
1062479ac375Sdm } else {
1063479ac375Sdm rc = IDMAP_ERR_ARG;
1064479ac375Sdm goto cleanup;
1065479ac375Sdm }
1066479ac375Sdm
1067479ac375Sdm cleanup:
1068479ac375Sdm return (rc);
1069479ac375Sdm }
1070