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.
24dafb549fSGordon Ross * Copyright 2019 Nexenta Systems, Inc. All rights reserved.
25*b6b7639aSGordon Ross * Copyright 2022 RackTop Systems, Inc.
26148c5f43SAlan Wright */
27148c5f43SAlan Wright
28148c5f43SAlan Wright /*
29148c5f43SAlan Wright * LSA lookups
30148c5f43SAlan Wright */
31148c5f43SAlan Wright
32148c5f43SAlan Wright #include <stdio.h>
33148c5f43SAlan Wright #include <note.h>
34148c5f43SAlan Wright #include <assert.h>
35148c5f43SAlan Wright
36148c5f43SAlan Wright #include "idmapd.h"
37148c5f43SAlan Wright #include "libsmb.h"
38148c5f43SAlan Wright
39148c5f43SAlan Wright idmap_retcode
idmap_lsa_xlate_sid_type(const lsa_account_t * acct,idmap_id_type * ret_type)40148c5f43SAlan Wright idmap_lsa_xlate_sid_type(const lsa_account_t *acct, idmap_id_type *ret_type)
41148c5f43SAlan Wright {
42148c5f43SAlan Wright switch (acct->a_sidtype) {
43148c5f43SAlan Wright case SidTypeUser:
44148c5f43SAlan Wright case SidTypeComputer:
45148c5f43SAlan Wright case SidTypeDomain:
46148c5f43SAlan Wright case SidTypeDeletedAccount:
47148c5f43SAlan Wright case SidTypeUnknown:
48148c5f43SAlan Wright case SidTypeLabel:
49148c5f43SAlan Wright *ret_type = IDMAP_USID;
50148c5f43SAlan Wright return (IDMAP_SUCCESS);
51148c5f43SAlan Wright case SidTypeGroup:
52148c5f43SAlan Wright case SidTypeAlias:
53148c5f43SAlan Wright case SidTypeWellKnownGroup:
54148c5f43SAlan Wright *ret_type = IDMAP_GSID;
55148c5f43SAlan Wright return (IDMAP_SUCCESS);
56148c5f43SAlan Wright case SidTypeNull:
57148c5f43SAlan Wright case SidTypeInvalid:
58148c5f43SAlan Wright default:
59148c5f43SAlan Wright idmapdlog(LOG_WARNING,
60148c5f43SAlan Wright "LSA lookup: bad type %d for %s@%s",
61148c5f43SAlan Wright acct->a_sidtype, acct->a_name, acct->a_domain);
62148c5f43SAlan Wright return (IDMAP_ERR_OTHER);
63148c5f43SAlan Wright }
64148c5f43SAlan Wright NOTE(NOTREACHED)
65148c5f43SAlan Wright }
66148c5f43SAlan Wright
67148c5f43SAlan Wright /* Given SID, look up name and type */
68148c5f43SAlan Wright idmap_retcode
lookup_lsa_by_sid(const char * sidprefix,uint32_t rid,char ** ret_name,char ** ret_domain,idmap_id_type * ret_type)69148c5f43SAlan Wright lookup_lsa_by_sid(
70148c5f43SAlan Wright const char *sidprefix,
71148c5f43SAlan Wright uint32_t rid,
72148c5f43SAlan Wright char **ret_name,
73148c5f43SAlan Wright char **ret_domain,
74148c5f43SAlan Wright idmap_id_type *ret_type)
75148c5f43SAlan Wright {
76148c5f43SAlan Wright lsa_account_t acct;
77148c5f43SAlan Wright char sid[SMB_SID_STRSZ + 1];
78148c5f43SAlan Wright idmap_retcode ret;
79148c5f43SAlan Wright int rc;
80148c5f43SAlan Wright
81148c5f43SAlan Wright (void) memset(&acct, 0, sizeof (acct));
82148c5f43SAlan Wright *ret_name = NULL;
83148c5f43SAlan Wright *ret_domain = NULL;
84148c5f43SAlan Wright
85148c5f43SAlan Wright (void) snprintf(sid, sizeof (sid), "%s-%u", sidprefix, rid);
86148c5f43SAlan Wright
87dafb549fSGordon Ross rc = smb_lookup_lsid(sid, &acct);
88148c5f43SAlan Wright if (rc != 0) {
89dafb549fSGordon Ross idmapdlog(LOG_ERR, "Error: SMB lookup SID failed.");
90148c5f43SAlan Wright idmapdlog(LOG_ERR,
91148c5f43SAlan Wright "Check SMB service (svc:/network/smb/server).");
92148c5f43SAlan Wright idmapdlog(LOG_ERR,
93148c5f43SAlan Wright "Check connectivity to Active Directory.");
94148c5f43SAlan Wright
95148c5f43SAlan Wright ret = IDMAP_ERR_OTHER;
96148c5f43SAlan Wright goto out;
97148c5f43SAlan Wright }
98148c5f43SAlan Wright if (acct.a_status == NT_STATUS_NONE_MAPPED) {
99148c5f43SAlan Wright ret = IDMAP_ERR_NOTFOUND;
100148c5f43SAlan Wright goto out;
101148c5f43SAlan Wright }
102148c5f43SAlan Wright if (acct.a_status != NT_STATUS_SUCCESS) {
103148c5f43SAlan Wright idmapdlog(LOG_WARNING,
104dafb549fSGordon Ross "Warning: SMB lookup SID(%s) failed (0x%x)",
105148c5f43SAlan Wright sid, acct.a_status);
106148c5f43SAlan Wright /* Fail soft */
107148c5f43SAlan Wright ret = IDMAP_ERR_NOTFOUND;
108148c5f43SAlan Wright goto out;
109148c5f43SAlan Wright }
110148c5f43SAlan Wright
111148c5f43SAlan Wright ret = idmap_lsa_xlate_sid_type(&acct, ret_type);
112148c5f43SAlan Wright if (ret != IDMAP_SUCCESS)
113148c5f43SAlan Wright goto out;
114148c5f43SAlan Wright
115148c5f43SAlan Wright *ret_name = strdup(acct.a_name);
116148c5f43SAlan Wright if (*ret_name == NULL) {
117148c5f43SAlan Wright ret = IDMAP_ERR_MEMORY;
118148c5f43SAlan Wright goto out;
119148c5f43SAlan Wright }
120148c5f43SAlan Wright
121148c5f43SAlan Wright *ret_domain = strdup(acct.a_domain);
122148c5f43SAlan Wright if (*ret_domain == NULL) {
123148c5f43SAlan Wright ret = IDMAP_ERR_MEMORY;
124148c5f43SAlan Wright goto out;
125148c5f43SAlan Wright }
126148c5f43SAlan Wright
127148c5f43SAlan Wright ret = IDMAP_SUCCESS;
128148c5f43SAlan Wright
129148c5f43SAlan Wright out:
130148c5f43SAlan Wright if (ret != IDMAP_SUCCESS) {
131148c5f43SAlan Wright free(*ret_name);
132148c5f43SAlan Wright *ret_name = NULL;
133148c5f43SAlan Wright free(*ret_domain);
134148c5f43SAlan Wright *ret_domain = NULL;
135148c5f43SAlan Wright }
136148c5f43SAlan Wright return (ret);
137148c5f43SAlan Wright }
138148c5f43SAlan Wright
139148c5f43SAlan Wright /* Given name and optional domain, look up SID, type, and canonical name */
140148c5f43SAlan Wright 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)141148c5f43SAlan Wright lookup_lsa_by_name(
142148c5f43SAlan Wright const char *name,
143148c5f43SAlan Wright const char *domain,
144148c5f43SAlan Wright char **ret_sidprefix,
145148c5f43SAlan Wright uint32_t *ret_rid,
146148c5f43SAlan Wright char **ret_name,
147148c5f43SAlan Wright char **ret_domain,
148148c5f43SAlan Wright idmap_id_type *ret_type)
149148c5f43SAlan Wright {
150148c5f43SAlan Wright lsa_account_t acct;
151148c5f43SAlan Wright char *namedom = NULL;
152148c5f43SAlan Wright idmap_retcode ret;
153148c5f43SAlan Wright int rc;
154148c5f43SAlan Wright
155148c5f43SAlan Wright (void) memset(&acct, 0, sizeof (acct));
156148c5f43SAlan Wright *ret_sidprefix = NULL;
157148c5f43SAlan Wright if (ret_name != NULL)
158148c5f43SAlan Wright *ret_name = NULL;
159148c5f43SAlan Wright if (ret_domain != NULL)
160148c5f43SAlan Wright *ret_domain = NULL;
161148c5f43SAlan Wright
162148c5f43SAlan Wright if (domain != NULL)
163148c5f43SAlan Wright (void) asprintf(&namedom, "%s@%s", name, domain);
164148c5f43SAlan Wright else
165148c5f43SAlan Wright namedom = strdup(name);
166148c5f43SAlan Wright if (namedom == NULL) {
167148c5f43SAlan Wright ret = IDMAP_ERR_MEMORY;
168148c5f43SAlan Wright goto out;
169148c5f43SAlan Wright }
170148c5f43SAlan Wright
171dafb549fSGordon Ross rc = smb_lookup_lname(namedom, SidTypeUnknown, &acct);
172148c5f43SAlan Wright if (rc != 0) {
173dafb549fSGordon Ross idmapdlog(LOG_ERR, "Error: SMB lookup name failed.");
174148c5f43SAlan Wright idmapdlog(LOG_ERR,
175148c5f43SAlan Wright "Check SMB service (svc:/network/smb/server).");
176148c5f43SAlan Wright idmapdlog(LOG_ERR,
177148c5f43SAlan Wright "Check connectivity to Active Directory.");
178148c5f43SAlan Wright ret = IDMAP_ERR_OTHER;
179148c5f43SAlan Wright goto out;
180148c5f43SAlan Wright }
181148c5f43SAlan Wright if (acct.a_status == NT_STATUS_NONE_MAPPED) {
182148c5f43SAlan Wright ret = IDMAP_ERR_NOTFOUND;
183148c5f43SAlan Wright goto out;
184148c5f43SAlan Wright }
185148c5f43SAlan Wright if (acct.a_status != NT_STATUS_SUCCESS) {
186148c5f43SAlan Wright idmapdlog(LOG_WARNING,
187dafb549fSGordon Ross "Warning: SMB lookup name(%s) failed (0x%x)",
188148c5f43SAlan Wright namedom, acct.a_status);
189148c5f43SAlan Wright /* Fail soft */
190148c5f43SAlan Wright ret = IDMAP_ERR_NOTFOUND;
191148c5f43SAlan Wright goto out;
192148c5f43SAlan Wright }
193148c5f43SAlan Wright
194148c5f43SAlan Wright rc = smb_sid_splitstr(acct.a_sid, ret_rid);
195148c5f43SAlan Wright assert(rc == 0);
196148c5f43SAlan Wright *ret_sidprefix = strdup(acct.a_sid);
197148c5f43SAlan Wright if (*ret_sidprefix == NULL) {
198148c5f43SAlan Wright ret = IDMAP_ERR_MEMORY;
199148c5f43SAlan Wright goto out;
200148c5f43SAlan Wright }
201148c5f43SAlan Wright
202148c5f43SAlan Wright ret = idmap_lsa_xlate_sid_type(&acct, ret_type);
203148c5f43SAlan Wright if (ret != IDMAP_SUCCESS)
204148c5f43SAlan Wright goto out;
205148c5f43SAlan Wright
206148c5f43SAlan Wright if (ret_name != NULL) {
207148c5f43SAlan Wright *ret_name = strdup(acct.a_name);
208148c5f43SAlan Wright if (*ret_name == NULL) {
209148c5f43SAlan Wright ret = IDMAP_ERR_MEMORY;
210148c5f43SAlan Wright goto out;
211148c5f43SAlan Wright }
212148c5f43SAlan Wright }
213148c5f43SAlan Wright
214148c5f43SAlan Wright if (ret_domain != NULL) {
215148c5f43SAlan Wright *ret_domain = strdup(acct.a_domain);
216148c5f43SAlan Wright if (*ret_domain == NULL) {
217148c5f43SAlan Wright ret = IDMAP_ERR_MEMORY;
218148c5f43SAlan Wright goto out;
219148c5f43SAlan Wright }
220148c5f43SAlan Wright }
221148c5f43SAlan Wright
222148c5f43SAlan Wright ret = IDMAP_SUCCESS;
223148c5f43SAlan Wright
224148c5f43SAlan Wright out:
225148c5f43SAlan Wright free(namedom);
226148c5f43SAlan Wright if (ret != IDMAP_SUCCESS) {
227148c5f43SAlan Wright if (ret_name != NULL) {
228148c5f43SAlan Wright free(*ret_name);
229148c5f43SAlan Wright *ret_name = NULL;
230148c5f43SAlan Wright }
231148c5f43SAlan Wright if (ret_domain != NULL) {
232148c5f43SAlan Wright free(*ret_domain);
233148c5f43SAlan Wright *ret_domain = NULL;
234148c5f43SAlan Wright }
235148c5f43SAlan Wright free(*ret_sidprefix);
236148c5f43SAlan Wright *ret_sidprefix = NULL;
237148c5f43SAlan Wright }
238148c5f43SAlan Wright return (ret);
239148c5f43SAlan Wright }
240b3700b07SGordon Ross
241b3700b07SGordon Ross /*
242b3700b07SGordon Ross * This exists just so we can avoid exposing all of idmapd to libsmb.h.
243b3700b07SGordon Ross * Like the above functions, it's a door call over to smbd.
244b3700b07SGordon Ross */
245b3700b07SGordon Ross void
notify_dc_changed(void)246b3700b07SGordon Ross notify_dc_changed(void)
247b3700b07SGordon Ross {
248*b6b7639aSGordon Ross int rc;
249*b6b7639aSGordon Ross rc = smb_notify_dc_changed();
250*b6b7639aSGordon Ross if (rc != 0) {
251*b6b7639aSGordon Ross idmapdlog(LOG_WARNING,
252*b6b7639aSGordon Ross "Warning: smb_notify_dc_changed, rc=%d", rc);
253*b6b7639aSGordon Ross }
254b3700b07SGordon Ross }
255