source: vendor/3.6.23/source4/libcli/util/clilsa.c

Last change on this file was 860, checked in by Silvan Scherrer, 11 years ago

Samba 3.6: updated vendor to latest version

File size: 9.0 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 lsa calls for file sharing connections
5
6 Copyright (C) Andrew Tridgell 2004
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22/*
23 when dealing with ACLs the file sharing client code needs to
24 sometimes make LSA RPC calls. This code provides an easy interface
25 for doing those calls.
26*/
27
28#include "includes.h"
29#include "libcli/raw/libcliraw.h"
30#include "libcli/libcli.h"
31#include "libcli/security/security.h"
32#include "librpc/gen_ndr/ndr_lsa.h"
33#include "librpc/gen_ndr/ndr_lsa_c.h"
34#include "libcli/util/clilsa.h"
35
36struct smblsa_state {
37 struct dcerpc_pipe *pipe;
38 struct smbcli_tree *ipc_tree;
39 struct policy_handle handle;
40};
41
42/*
43 establish the lsa pipe connection
44*/
45static NTSTATUS smblsa_connect(struct smbcli_state *cli)
46{
47 struct smblsa_state *lsa;
48 NTSTATUS status;
49 struct lsa_OpenPolicy r;
50 uint16_t system_name = '\\';
51 union smb_tcon tcon;
52 struct lsa_ObjectAttribute attr;
53 struct lsa_QosInfo qos;
54
55 if (cli->lsa != NULL) {
56 return NT_STATUS_OK;
57 }
58
59 lsa = talloc(cli, struct smblsa_state);
60 if (lsa == NULL) {
61 return NT_STATUS_NO_MEMORY;
62 }
63
64 lsa->ipc_tree = smbcli_tree_init(cli->session, lsa, false);
65 if (lsa->ipc_tree == NULL) {
66 return NT_STATUS_NO_MEMORY;
67 }
68
69 /* connect to IPC$ */
70 tcon.generic.level = RAW_TCON_TCONX;
71 tcon.tconx.in.flags = 0;
72 tcon.tconx.in.password = data_blob(NULL, 0);
73 tcon.tconx.in.path = "ipc$";
74 tcon.tconx.in.device = "IPC";
75 status = smb_raw_tcon(lsa->ipc_tree, lsa, &tcon);
76 if (!NT_STATUS_IS_OK(status)) {
77 talloc_free(lsa);
78 return status;
79 }
80 lsa->ipc_tree->tid = tcon.tconx.out.tid;
81
82 lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx);
83 if (lsa->pipe == NULL) {
84 talloc_free(lsa);
85 return NT_STATUS_NO_MEMORY;
86 }
87
88 /* open the LSA pipe */
89 status = dcerpc_pipe_open_smb(lsa->pipe, lsa->ipc_tree, NDR_LSARPC_NAME);
90 if (!NT_STATUS_IS_OK(status)) {
91 talloc_free(lsa);
92 return status;
93 }
94
95 /* bind to the LSA pipe */
96 status = dcerpc_bind_auth_none(lsa->pipe, &ndr_table_lsarpc);
97 if (!NT_STATUS_IS_OK(status)) {
98 talloc_free(lsa);
99 return status;
100 }
101
102
103 /* open a lsa policy handle */
104 qos.len = 0;
105 qos.impersonation_level = 2;
106 qos.context_mode = 1;
107 qos.effective_only = 0;
108
109 attr.len = 0;
110 attr.root_dir = NULL;
111 attr.object_name = NULL;
112 attr.attributes = 0;
113 attr.sec_desc = NULL;
114 attr.sec_qos = &qos;
115
116 r.in.system_name = &system_name;
117 r.in.attr = &attr;
118 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
119 r.out.handle = &lsa->handle;
120
121 status = dcerpc_lsa_OpenPolicy_r(lsa->pipe->binding_handle, lsa, &r);
122 if (!NT_STATUS_IS_OK(status)) {
123 talloc_free(lsa);
124 return status;
125 }
126
127 if (!NT_STATUS_IS_OK(r.out.result)) {
128 talloc_free(lsa);
129 return r.out.result;
130 }
131
132 cli->lsa = lsa;
133
134 return NT_STATUS_OK;
135}
136
137
138/*
139 return the set of privileges for the given sid
140*/
141NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid,
142 TALLOC_CTX *mem_ctx,
143 struct lsa_RightSet *rights)
144{
145 NTSTATUS status;
146 struct lsa_EnumAccountRights r;
147
148 status = smblsa_connect(cli);
149 if (!NT_STATUS_IS_OK(status)) {
150 return status;
151 }
152
153 r.in.handle = &cli->lsa->handle;
154 r.in.sid = sid;
155 r.out.rights = rights;
156
157 status = dcerpc_lsa_EnumAccountRights_r(cli->lsa->pipe->binding_handle, mem_ctx, &r);
158 if (!NT_STATUS_IS_OK(status)) {
159 return status;
160 }
161
162 return r.out.result;
163}
164
165
166/*
167 check if a named sid has a particular named privilege
168*/
169NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli,
170 const char *sid_str,
171 const char *privilege)
172{
173 struct lsa_RightSet rights;
174 NTSTATUS status;
175 TALLOC_CTX *mem_ctx = talloc_new(cli);
176 struct dom_sid *sid;
177 unsigned i;
178
179 sid = dom_sid_parse_talloc(mem_ctx, sid_str);
180 if (sid == NULL) {
181 talloc_free(mem_ctx);
182 return NT_STATUS_INVALID_SID;
183 }
184
185 status = smblsa_sid_privileges(cli, sid, mem_ctx, &rights);
186 if (!NT_STATUS_IS_OK(status)) {
187 talloc_free(mem_ctx);
188 return status;
189 }
190
191 for (i=0;i<rights.count;i++) {
192 if (strcmp(rights.names[i].string, privilege) == 0) {
193 talloc_free(mem_ctx);
194 return NT_STATUS_OK;
195 }
196 }
197
198 talloc_free(mem_ctx);
199 return NT_STATUS_NOT_FOUND;
200}
201
202
203/*
204 lookup a SID, returning its name
205*/
206NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli,
207 const char *sid_str,
208 TALLOC_CTX *mem_ctx,
209 const char **name)
210{
211 struct lsa_LookupSids r;
212 struct lsa_TransNameArray names;
213 struct lsa_SidArray sids;
214 struct lsa_RefDomainList *domains = NULL;
215 uint32_t count = 1;
216 NTSTATUS status;
217 struct dom_sid *sid;
218 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
219
220 status = smblsa_connect(cli);
221 if (!NT_STATUS_IS_OK(status)) {
222 return status;
223 }
224
225 sid = dom_sid_parse_talloc(mem_ctx2, sid_str);
226 if (sid == NULL) {
227 return NT_STATUS_INVALID_SID;
228 }
229
230 names.count = 0;
231 names.names = NULL;
232
233 sids.num_sids = 1;
234 sids.sids = talloc(mem_ctx2, struct lsa_SidPtr);
235 sids.sids[0].sid = sid;
236
237 r.in.handle = &cli->lsa->handle;
238 r.in.sids = &sids;
239 r.in.names = &names;
240 r.in.level = 1;
241 r.in.count = &count;
242 r.out.count = &count;
243 r.out.names = &names;
244 r.out.domains = &domains;
245
246 status = dcerpc_lsa_LookupSids_r(cli->lsa->pipe->binding_handle, mem_ctx2, &r);
247 if (!NT_STATUS_IS_OK(status)) {
248 talloc_free(mem_ctx2);
249 return status;
250 }
251 if (!NT_STATUS_IS_OK(r.out.result)) {
252 talloc_free(mem_ctx2);
253 return r.out.result;
254 }
255 if (names.count != 1) {
256 talloc_free(mem_ctx2);
257 return NT_STATUS_INVALID_NETWORK_RESPONSE;
258 }
259 if (domains == NULL) {
260 talloc_free(mem_ctx2);
261 return NT_STATUS_INVALID_NETWORK_RESPONSE;
262 }
263 if (domains->count != 1) {
264 talloc_free(mem_ctx2);
265 return NT_STATUS_INVALID_NETWORK_RESPONSE;
266 }
267 if (names.names[0].sid_index != UINT32_MAX &&
268 names.names[0].sid_index >= domains->count)
269 {
270 talloc_free(mem_ctx2);
271 return NT_STATUS_INVALID_NETWORK_RESPONSE;
272 }
273
274 (*name) = talloc_asprintf(mem_ctx, "%s\\%s",
275 domains->domains[0].name.string,
276 names.names[0].name.string);
277
278 talloc_free(mem_ctx2);
279
280 return NT_STATUS_OK;
281}
282
283/*
284 lookup a name, returning its sid
285*/
286NTSTATUS smblsa_lookup_name(struct smbcli_state *cli,
287 const char *name,
288 TALLOC_CTX *mem_ctx,
289 const char **sid_str)
290{
291 struct lsa_LookupNames r;
292 struct lsa_TransSidArray sids;
293 struct lsa_String names;
294 struct lsa_RefDomainList *domains = NULL;
295 uint32_t count = 1;
296 NTSTATUS status;
297 struct dom_sid *sid;
298 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
299 uint32_t rid;
300
301 status = smblsa_connect(cli);
302 if (!NT_STATUS_IS_OK(status)) {
303 return status;
304 }
305
306 sids.count = 0;
307 sids.sids = NULL;
308
309 names.string = name;
310
311 r.in.handle = &cli->lsa->handle;
312 r.in.num_names = 1;
313 r.in.names = &names;
314 r.in.sids = &sids;
315 r.in.level = 1;
316 r.in.count = &count;
317 r.out.count = &count;
318 r.out.sids = &sids;
319 r.out.domains = &domains;
320
321 status = dcerpc_lsa_LookupNames_r(cli->lsa->pipe->binding_handle, mem_ctx2, &r);
322 if (!NT_STATUS_IS_OK(status)) {
323 talloc_free(mem_ctx2);
324 return status;
325 }
326 if (!NT_STATUS_IS_OK(r.out.result)) {
327 talloc_free(mem_ctx2);
328 return r.out.result;
329 }
330 if (sids.count != 1) {
331 talloc_free(mem_ctx2);
332 return NT_STATUS_INVALID_NETWORK_RESPONSE;
333 }
334 if (domains->count != 1) {
335 talloc_free(mem_ctx2);
336 return NT_STATUS_INVALID_NETWORK_RESPONSE;
337 }
338
339 sid = domains->domains[0].sid;
340 rid = sids.sids[0].rid;
341
342 (*sid_str) = talloc_asprintf(mem_ctx, "%s-%u",
343 dom_sid_string(mem_ctx2, sid), rid);
344
345 talloc_free(mem_ctx2);
346
347 return NT_STATUS_OK;
348}
349
350
351/*
352 add a set of privileges to the given sid
353*/
354NTSTATUS smblsa_sid_add_privileges(struct smbcli_state *cli, struct dom_sid *sid,
355 TALLOC_CTX *mem_ctx,
356 struct lsa_RightSet *rights)
357{
358 NTSTATUS status;
359 struct lsa_AddAccountRights r;
360
361 status = smblsa_connect(cli);
362 if (!NT_STATUS_IS_OK(status)) {
363 return status;
364 }
365
366 r.in.handle = &cli->lsa->handle;
367 r.in.sid = sid;
368 r.in.rights = rights;
369
370 status = dcerpc_lsa_AddAccountRights_r(cli->lsa->pipe->binding_handle, mem_ctx, &r);
371 if (!NT_STATUS_IS_OK(status)) {
372 return status;
373 }
374
375 return r.out.result;
376}
377
378/*
379 remove a set of privileges from the given sid
380*/
381NTSTATUS smblsa_sid_del_privileges(struct smbcli_state *cli, struct dom_sid *sid,
382 TALLOC_CTX *mem_ctx,
383 struct lsa_RightSet *rights)
384{
385 NTSTATUS status;
386 struct lsa_RemoveAccountRights r;
387
388 status = smblsa_connect(cli);
389 if (!NT_STATUS_IS_OK(status)) {
390 return status;
391 }
392
393 r.in.handle = &cli->lsa->handle;
394 r.in.sid = sid;
395 r.in.remove_all = 0;
396 r.in.rights = rights;
397
398 status = dcerpc_lsa_RemoveAccountRights_r(cli->lsa->pipe->binding_handle, mem_ctx, &r);
399 if (!NT_STATUS_IS_OK(status)) {
400 return status;
401 }
402
403 return r.out.result;
404}
Note: See TracBrowser for help on using the repository browser.