1*148c5f43SAlan Wright /*
2*148c5f43SAlan Wright  * CDDL HEADER START
3*148c5f43SAlan Wright  *
4*148c5f43SAlan Wright  * The contents of this file are subject to the terms of the
5*148c5f43SAlan Wright  * Common Development and Distribution License (the "License").
6*148c5f43SAlan Wright  * You may not use this file except in compliance with the License.
7*148c5f43SAlan Wright  *
8*148c5f43SAlan Wright  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*148c5f43SAlan Wright  * or http://www.opensolaris.org/os/licensing.
10*148c5f43SAlan Wright  * See the License for the specific language governing permissions
11*148c5f43SAlan Wright  * and limitations under the License.
12*148c5f43SAlan Wright  *
13*148c5f43SAlan Wright  * When distributing Covered Code, include this CDDL HEADER in each
14*148c5f43SAlan Wright  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*148c5f43SAlan Wright  * If applicable, add the following below this CDDL HEADER, with the
16*148c5f43SAlan Wright  * fields enclosed by brackets "[]" replaced with your own identifying
17*148c5f43SAlan Wright  * information: Portions Copyright [yyyy] [name of copyright owner]
18*148c5f43SAlan Wright  *
19*148c5f43SAlan Wright  * CDDL HEADER END
20*148c5f43SAlan Wright  */
21*148c5f43SAlan Wright 
22*148c5f43SAlan Wright /*
23*148c5f43SAlan Wright  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*148c5f43SAlan Wright  */
25*148c5f43SAlan Wright 
26*148c5f43SAlan Wright /*
27*148c5f43SAlan Wright  * LSA lookups
28*148c5f43SAlan Wright  */
29*148c5f43SAlan Wright 
30*148c5f43SAlan Wright #include <stdio.h>
31*148c5f43SAlan Wright #include <note.h>
32*148c5f43SAlan Wright #include <assert.h>
33*148c5f43SAlan Wright 
34*148c5f43SAlan Wright #include "idmapd.h"
35*148c5f43SAlan Wright #include "libsmb.h"
36*148c5f43SAlan Wright 
37*148c5f43SAlan Wright idmap_retcode
38*148c5f43SAlan Wright idmap_lsa_xlate_sid_type(const lsa_account_t *acct, idmap_id_type *ret_type)
39*148c5f43SAlan Wright {
40*148c5f43SAlan Wright 	switch (acct->a_sidtype) {
41*148c5f43SAlan Wright 	case SidTypeUser:
42*148c5f43SAlan Wright 	case SidTypeComputer:
43*148c5f43SAlan Wright 	case SidTypeDomain:
44*148c5f43SAlan Wright 	case SidTypeDeletedAccount:
45*148c5f43SAlan Wright 	case SidTypeUnknown:
46*148c5f43SAlan Wright 	case SidTypeLabel:
47*148c5f43SAlan Wright 		*ret_type = IDMAP_USID;
48*148c5f43SAlan Wright 		return (IDMAP_SUCCESS);
49*148c5f43SAlan Wright 	case SidTypeGroup:
50*148c5f43SAlan Wright 	case SidTypeAlias:
51*148c5f43SAlan Wright 	case SidTypeWellKnownGroup:
52*148c5f43SAlan Wright 		*ret_type = IDMAP_GSID;
53*148c5f43SAlan Wright 		return (IDMAP_SUCCESS);
54*148c5f43SAlan Wright 	case SidTypeNull:
55*148c5f43SAlan Wright 	case SidTypeInvalid:
56*148c5f43SAlan Wright 	default:
57*148c5f43SAlan Wright 		idmapdlog(LOG_WARNING,
58*148c5f43SAlan Wright 		    "LSA lookup:  bad type %d for %s@%s",
59*148c5f43SAlan Wright 		    acct->a_sidtype, acct->a_name, acct->a_domain);
60*148c5f43SAlan Wright 		return (IDMAP_ERR_OTHER);
61*148c5f43SAlan Wright 	}
62*148c5f43SAlan Wright 	NOTE(NOTREACHED)
63*148c5f43SAlan Wright }
64*148c5f43SAlan Wright 
65*148c5f43SAlan Wright /* Given SID, look up name and type */
66*148c5f43SAlan Wright idmap_retcode
67*148c5f43SAlan Wright lookup_lsa_by_sid(
68*148c5f43SAlan Wright     const char *sidprefix,
69*148c5f43SAlan Wright     uint32_t rid,
70*148c5f43SAlan Wright     char **ret_name,
71*148c5f43SAlan Wright     char **ret_domain,
72*148c5f43SAlan Wright     idmap_id_type *ret_type)
73*148c5f43SAlan Wright {
74*148c5f43SAlan Wright 	lsa_account_t acct;
75*148c5f43SAlan Wright 	char sid[SMB_SID_STRSZ + 1];
76*148c5f43SAlan Wright 	idmap_retcode ret;
77*148c5f43SAlan Wright 	int rc;
78*148c5f43SAlan Wright 
79*148c5f43SAlan Wright 	(void) memset(&acct, 0, sizeof (acct));
80*148c5f43SAlan Wright 	*ret_name = NULL;
81*148c5f43SAlan Wright 	*ret_domain = NULL;
82*148c5f43SAlan Wright 
83*148c5f43SAlan Wright 	(void) snprintf(sid, sizeof (sid), "%s-%u", sidprefix, rid);
84*148c5f43SAlan Wright 
85*148c5f43SAlan Wright 	rc = smb_lookup_sid(sid, &acct);
86*148c5f43SAlan Wright 	if (rc != 0) {
87*148c5f43SAlan Wright 		idmapdlog(LOG_ERR, "Error:  smb_lookup_sid failed.");
88*148c5f43SAlan Wright 		idmapdlog(LOG_ERR,
89*148c5f43SAlan Wright 		    "Check SMB service (svc:/network/smb/server).");
90*148c5f43SAlan Wright 		idmapdlog(LOG_ERR,
91*148c5f43SAlan Wright 		    "Check connectivity to Active Directory.");
92*148c5f43SAlan Wright 
93*148c5f43SAlan Wright 		ret = IDMAP_ERR_OTHER;
94*148c5f43SAlan Wright 		goto out;
95*148c5f43SAlan Wright 	}
96*148c5f43SAlan Wright 	if (acct.a_status == NT_STATUS_NONE_MAPPED) {
97*148c5f43SAlan Wright 		ret = IDMAP_ERR_NOTFOUND;
98*148c5f43SAlan Wright 		goto out;
99*148c5f43SAlan Wright 	}
100*148c5f43SAlan Wright 	if (acct.a_status != NT_STATUS_SUCCESS) {
101*148c5f43SAlan Wright 		idmapdlog(LOG_WARNING,
102*148c5f43SAlan Wright 		    "Warning:  smb_lookup_sid(%s) failed (0x%x)",
103*148c5f43SAlan Wright 		    sid, acct.a_status);
104*148c5f43SAlan Wright 		/* Fail soft */
105*148c5f43SAlan Wright 		ret = IDMAP_ERR_NOTFOUND;
106*148c5f43SAlan Wright 		goto out;
107*148c5f43SAlan Wright 	}
108*148c5f43SAlan Wright 
109*148c5f43SAlan Wright 	ret = idmap_lsa_xlate_sid_type(&acct, ret_type);
110*148c5f43SAlan Wright 	if (ret != IDMAP_SUCCESS)
111*148c5f43SAlan Wright 		goto out;
112*148c5f43SAlan Wright 
113*148c5f43SAlan Wright 	*ret_name = strdup(acct.a_name);
114*148c5f43SAlan Wright 	if (*ret_name == NULL) {
115*148c5f43SAlan Wright 		ret = IDMAP_ERR_MEMORY;
116*148c5f43SAlan Wright 		goto out;
117*148c5f43SAlan Wright 	}
118*148c5f43SAlan Wright 
119*148c5f43SAlan Wright 	*ret_domain = strdup(acct.a_domain);
120*148c5f43SAlan Wright 	if (*ret_domain == NULL) {
121*148c5f43SAlan Wright 		ret = IDMAP_ERR_MEMORY;
122*148c5f43SAlan Wright 		goto out;
123*148c5f43SAlan Wright 	}
124*148c5f43SAlan Wright 
125*148c5f43SAlan Wright 	ret = IDMAP_SUCCESS;
126*148c5f43SAlan Wright 
127*148c5f43SAlan Wright out:
128*148c5f43SAlan Wright 	if (ret != IDMAP_SUCCESS) {
129*148c5f43SAlan Wright 		free(*ret_name);
130*148c5f43SAlan Wright 		*ret_name = NULL;
131*148c5f43SAlan Wright 		free(*ret_domain);
132*148c5f43SAlan Wright 		*ret_domain = NULL;
133*148c5f43SAlan Wright 	}
134*148c5f43SAlan Wright 	return (ret);
135*148c5f43SAlan Wright }
136*148c5f43SAlan Wright 
137*148c5f43SAlan Wright /* Given name and optional domain, look up SID, type, and canonical name */
138*148c5f43SAlan Wright idmap_retcode
139*148c5f43SAlan Wright lookup_lsa_by_name(
140*148c5f43SAlan Wright     const char *name,
141*148c5f43SAlan Wright     const char *domain,
142*148c5f43SAlan Wright     char **ret_sidprefix,
143*148c5f43SAlan Wright     uint32_t *ret_rid,
144*148c5f43SAlan Wright     char **ret_name,
145*148c5f43SAlan Wright     char **ret_domain,
146*148c5f43SAlan Wright     idmap_id_type *ret_type)
147*148c5f43SAlan Wright {
148*148c5f43SAlan Wright 	lsa_account_t acct;
149*148c5f43SAlan Wright 	char *namedom = NULL;
150*148c5f43SAlan Wright 	idmap_retcode ret;
151*148c5f43SAlan Wright 	int rc;
152*148c5f43SAlan Wright 
153*148c5f43SAlan Wright 	(void) memset(&acct, 0, sizeof (acct));
154*148c5f43SAlan Wright 	*ret_sidprefix = NULL;
155*148c5f43SAlan Wright 	if (ret_name != NULL)
156*148c5f43SAlan Wright 		*ret_name = NULL;
157*148c5f43SAlan Wright 	if (ret_domain != NULL)
158*148c5f43SAlan Wright 		*ret_domain = NULL;
159*148c5f43SAlan Wright 
160*148c5f43SAlan Wright 	if (domain != NULL)
161*148c5f43SAlan Wright 		(void) asprintf(&namedom, "%s@%s", name, domain);
162*148c5f43SAlan Wright 	else
163*148c5f43SAlan Wright 		namedom = strdup(name);
164*148c5f43SAlan Wright 	if (namedom == NULL) {
165*148c5f43SAlan Wright 		ret = IDMAP_ERR_MEMORY;
166*148c5f43SAlan Wright 		goto out;
167*148c5f43SAlan Wright 	}
168*148c5f43SAlan Wright 
169*148c5f43SAlan Wright 	rc = smb_lookup_name(namedom, SidTypeUnknown, &acct);
170*148c5f43SAlan Wright 	if (rc != 0) {
171*148c5f43SAlan Wright 		idmapdlog(LOG_ERR, "Error:  smb_lookup_name failed.");
172*148c5f43SAlan Wright 		idmapdlog(LOG_ERR,
173*148c5f43SAlan Wright 		    "Check SMB service (svc:/network/smb/server).");
174*148c5f43SAlan Wright 		idmapdlog(LOG_ERR,
175*148c5f43SAlan Wright 		    "Check connectivity to Active Directory.");
176*148c5f43SAlan Wright 		ret = IDMAP_ERR_OTHER;
177*148c5f43SAlan Wright 		goto out;
178*148c5f43SAlan Wright 	}
179*148c5f43SAlan Wright 	if (acct.a_status == NT_STATUS_NONE_MAPPED) {
180*148c5f43SAlan Wright 		ret = IDMAP_ERR_NOTFOUND;
181*148c5f43SAlan Wright 		goto out;
182*148c5f43SAlan Wright 	}
183*148c5f43SAlan Wright 	if (acct.a_status != NT_STATUS_SUCCESS) {
184*148c5f43SAlan Wright 		idmapdlog(LOG_WARNING,
185*148c5f43SAlan Wright 		    "Warning:  smb_lookup_name(%s) failed (0x%x)",
186*148c5f43SAlan Wright 		    namedom, acct.a_status);
187*148c5f43SAlan Wright 		/* Fail soft */
188*148c5f43SAlan Wright 		ret = IDMAP_ERR_NOTFOUND;
189*148c5f43SAlan Wright 		goto out;
190*148c5f43SAlan Wright 	}
191*148c5f43SAlan Wright 
192*148c5f43SAlan Wright 	rc = smb_sid_splitstr(acct.a_sid, ret_rid);
193*148c5f43SAlan Wright 	assert(rc == 0);
194*148c5f43SAlan Wright 	*ret_sidprefix = strdup(acct.a_sid);
195*148c5f43SAlan Wright 	if (*ret_sidprefix == NULL) {
196*148c5f43SAlan Wright 		ret = IDMAP_ERR_MEMORY;
197*148c5f43SAlan Wright 		goto out;
198*148c5f43SAlan Wright 	}
199*148c5f43SAlan Wright 
200*148c5f43SAlan Wright 	ret = idmap_lsa_xlate_sid_type(&acct, ret_type);
201*148c5f43SAlan Wright 	if (ret != IDMAP_SUCCESS)
202*148c5f43SAlan Wright 		goto out;
203*148c5f43SAlan Wright 
204*148c5f43SAlan Wright 	if (ret_name != NULL) {
205*148c5f43SAlan Wright 		*ret_name = strdup(acct.a_name);
206*148c5f43SAlan Wright 		if (*ret_name == NULL) {
207*148c5f43SAlan Wright 			ret = IDMAP_ERR_MEMORY;
208*148c5f43SAlan Wright 			goto out;
209*148c5f43SAlan Wright 		}
210*148c5f43SAlan Wright 	}
211*148c5f43SAlan Wright 
212*148c5f43SAlan Wright 	if (ret_domain != NULL) {
213*148c5f43SAlan Wright 		*ret_domain = strdup(acct.a_domain);
214*148c5f43SAlan Wright 		if (*ret_domain == NULL) {
215*148c5f43SAlan Wright 			ret = IDMAP_ERR_MEMORY;
216*148c5f43SAlan Wright 			goto out;
217*148c5f43SAlan Wright 		}
218*148c5f43SAlan Wright 	}
219*148c5f43SAlan Wright 
220*148c5f43SAlan Wright 	ret = IDMAP_SUCCESS;
221*148c5f43SAlan Wright 
222*148c5f43SAlan Wright out:
223*148c5f43SAlan Wright 	free(namedom);
224*148c5f43SAlan Wright 	if (ret != IDMAP_SUCCESS) {
225*148c5f43SAlan Wright 		if (ret_name != NULL) {
226*148c5f43SAlan Wright 			free(*ret_name);
227*148c5f43SAlan Wright 			*ret_name = NULL;
228*148c5f43SAlan Wright 		}
229*148c5f43SAlan Wright 		if (ret_domain != NULL) {
230*148c5f43SAlan Wright 			free(*ret_domain);
231*148c5f43SAlan Wright 			*ret_domain = NULL;
232*148c5f43SAlan Wright 		}
233*148c5f43SAlan Wright 		free(*ret_sidprefix);
234*148c5f43SAlan Wright 		*ret_sidprefix = NULL;
235*148c5f43SAlan Wright 	}
236*148c5f43SAlan Wright 	return (ret);
237*148c5f43SAlan Wright }
238