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(cli, struct smblsa_state);
58 return NT_STATUS_NO_MEMORY;
61 lsa->ipc_tree = smbcli_tree_init(cli->session, lsa, False);
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_raw_tcon(lsa->ipc_tree, lsa, &tcon);
73 if (!NT_STATUS_IS_OK(status)) {
77 lsa->ipc_tree->tid = tcon.tconx.out.tid;
79 lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx);
80 if (lsa->pipe == NULL) {
82 return NT_STATUS_NO_MEMORY;
85 /* open the LSA pipe */
86 status = dcerpc_pipe_open_smb(lsa->pipe->conn, lsa->ipc_tree, DCERPC_LSARPC_NAME);
87 if (!NT_STATUS_IS_OK(status)) {
92 /* bind to the LSA pipe */
93 status = dcerpc_bind_auth_none(lsa->pipe, DCERPC_LSARPC_UUID, DCERPC_LSARPC_VERSION);
94 if (!NT_STATUS_IS_OK(status)) {
100 /* open a lsa policy handle */
102 qos.impersonation_level = 2;
103 qos.context_mode = 1;
104 qos.effective_only = 0;
107 attr.root_dir = NULL;
108 attr.object_name = NULL;
110 attr.sec_desc = NULL;
113 r.in.system_name = &system_name;
115 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
116 r.out.handle = &lsa->handle;
118 status = dcerpc_lsa_OpenPolicy(lsa->pipe, lsa, &r);
119 if (!NT_STATUS_IS_OK(status)) {
131 return the set of privileges for the given sid
133 NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid,
135 struct lsa_RightSet *rights)
138 struct lsa_EnumAccountRights r;
140 status = smblsa_connect(cli);
141 if (!NT_STATUS_IS_OK(status)) {
145 r.in.handle = &cli->lsa->handle;
147 r.out.rights = rights;
149 return dcerpc_lsa_EnumAccountRights(cli->lsa->pipe, mem_ctx, &r);
154 check if a named sid has a particular named privilege
156 NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli,
158 const char *privilege)
160 struct lsa_RightSet rights;
162 TALLOC_CTX *mem_ctx = talloc_new(cli);
166 sid = dom_sid_parse_talloc(mem_ctx, sid_str);
168 talloc_free(mem_ctx);
169 return NT_STATUS_INVALID_SID;
172 status = smblsa_sid_privileges(cli, sid, mem_ctx, &rights);
173 if (!NT_STATUS_IS_OK(status)) {
174 talloc_free(mem_ctx);
178 for (i=0;i<rights.count;i++) {
179 if (strcmp(rights.names[i].string, privilege) == 0) {
180 talloc_free(mem_ctx);
185 talloc_free(mem_ctx);
186 return NT_STATUS_NOT_FOUND;
191 lookup a SID, returning its name
193 NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli,
198 struct lsa_LookupSids r;
199 struct lsa_TransNameArray names;
200 struct lsa_SidArray sids;
204 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
206 status = smblsa_connect(cli);
207 if (!NT_STATUS_IS_OK(status)) {
211 sid = dom_sid_parse_talloc(mem_ctx2, sid_str);
213 return NT_STATUS_INVALID_SID;
220 sids.sids = talloc(mem_ctx2, struct lsa_SidPtr);
221 sids.sids[0].sid = sid;
223 r.in.handle = &cli->lsa->handle;
228 r.out.count = &count;
229 r.out.names = &names;
231 status = dcerpc_lsa_LookupSids(cli->lsa->pipe, mem_ctx2, &r);
232 if (!NT_STATUS_IS_OK(status)) {
233 talloc_free(mem_ctx2);
236 if (names.count != 1) {
237 talloc_free(mem_ctx2);
238 return NT_STATUS_UNSUCCESSFUL;
241 (*name) = talloc_asprintf(mem_ctx, "%s\\%s",
242 r.out.domains->domains[0].name.string,
243 names.names[0].name.string);
245 talloc_free(mem_ctx2);
251 lookup a name, returning its sid
253 NTSTATUS smblsa_lookup_name(struct smbcli_state *cli,
256 const char **sid_str)
258 struct lsa_LookupNames r;
259 struct lsa_TransSidArray sids;
260 struct lsa_String names;
264 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
267 status = smblsa_connect(cli);
268 if (!NT_STATUS_IS_OK(status)) {
277 r.in.handle = &cli->lsa->handle;
283 r.out.count = &count;
286 status = dcerpc_lsa_LookupNames(cli->lsa->pipe, mem_ctx2, &r);
287 if (!NT_STATUS_IS_OK(status)) {
288 talloc_free(mem_ctx2);
291 if (sids.count != 1) {
292 talloc_free(mem_ctx2);
293 return NT_STATUS_UNSUCCESSFUL;
296 sid = r.out.domains->domains[0].sid;
297 rid = sids.sids[0].rid;
299 (*sid_str) = talloc_asprintf(mem_ctx, "%s-%u",
300 dom_sid_string(mem_ctx2, sid), rid);
302 talloc_free(mem_ctx2);
309 add a set of privileges to the given sid
311 NTSTATUS smblsa_sid_add_privileges(struct smbcli_state *cli, struct dom_sid *sid,
313 struct lsa_RightSet *rights)
316 struct lsa_AddAccountRights r;
318 status = smblsa_connect(cli);
319 if (!NT_STATUS_IS_OK(status)) {
323 r.in.handle = &cli->lsa->handle;
325 r.in.rights = rights;
327 return dcerpc_lsa_AddAccountRights(cli->lsa->pipe, mem_ctx, &r);
331 remove a set of privileges from the given sid
333 NTSTATUS smblsa_sid_del_privileges(struct smbcli_state *cli, struct dom_sid *sid,
335 struct lsa_RightSet *rights)
338 struct lsa_RemoveAccountRights r;
340 status = smblsa_connect(cli);
341 if (!NT_STATUS_IS_OK(status)) {
345 r.in.handle = &cli->lsa->handle;
348 r.in.rights = rights;
350 return dcerpc_lsa_RemoveAccountRights(cli->lsa->pipe, mem_ctx, &r);