4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * This module provides the high level interface to the LSA RPC functions.
29 */
30
31 #include <strings.h>
32 #include <unistd.h>
33
34 #include <smbsrv/libsmb.h>
35 #include <smbsrv/libmlsvc.h>
36 #include <smbsrv/smbinfo.h>
37 #include <smbsrv/smb_token.h>
38
39 #include <lsalib.h>
40
41 static uint32_t lsa_lookup_name_builtin(char *, char *, smb_account_t *);
42 static uint32_t lsa_lookup_name_domain(char *, smb_account_t *);
43
44 static uint32_t lsa_lookup_sid_builtin(smb_sid_t *, smb_account_t *);
45 static uint32_t lsa_lookup_sid_domain(smb_sid_t *, smb_account_t *);
46
47 static uint32_t lsa_list_accounts(mlsvc_handle_t *);
48 static uint32_t lsa_map_status(uint32_t);
49
50 /*
51 * Lookup the given account and returns the account information
52 * in the passed smb_account_t structure.
53 *
54 * The lookup is performed in the following order:
55 * well known accounts
56 * local accounts
57 * domain accounts
58 *
59 * If it's established the given account is well know or local
60 * but the lookup fails for some reason, the next step(s) won't be
61 * performed.
62 *
63 * If the name is a domain account, it may refer to a user, group or
64 * alias. If it is a local account, its type should be specified
65 * in the sid_type parameter. In case the account type is unknown
66 * sid_type should be set to SidTypeUnknown.
67 *
68 * account argument could be either [domain\]name or [domain/]name.
69 *
70 * Return status:
71 *
72 * NT_STATUS_SUCCESS Account is successfully translated
73 * NT_STATUS_NONE_MAPPED Couldn't translate the account
74 */
75 uint32_t
76 lsa_lookup_name(char *account, uint16_t type, smb_account_t *info)
77 {
78 char nambuf[SMB_USERNAME_MAXLEN];
79 char dombuf[SMB_PI_MAX_DOMAIN];
80 char *name, *domain;
81 uint32_t status;
82 char *slash;
83
84 (void) strsubst(account, '/', '\\');
85 (void) strcanon(account, "\\");
86 /* \john -> john */
87 account += strspn(account, "\\");
88
89 if ((slash = strchr(account, '\\')) != NULL) {
90 *slash = '\0';
91 (void) strlcpy(dombuf, account, sizeof (dombuf));
92 (void) strlcpy(nambuf, slash + 1, sizeof (nambuf));
93 *slash = '\\';
94 name = nambuf;
95 domain = dombuf;
96 } else {
97 name = account;
98 domain = NULL;
99 }
100
101 status = lsa_lookup_name_builtin(domain, name, info);
102 if (status == NT_STATUS_NOT_FOUND) {
103 status = smb_sam_lookup_name(domain, name, type, info);
104 if (status == NT_STATUS_SUCCESS)
105 return (status);
106
107 if ((domain == NULL) || (status == NT_STATUS_NOT_FOUND))
108 status = lsa_lookup_name_domain(account, info);
109 }
110
111 return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED);
112 }
113
114 uint32_t
115 lsa_lookup_sid(smb_sid_t *sid, smb_account_t *info)
116 {
117 uint32_t status;
118
119 if (!smb_sid_isvalid(sid))
120 return (NT_STATUS_INVALID_SID);
121
122 status = lsa_lookup_sid_builtin(sid, info);
123 if (status == NT_STATUS_NOT_FOUND) {
124 status = smb_sam_lookup_sid(sid, info);
125 if (status == NT_STATUS_NOT_FOUND)
126 status = lsa_lookup_sid_domain(sid, info);
127 }
128
129 return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED);
130 }
131
132 /*
133 * Obtains the primary domain SID and name from the specified server
134 * (domain controller).
135 *
136 * The requested information will be returned via 'info' argument.
137 *
138 * Returns NT status codes. (Raw, not LSA-ized)
139 */
140 DWORD
141 lsa_query_primary_domain_info(char *server, char *domain,
142 smb_domain_t *info)
143 {
144 mlsvc_handle_t domain_handle;
145 char user[SMB_USERNAME_MAXLEN];
146 DWORD status;
147
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2019 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * This module provides the high level interface to the LSA RPC functions.
29 */
30
31 #include <strings.h>
32 #include <unistd.h>
33
34 #include <smbsrv/libsmb.h>
35 #include <smbsrv/libmlsvc.h>
36 #include <smbsrv/smbinfo.h>
37 #include <smbsrv/smb_token.h>
38
39 #include <lsalib.h>
40
41 static uint32_t lsa_lookup_name_int(char *, uint16_t, smb_account_t *,
42 boolean_t);
43 static uint32_t lsa_lookup_sid_int(smb_sid_t *, smb_account_t *, boolean_t);
44
45 static uint32_t lsa_lookup_name_builtin(char *, char *, smb_account_t *);
46 static uint32_t lsa_lookup_name_domain(char *, smb_account_t *);
47
48 static uint32_t lsa_lookup_sid_builtin(smb_sid_t *, smb_account_t *);
49 static uint32_t lsa_lookup_sid_domain(smb_sid_t *, smb_account_t *);
50
51 static uint32_t lsa_list_accounts(mlsvc_handle_t *);
52 static uint32_t lsa_map_status(uint32_t);
53
54 /*
55 * Lookup the given account and returns the account information
56 * in the passed smb_account_t structure.
57 *
58 * The lookup is performed in the following order:
59 * well known accounts
60 * local accounts
61 * domain accounts
62 *
63 * If it's established the given account is well know or local
64 * but the lookup fails for some reason, the next step(s) won't be
65 * performed.
66 *
67 * If the name is a domain account, it may refer to a user, group or
68 * alias. If it is a local account, its type should be specified
69 * in the sid_type parameter. In case the account type is unknown
70 * sid_type should be set to SidTypeUnknown.
71 *
72 * account argument could be either [domain\]name or [domain/]name.
73 *
74 * Return status:
75 *
76 * NT_STATUS_SUCCESS Account is successfully translated
77 * NT_STATUS_NONE_MAPPED Couldn't translate the account
78 */
79 uint32_t
80 lsa_lookup_name(char *account, uint16_t type, smb_account_t *info)
81 {
82 return (lsa_lookup_name_int(account, type, info, B_TRUE));
83 }
84
85 /* Variant that avoids the call out to AD. */
86 uint32_t
87 lsa_lookup_lname(char *account, uint16_t type, smb_account_t *info)
88 {
89 return (lsa_lookup_name_int(account, type, info, B_FALSE));
90 }
91
92 uint32_t
93 lsa_lookup_name_int(char *account, uint16_t type, smb_account_t *info,
94 boolean_t try_ad)
95 {
96 char nambuf[SMB_USERNAME_MAXLEN];
97 char dombuf[SMB_PI_MAX_DOMAIN];
98 char *name, *domain;
99 uint32_t status;
100 char *slash;
101
102 if (account == NULL)
103 return (NT_STATUS_NONE_MAPPED);
104
105 (void) strsubst(account, '/', '\\');
106 (void) strcanon(account, "\\");
107 /* \john -> john */
108 account += strspn(account, "\\");
109
110 if ((slash = strchr(account, '\\')) != NULL) {
111 *slash = '\0';
112 (void) strlcpy(dombuf, account, sizeof (dombuf));
113 (void) strlcpy(nambuf, slash + 1, sizeof (nambuf));
114 *slash = '\\';
115 name = nambuf;
116 domain = dombuf;
117 } else {
118 name = account;
119 domain = NULL;
120 }
121
122 status = lsa_lookup_name_builtin(domain, name, info);
123 if (status == NT_STATUS_NOT_FOUND) {
124 status = smb_sam_lookup_name(domain, name, type, info);
125 if (status == NT_STATUS_SUCCESS)
126 return (status);
127
128 if (try_ad && ((domain == NULL) ||
129 (status == NT_STATUS_NOT_FOUND))) {
130 status = lsa_lookup_name_domain(account, info);
131 }
132 }
133
134 return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED);
135 }
136
137 uint32_t
138 lsa_lookup_sid(smb_sid_t *sid, smb_account_t *info)
139 {
140 return (lsa_lookup_sid_int(sid, info, B_TRUE));
141 }
142
143 /* Variant that avoids the call out to AD. */
144 uint32_t
145 lsa_lookup_lsid(smb_sid_t *sid, smb_account_t *info)
146 {
147 return (lsa_lookup_sid_int(sid, info, B_FALSE));
148 }
149
150 static uint32_t
151 lsa_lookup_sid_int(smb_sid_t *sid, smb_account_t *info, boolean_t try_ad)
152 {
153 uint32_t status;
154
155 if (!smb_sid_isvalid(sid))
156 return (NT_STATUS_INVALID_SID);
157
158 status = lsa_lookup_sid_builtin(sid, info);
159 if (status == NT_STATUS_NOT_FOUND) {
160 status = smb_sam_lookup_sid(sid, info);
161 if (try_ad && status == NT_STATUS_NOT_FOUND) {
162 status = lsa_lookup_sid_domain(sid, info);
163 }
164 }
165
166 return ((status == NT_STATUS_SUCCESS) ? status : NT_STATUS_NONE_MAPPED);
167 }
168
169 /*
170 * Obtains the primary domain SID and name from the specified server
171 * (domain controller).
172 *
173 * The requested information will be returned via 'info' argument.
174 *
175 * Returns NT status codes. (Raw, not LSA-ized)
176 */
177 DWORD
178 lsa_query_primary_domain_info(char *server, char *domain,
179 smb_domain_t *info)
180 {
181 mlsvc_handle_t domain_handle;
182 char user[SMB_USERNAME_MAXLEN];
183 DWORD status;
184
|