2 Unix SMB/CIFS implementation.
4 lsa calls for file sharing connections
6 Copyright (C) Andrew Tridgell 2004
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 2 of the License, or
11 (at your option) any later version.
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.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 when dealing with ACLs the file sharing client code needs to
25 sometimes make LSA RPC calls. This code provides an easy interface
26 for doing those calls.
30 #include "libcli/raw/libcliraw.h"
31 #include "librpc/gen_ndr/ndr_lsa.h"
34 struct dcerpc_pipe *pipe;
35 struct smbcli_tree *ipc_tree;
36 struct policy_handle handle;
40 establish the lsa pipe connection
42 static NTSTATUS smblsa_connect(struct smbcli_state *cli)
44 struct smblsa_state *lsa;
46 struct lsa_OpenPolicy r;
47 uint16_t system_name = '\\';
49 struct lsa_ObjectAttribute attr;
50 struct lsa_QosInfo qos;
52 if (cli->lsa != NULL) {
56 lsa = talloc_p(cli, struct smblsa_state);
58 return NT_STATUS_NO_MEMORY;
61 lsa->ipc_tree = smbcli_tree_init(cli->session);
62 if (lsa->ipc_tree == NULL) {
63 return NT_STATUS_NO_MEMORY;
67 tcon.generic.level = RAW_TCON_TCONX;
68 tcon.tconx.in.flags = 0;
69 tcon.tconx.in.password = data_blob(NULL, 0);
70 tcon.tconx.in.path = "ipc$";
71 tcon.tconx.in.device = "IPC";
72 status = smb_tree_connect(lsa->ipc_tree, lsa, &tcon);
73 if (!NT_STATUS_IS_OK(status)) {
77 lsa->ipc_tree->tid = tcon.tconx.out.cnum;
79 /* open the LSA pipe */
80 status = dcerpc_pipe_open_smb(&lsa->pipe, lsa->ipc_tree, DCERPC_LSARPC_NAME);
81 if (!NT_STATUS_IS_OK(status)) {
86 /* bind to the LSA pipe */
87 status = dcerpc_bind_auth_none(lsa->pipe, DCERPC_LSARPC_UUID, DCERPC_LSARPC_VERSION);
88 if (!NT_STATUS_IS_OK(status)) {
94 /* open a lsa policy handle */
96 qos.impersonation_level = 2;
98 qos.effective_only = 0;
101 attr.root_dir = NULL;
102 attr.object_name = NULL;
104 attr.sec_desc = NULL;
107 r.in.system_name = &system_name;
109 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
110 r.out.handle = &lsa->handle;
112 status = dcerpc_lsa_OpenPolicy(lsa->pipe, lsa, &r);
113 if (!NT_STATUS_IS_OK(status)) {
125 return the set of privileges for the given sid
127 NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid,
129 struct lsa_RightSet *rights)
132 struct lsa_EnumAccountRights r;
134 status = smblsa_connect(cli);
135 if (!NT_STATUS_IS_OK(status)) {
139 r.in.handle = &cli->lsa->handle;
141 r.out.rights = rights;
143 return dcerpc_lsa_EnumAccountRights(cli->lsa->pipe, mem_ctx, &r);
148 check if a named sid has a particular named privilege
150 NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli,
152 const char *privilege)
154 struct lsa_RightSet rights;
156 TALLOC_CTX *mem_ctx = talloc(cli, 0);
160 sid = dom_sid_parse_talloc(mem_ctx, sid_str);
162 talloc_free(mem_ctx);
163 return NT_STATUS_INVALID_SID;
166 status = smblsa_sid_privileges(cli, sid, mem_ctx, &rights);
167 if (!NT_STATUS_IS_OK(status)) {
168 talloc_free(mem_ctx);
172 for (i=0;i<rights.count;i++) {
173 if (strcmp(rights.names[i].string, privilege) == 0) {
174 talloc_free(mem_ctx);
179 talloc_free(mem_ctx);
180 return NT_STATUS_NOT_FOUND;
185 lookup a SID, returning its name
187 NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli,
192 struct lsa_LookupSids r;
193 struct lsa_TransNameArray names;
194 struct lsa_SidArray sids;
198 TALLOC_CTX *mem_ctx2 = talloc(mem_ctx, 0);
200 status = smblsa_connect(cli);
201 if (!NT_STATUS_IS_OK(status)) {
205 sid = dom_sid_parse_talloc(mem_ctx2, sid_str);
207 return NT_STATUS_INVALID_SID;
214 sids.sids = talloc_p(mem_ctx2, struct lsa_SidPtr);
215 sids.sids[0].sid = sid;
217 r.in.handle = &cli->lsa->handle;
222 r.out.count = &count;
223 r.out.names = &names;
225 status = dcerpc_lsa_LookupSids(cli->lsa->pipe, mem_ctx2, &r);
226 if (!NT_STATUS_IS_OK(status)) {
227 talloc_free(mem_ctx2);
230 if (names.count != 1) {
231 talloc_free(mem_ctx2);
232 return NT_STATUS_UNSUCCESSFUL;
235 (*name) = talloc_asprintf(mem_ctx, "%s\\%s",
236 r.out.domains->domains[0].name.string,
237 names.names[0].name.string);
239 talloc_free(mem_ctx2);
245 lookup a name, returning its sid
247 NTSTATUS smblsa_lookup_name(struct smbcli_state *cli,
250 const char **sid_str)
252 struct lsa_LookupNames r;
253 struct lsa_TransSidArray sids;
254 struct lsa_String names;
258 TALLOC_CTX *mem_ctx2 = talloc(mem_ctx, 0);
261 status = smblsa_connect(cli);
262 if (!NT_STATUS_IS_OK(status)) {
271 r.in.handle = &cli->lsa->handle;
277 r.out.count = &count;
280 status = dcerpc_lsa_LookupNames(cli->lsa->pipe, mem_ctx2, &r);
281 if (!NT_STATUS_IS_OK(status)) {
282 talloc_free(mem_ctx2);
285 if (sids.count != 1) {
286 talloc_free(mem_ctx2);
287 return NT_STATUS_UNSUCCESSFUL;
290 sid = r.out.domains->domains[0].sid;
291 rid = sids.sids[0].rid;
293 (*sid_str) = talloc_asprintf(mem_ctx, "%s-%u",
294 dom_sid_string(mem_ctx2, sid), rid);
296 talloc_free(mem_ctx2);
303 add a set of privileges to the given sid
305 NTSTATUS smblsa_sid_add_privileges(struct smbcli_state *cli, struct dom_sid *sid,
307 struct lsa_RightSet *rights)
310 struct lsa_AddAccountRights r;
312 status = smblsa_connect(cli);
313 if (!NT_STATUS_IS_OK(status)) {
317 r.in.handle = &cli->lsa->handle;
319 r.in.rights = rights;
321 return dcerpc_lsa_AddAccountRights(cli->lsa->pipe, mem_ctx, &r);
325 remove a set of privileges from the given sid
327 NTSTATUS smblsa_sid_del_privileges(struct smbcli_state *cli, struct dom_sid *sid,
329 struct lsa_RightSet *rights)
332 struct lsa_RemoveAccountRights r;
334 status = smblsa_connect(cli);
335 if (!NT_STATUS_IS_OK(status)) {
339 r.in.handle = &cli->lsa->handle;
342 r.in.rights = rights;
344 return dcerpc_lsa_RemoveAccountRights(cli->lsa->pipe, mem_ctx, &r);