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