source: branches/samba-3.5.x/source4/libcli/util/clilsa.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 7.9 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 cli->transport->iconv_convenience);
84 if (lsa->pipe == NULL) {
85 talloc_free(lsa);
86 return NT_STATUS_NO_MEMORY;
87 }
88
89 /* open the LSA pipe */
90 status = dcerpc_pipe_open_smb(lsa->pipe, lsa->ipc_tree, NDR_LSARPC_NAME);
91 if (!NT_STATUS_IS_OK(status)) {
92 talloc_free(lsa);
93 return status;
94 }
95
96 /* bind to the LSA pipe */
97 status = dcerpc_bind_auth_none(lsa->pipe, &ndr_table_lsarpc);
98 if (!NT_STATUS_IS_OK(status)) {
99 talloc_free(lsa);
100 return status;
101 }
102
103
104 /* open a lsa policy handle */
105 qos.len = 0;
106 qos.impersonation_level = 2;
107 qos.context_mode = 1;
108 qos.effective_only = 0;
109
110 attr.len = 0;
111 attr.root_dir = NULL;
112 attr.object_name = NULL;
113 attr.attributes = 0;
114 attr.sec_desc = NULL;
115 attr.sec_qos = &qos;
116
117 r.in.system_name = &system_name;
118 r.in.attr = &attr;
119 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
120 r.out.handle = &lsa->handle;
121
122 status = dcerpc_lsa_OpenPolicy(lsa->pipe, lsa, &r);
123 if (!NT_STATUS_IS_OK(status)) {
124 talloc_free(lsa);
125 return status;
126 }
127
128 cli->lsa = lsa;
129
130 return NT_STATUS_OK;
131}
132
133
134/*
135 return the set of privileges for the given sid
136*/
137NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid,
138 TALLOC_CTX *mem_ctx,
139 struct lsa_RightSet *rights)
140{
141 NTSTATUS status;
142 struct lsa_EnumAccountRights r;
143
144 status = smblsa_connect(cli);
145 if (!NT_STATUS_IS_OK(status)) {
146 return status;
147 }
148
149 r.in.handle = &cli->lsa->handle;
150 r.in.sid = sid;
151 r.out.rights = rights;
152
153 return dcerpc_lsa_EnumAccountRights(cli->lsa->pipe, mem_ctx, &r);
154}
155
156
157/*
158 check if a named sid has a particular named privilege
159*/
160NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli,
161 const char *sid_str,
162 const char *privilege)
163{
164 struct lsa_RightSet rights;
165 NTSTATUS status;
166 TALLOC_CTX *mem_ctx = talloc_new(cli);
167 struct dom_sid *sid;
168 unsigned i;
169
170 sid = dom_sid_parse_talloc(mem_ctx, sid_str);
171 if (sid == NULL) {
172 talloc_free(mem_ctx);
173 return NT_STATUS_INVALID_SID;
174 }
175
176 status = smblsa_sid_privileges(cli, sid, mem_ctx, &rights);
177 if (!NT_STATUS_IS_OK(status)) {
178 talloc_free(mem_ctx);
179 return status;
180 }
181
182 for (i=0;i<rights.count;i++) {
183 if (strcmp(rights.names[i].string, privilege) == 0) {
184 talloc_free(mem_ctx);
185 return NT_STATUS_OK;
186 }
187 }
188
189 talloc_free(mem_ctx);
190 return NT_STATUS_NOT_FOUND;
191}
192
193
194/*
195 lookup a SID, returning its name
196*/
197NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli,
198 const char *sid_str,
199 TALLOC_CTX *mem_ctx,
200 const char **name)
201{
202 struct lsa_LookupSids r;
203 struct lsa_TransNameArray names;
204 struct lsa_SidArray sids;
205 struct lsa_RefDomainList *domains = NULL;
206 uint32_t count = 1;
207 NTSTATUS status;
208 struct dom_sid *sid;
209 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
210
211 status = smblsa_connect(cli);
212 if (!NT_STATUS_IS_OK(status)) {
213 return status;
214 }
215
216 sid = dom_sid_parse_talloc(mem_ctx2, sid_str);
217 if (sid == NULL) {
218 return NT_STATUS_INVALID_SID;
219 }
220
221 names.count = 0;
222 names.names = NULL;
223
224 sids.num_sids = 1;
225 sids.sids = talloc(mem_ctx2, struct lsa_SidPtr);
226 sids.sids[0].sid = sid;
227
228 r.in.handle = &cli->lsa->handle;
229 r.in.sids = &sids;
230 r.in.names = &names;
231 r.in.level = 1;
232 r.in.count = &count;
233 r.out.count = &count;
234 r.out.names = &names;
235 r.out.domains = &domains;
236
237 status = dcerpc_lsa_LookupSids(cli->lsa->pipe, mem_ctx2, &r);
238 if (!NT_STATUS_IS_OK(status)) {
239 talloc_free(mem_ctx2);
240 return status;
241 }
242 if (names.count != 1) {
243 talloc_free(mem_ctx2);
244 return NT_STATUS_UNSUCCESSFUL;
245 }
246
247 (*name) = talloc_asprintf(mem_ctx, "%s\\%s",
248 domains->domains[0].name.string,
249 names.names[0].name.string);
250
251 talloc_free(mem_ctx2);
252
253 return NT_STATUS_OK;
254}
255
256/*
257 lookup a name, returning its sid
258*/
259NTSTATUS smblsa_lookup_name(struct smbcli_state *cli,
260 const char *name,
261 TALLOC_CTX *mem_ctx,
262 const char **sid_str)
263{
264 struct lsa_LookupNames r;
265 struct lsa_TransSidArray sids;
266 struct lsa_String names;
267 struct lsa_RefDomainList *domains = NULL;
268 uint32_t count = 1;
269 NTSTATUS status;
270 struct dom_sid *sid;
271 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
272 uint32_t rid;
273
274 status = smblsa_connect(cli);
275 if (!NT_STATUS_IS_OK(status)) {
276 return status;
277 }
278
279 sids.count = 0;
280 sids.sids = NULL;
281
282 names.string = name;
283
284 r.in.handle = &cli->lsa->handle;
285 r.in.num_names = 1;
286 r.in.names = &names;
287 r.in.sids = &sids;
288 r.in.level = 1;
289 r.in.count = &count;
290 r.out.count = &count;
291 r.out.sids = &sids;
292 r.out.domains = &domains;
293
294 status = dcerpc_lsa_LookupNames(cli->lsa->pipe, mem_ctx2, &r);
295 if (!NT_STATUS_IS_OK(status)) {
296 talloc_free(mem_ctx2);
297 return status;
298 }
299 if (sids.count != 1) {
300 talloc_free(mem_ctx2);
301 return NT_STATUS_UNSUCCESSFUL;
302 }
303
304 sid = domains->domains[0].sid;
305 rid = sids.sids[0].rid;
306
307 (*sid_str) = talloc_asprintf(mem_ctx, "%s-%u",
308 dom_sid_string(mem_ctx2, sid), rid);
309
310 talloc_free(mem_ctx2);
311
312 return NT_STATUS_OK;
313}
314
315
316/*
317 add a set of privileges to the given sid
318*/
319NTSTATUS smblsa_sid_add_privileges(struct smbcli_state *cli, struct dom_sid *sid,
320 TALLOC_CTX *mem_ctx,
321 struct lsa_RightSet *rights)
322{
323 NTSTATUS status;
324 struct lsa_AddAccountRights r;
325
326 status = smblsa_connect(cli);
327 if (!NT_STATUS_IS_OK(status)) {
328 return status;
329 }
330
331 r.in.handle = &cli->lsa->handle;
332 r.in.sid = sid;
333 r.in.rights = rights;
334
335 return dcerpc_lsa_AddAccountRights(cli->lsa->pipe, mem_ctx, &r);
336}
337
338/*
339 remove a set of privileges from the given sid
340*/
341NTSTATUS smblsa_sid_del_privileges(struct smbcli_state *cli, struct dom_sid *sid,
342 TALLOC_CTX *mem_ctx,
343 struct lsa_RightSet *rights)
344{
345 NTSTATUS status;
346 struct lsa_RemoveAccountRights r;
347
348 status = smblsa_connect(cli);
349 if (!NT_STATUS_IS_OK(status)) {
350 return status;
351 }
352
353 r.in.handle = &cli->lsa->handle;
354 r.in.sid = sid;
355 r.in.remove_all = 0;
356 r.in.rights = rights;
357
358 return dcerpc_lsa_RemoveAccountRights(cli->lsa->pipe, mem_ctx, &r);
359}
Note: See TracBrowser for help on using the repository browser.