xref: /titanic_52/usr/src/cmd/idmap/idmapd/idmap_lsa.c (revision b3700b074e637f8c6991b70754c88a2cfffb246b)
1148c5f43SAlan Wright /*
2148c5f43SAlan Wright  * CDDL HEADER START
3148c5f43SAlan Wright  *
4148c5f43SAlan Wright  * The contents of this file are subject to the terms of the
5148c5f43SAlan Wright  * Common Development and Distribution License (the "License").
6148c5f43SAlan Wright  * You may not use this file except in compliance with the License.
7148c5f43SAlan Wright  *
8148c5f43SAlan Wright  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9148c5f43SAlan Wright  * or http://www.opensolaris.org/os/licensing.
10148c5f43SAlan Wright  * See the License for the specific language governing permissions
11148c5f43SAlan Wright  * and limitations under the License.
12148c5f43SAlan Wright  *
13148c5f43SAlan Wright  * When distributing Covered Code, include this CDDL HEADER in each
14148c5f43SAlan Wright  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15148c5f43SAlan Wright  * If applicable, add the following below this CDDL HEADER, with the
16148c5f43SAlan Wright  * fields enclosed by brackets "[]" replaced with your own identifying
17148c5f43SAlan Wright  * information: Portions Copyright [yyyy] [name of copyright owner]
18148c5f43SAlan Wright  *
19148c5f43SAlan Wright  * CDDL HEADER END
20148c5f43SAlan Wright  */
21148c5f43SAlan Wright 
22148c5f43SAlan Wright /*
23148c5f43SAlan Wright  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*b3700b07SGordon Ross  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
25148c5f43SAlan Wright  */
26148c5f43SAlan Wright 
27148c5f43SAlan Wright /*
28148c5f43SAlan Wright  * LSA lookups
29148c5f43SAlan Wright  */
30148c5f43SAlan Wright 
31148c5f43SAlan Wright #include <stdio.h>
32148c5f43SAlan Wright #include <note.h>
33148c5f43SAlan Wright #include <assert.h>
34148c5f43SAlan Wright 
35148c5f43SAlan Wright #include "idmapd.h"
36148c5f43SAlan Wright #include "libsmb.h"
37148c5f43SAlan Wright 
38148c5f43SAlan Wright idmap_retcode
39148c5f43SAlan Wright idmap_lsa_xlate_sid_type(const lsa_account_t *acct, idmap_id_type *ret_type)
40148c5f43SAlan Wright {
41148c5f43SAlan Wright 	switch (acct->a_sidtype) {
42148c5f43SAlan Wright 	case SidTypeUser:
43148c5f43SAlan Wright 	case SidTypeComputer:
44148c5f43SAlan Wright 	case SidTypeDomain:
45148c5f43SAlan Wright 	case SidTypeDeletedAccount:
46148c5f43SAlan Wright 	case SidTypeUnknown:
47148c5f43SAlan Wright 	case SidTypeLabel:
48148c5f43SAlan Wright 		*ret_type = IDMAP_USID;
49148c5f43SAlan Wright 		return (IDMAP_SUCCESS);
50148c5f43SAlan Wright 	case SidTypeGroup:
51148c5f43SAlan Wright 	case SidTypeAlias:
52148c5f43SAlan Wright 	case SidTypeWellKnownGroup:
53148c5f43SAlan Wright 		*ret_type = IDMAP_GSID;
54148c5f43SAlan Wright 		return (IDMAP_SUCCESS);
55148c5f43SAlan Wright 	case SidTypeNull:
56148c5f43SAlan Wright 	case SidTypeInvalid:
57148c5f43SAlan Wright 	default:
58148c5f43SAlan Wright 		idmapdlog(LOG_WARNING,
59148c5f43SAlan Wright 		    "LSA lookup:  bad type %d for %s@%s",
60148c5f43SAlan Wright 		    acct->a_sidtype, acct->a_name, acct->a_domain);
61148c5f43SAlan Wright 		return (IDMAP_ERR_OTHER);
62148c5f43SAlan Wright 	}
63148c5f43SAlan Wright 	NOTE(NOTREACHED)
64148c5f43SAlan Wright }
65148c5f43SAlan Wright 
66148c5f43SAlan Wright /* Given SID, look up name and type */
67148c5f43SAlan Wright idmap_retcode
68148c5f43SAlan Wright lookup_lsa_by_sid(
69148c5f43SAlan Wright     const char *sidprefix,
70148c5f43SAlan Wright     uint32_t rid,
71148c5f43SAlan Wright     char **ret_name,
72148c5f43SAlan Wright     char **ret_domain,
73148c5f43SAlan Wright     idmap_id_type *ret_type)
74148c5f43SAlan Wright {
75148c5f43SAlan Wright 	lsa_account_t acct;
76148c5f43SAlan Wright 	char sid[SMB_SID_STRSZ + 1];
77148c5f43SAlan Wright 	idmap_retcode ret;
78148c5f43SAlan Wright 	int rc;
79148c5f43SAlan Wright 
80148c5f43SAlan Wright 	(void) memset(&acct, 0, sizeof (acct));
81148c5f43SAlan Wright 	*ret_name = NULL;
82148c5f43SAlan Wright 	*ret_domain = NULL;
83148c5f43SAlan Wright 
84148c5f43SAlan Wright 	(void) snprintf(sid, sizeof (sid), "%s-%u", sidprefix, rid);
85148c5f43SAlan Wright 
86148c5f43SAlan Wright 	rc = smb_lookup_sid(sid, &acct);
87148c5f43SAlan Wright 	if (rc != 0) {
88148c5f43SAlan Wright 		idmapdlog(LOG_ERR, "Error:  smb_lookup_sid failed.");
89148c5f43SAlan Wright 		idmapdlog(LOG_ERR,
90148c5f43SAlan Wright 		    "Check SMB service (svc:/network/smb/server).");
91148c5f43SAlan Wright 		idmapdlog(LOG_ERR,
92148c5f43SAlan Wright 		    "Check connectivity to Active Directory.");
93148c5f43SAlan Wright 
94148c5f43SAlan Wright 		ret = IDMAP_ERR_OTHER;
95148c5f43SAlan Wright 		goto out;
96148c5f43SAlan Wright 	}
97148c5f43SAlan Wright 	if (acct.a_status == NT_STATUS_NONE_MAPPED) {
98148c5f43SAlan Wright 		ret = IDMAP_ERR_NOTFOUND;
99148c5f43SAlan Wright 		goto out;
100148c5f43SAlan Wright 	}
101148c5f43SAlan Wright 	if (acct.a_status != NT_STATUS_SUCCESS) {
102148c5f43SAlan Wright 		idmapdlog(LOG_WARNING,
103148c5f43SAlan Wright 		    "Warning:  smb_lookup_sid(%s) failed (0x%x)",
104148c5f43SAlan Wright 		    sid, acct.a_status);
105148c5f43SAlan Wright 		/* Fail soft */
106148c5f43SAlan Wright 		ret = IDMAP_ERR_NOTFOUND;
107148c5f43SAlan Wright 		goto out;
108148c5f43SAlan Wright 	}
109148c5f43SAlan Wright 
110148c5f43SAlan Wright 	ret = idmap_lsa_xlate_sid_type(&acct, ret_type);
111148c5f43SAlan Wright 	if (ret != IDMAP_SUCCESS)
112148c5f43SAlan Wright 		goto out;
113148c5f43SAlan Wright 
114148c5f43SAlan Wright 	*ret_name = strdup(acct.a_name);
115148c5f43SAlan Wright 	if (*ret_name == NULL) {
116148c5f43SAlan Wright 		ret = IDMAP_ERR_MEMORY;
117148c5f43SAlan Wright 		goto out;
118148c5f43SAlan Wright 	}
119148c5f43SAlan Wright 
120148c5f43SAlan Wright 	*ret_domain = strdup(acct.a_domain);
121148c5f43SAlan Wright 	if (*ret_domain == NULL) {
122148c5f43SAlan Wright 		ret = IDMAP_ERR_MEMORY;
123148c5f43SAlan Wright 		goto out;
124148c5f43SAlan Wright 	}
125148c5f43SAlan Wright 
126148c5f43SAlan Wright 	ret = IDMAP_SUCCESS;
127148c5f43SAlan Wright 
128148c5f43SAlan Wright out:
129148c5f43SAlan Wright 	if (ret != IDMAP_SUCCESS) {
130148c5f43SAlan Wright 		free(*ret_name);
131148c5f43SAlan Wright 		*ret_name = NULL;
132148c5f43SAlan Wright 		free(*ret_domain);
133148c5f43SAlan Wright 		*ret_domain = NULL;
134148c5f43SAlan Wright 	}
135148c5f43SAlan Wright 	return (ret);
136148c5f43SAlan Wright }
137148c5f43SAlan Wright 
138148c5f43SAlan Wright /* Given name and optional domain, look up SID, type, and canonical name */
139148c5f43SAlan Wright idmap_retcode
140148c5f43SAlan Wright lookup_lsa_by_name(
141148c5f43SAlan Wright     const char *name,
142148c5f43SAlan Wright     const char *domain,
143148c5f43SAlan Wright     char **ret_sidprefix,
144148c5f43SAlan Wright     uint32_t *ret_rid,
145148c5f43SAlan Wright     char **ret_name,
146148c5f43SAlan Wright     char **ret_domain,
147148c5f43SAlan Wright     idmap_id_type *ret_type)
148148c5f43SAlan Wright {
149148c5f43SAlan Wright 	lsa_account_t acct;
150148c5f43SAlan Wright 	char *namedom = NULL;
151148c5f43SAlan Wright 	idmap_retcode ret;
152148c5f43SAlan Wright 	int rc;
153148c5f43SAlan Wright 
154148c5f43SAlan Wright 	(void) memset(&acct, 0, sizeof (acct));
155148c5f43SAlan Wright 	*ret_sidprefix = NULL;
156148c5f43SAlan Wright 	if (ret_name != NULL)
157148c5f43SAlan Wright 		*ret_name = NULL;
158148c5f43SAlan Wright 	if (ret_domain != NULL)
159148c5f43SAlan Wright 		*ret_domain = NULL;
160148c5f43SAlan Wright 
161148c5f43SAlan Wright 	if (domain != NULL)
162148c5f43SAlan Wright 		(void) asprintf(&namedom, "%s@%s", name, domain);
163148c5f43SAlan Wright 	else
164148c5f43SAlan Wright 		namedom = strdup(name);
165148c5f43SAlan Wright 	if (namedom == NULL) {
166148c5f43SAlan Wright 		ret = IDMAP_ERR_MEMORY;
167148c5f43SAlan Wright 		goto out;
168148c5f43SAlan Wright 	}
169148c5f43SAlan Wright 
170148c5f43SAlan Wright 	rc = smb_lookup_name(namedom, SidTypeUnknown, &acct);
171148c5f43SAlan Wright 	if (rc != 0) {
172148c5f43SAlan Wright 		idmapdlog(LOG_ERR, "Error:  smb_lookup_name failed.");
173148c5f43SAlan Wright 		idmapdlog(LOG_ERR,
174148c5f43SAlan Wright 		    "Check SMB service (svc:/network/smb/server).");
175148c5f43SAlan Wright 		idmapdlog(LOG_ERR,
176148c5f43SAlan Wright 		    "Check connectivity to Active Directory.");
177148c5f43SAlan Wright 		ret = IDMAP_ERR_OTHER;
178148c5f43SAlan Wright 		goto out;
179148c5f43SAlan Wright 	}
180148c5f43SAlan Wright 	if (acct.a_status == NT_STATUS_NONE_MAPPED) {
181148c5f43SAlan Wright 		ret = IDMAP_ERR_NOTFOUND;
182148c5f43SAlan Wright 		goto out;
183148c5f43SAlan Wright 	}
184148c5f43SAlan Wright 	if (acct.a_status != NT_STATUS_SUCCESS) {
185148c5f43SAlan Wright 		idmapdlog(LOG_WARNING,
186148c5f43SAlan Wright 		    "Warning:  smb_lookup_name(%s) failed (0x%x)",
187148c5f43SAlan Wright 		    namedom, acct.a_status);
188148c5f43SAlan Wright 		/* Fail soft */
189148c5f43SAlan Wright 		ret = IDMAP_ERR_NOTFOUND;
190148c5f43SAlan Wright 		goto out;
191148c5f43SAlan Wright 	}
192148c5f43SAlan Wright 
193148c5f43SAlan Wright 	rc = smb_sid_splitstr(acct.a_sid, ret_rid);
194148c5f43SAlan Wright 	assert(rc == 0);
195148c5f43SAlan Wright 	*ret_sidprefix = strdup(acct.a_sid);
196148c5f43SAlan Wright 	if (*ret_sidprefix == NULL) {
197148c5f43SAlan Wright 		ret = IDMAP_ERR_MEMORY;
198148c5f43SAlan Wright 		goto out;
199148c5f43SAlan Wright 	}
200148c5f43SAlan Wright 
201148c5f43SAlan Wright 	ret = idmap_lsa_xlate_sid_type(&acct, ret_type);
202148c5f43SAlan Wright 	if (ret != IDMAP_SUCCESS)
203148c5f43SAlan Wright 		goto out;
204148c5f43SAlan Wright 
205148c5f43SAlan Wright 	if (ret_name != NULL) {
206148c5f43SAlan Wright 		*ret_name = strdup(acct.a_name);
207148c5f43SAlan Wright 		if (*ret_name == NULL) {
208148c5f43SAlan Wright 			ret = IDMAP_ERR_MEMORY;
209148c5f43SAlan Wright 			goto out;
210148c5f43SAlan Wright 		}
211148c5f43SAlan Wright 	}
212148c5f43SAlan Wright 
213148c5f43SAlan Wright 	if (ret_domain != NULL) {
214148c5f43SAlan Wright 		*ret_domain = strdup(acct.a_domain);
215148c5f43SAlan Wright 		if (*ret_domain == NULL) {
216148c5f43SAlan Wright 			ret = IDMAP_ERR_MEMORY;
217148c5f43SAlan Wright 			goto out;
218148c5f43SAlan Wright 		}
219148c5f43SAlan Wright 	}
220148c5f43SAlan Wright 
221148c5f43SAlan Wright 	ret = IDMAP_SUCCESS;
222148c5f43SAlan Wright 
223148c5f43SAlan Wright out:
224148c5f43SAlan Wright 	free(namedom);
225148c5f43SAlan Wright 	if (ret != IDMAP_SUCCESS) {
226148c5f43SAlan Wright 		if (ret_name != NULL) {
227148c5f43SAlan Wright 			free(*ret_name);
228148c5f43SAlan Wright 			*ret_name = NULL;
229148c5f43SAlan Wright 		}
230148c5f43SAlan Wright 		if (ret_domain != NULL) {
231148c5f43SAlan Wright 			free(*ret_domain);
232148c5f43SAlan Wright 			*ret_domain = NULL;
233148c5f43SAlan Wright 		}
234148c5f43SAlan Wright 		free(*ret_sidprefix);
235148c5f43SAlan Wright 		*ret_sidprefix = NULL;
236148c5f43SAlan Wright 	}
237148c5f43SAlan Wright 	return (ret);
238148c5f43SAlan Wright }
239*b3700b07SGordon Ross 
240*b3700b07SGordon Ross /*
241*b3700b07SGordon Ross  * This exists just so we can avoid exposing all of idmapd to libsmb.h.
242*b3700b07SGordon Ross  * Like the above functions, it's a door call over to smbd.
243*b3700b07SGordon Ross  */
244*b3700b07SGordon Ross void
245*b3700b07SGordon Ross notify_dc_changed(void)
246*b3700b07SGordon Ross {
247*b3700b07SGordon Ross 	smb_notify_dc_changed();
248*b3700b07SGordon Ross }
249