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 "libcli/libcli.h"
32 #include "librpc/gen_ndr/ndr_lsa.h"
35 struct dcerpc_pipe *pipe;
36 struct smbcli_tree *ipc_tree;
37 struct policy_handle handle;
41 establish the lsa pipe connection
43 static NTSTATUS smblsa_connect(struct smbcli_state *cli)
45 struct smblsa_state *lsa;
47 struct lsa_OpenPolicy r;
48 uint16_t system_name = '\\';
50 struct lsa_ObjectAttribute attr;
51 struct lsa_QosInfo qos;
53 if (cli->lsa != NULL) {
57 lsa = talloc(cli, struct smblsa_state);
59 return NT_STATUS_NO_MEMORY;
62 lsa->ipc_tree = smbcli_tree_init(cli->session, lsa, False);
63 if (lsa->ipc_tree == NULL) {
64 return NT_STATUS_NO_MEMORY;
68 tcon.generic.level = RAW_TCON_TCONX;
69 tcon.tconx.in.flags = 0;
70 tcon.tconx.in.password = data_blob(NULL, 0);
71 tcon.tconx.in.path = "ipc$";
72 tcon.tconx.in.device = "IPC";
73 status = smb_raw_tcon(lsa->ipc_tree, lsa, &tcon);
74 if (!NT_STATUS_IS_OK(status)) {
78 lsa->ipc_tree->tid = tcon.tconx.out.tid;
80 lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx);
81 if (lsa->pipe == NULL) {
83 return NT_STATUS_NO_MEMORY;
86 /* open the LSA pipe */
87 status = dcerpc_pipe_open_smb(lsa->pipe->conn, lsa->ipc_tree, DCERPC_LSARPC_NAME);
88 if (!NT_STATUS_IS_OK(status)) {
93 /* bind to the LSA pipe */
94 status = dcerpc_bind_auth_none(lsa->pipe, &dcerpc_table_lsarpc);
95 if (!NT_STATUS_IS_OK(status)) {
101 /* open a lsa policy handle */
103 qos.impersonation_level = 2;
104 qos.context_mode = 1;
105 qos.effective_only = 0;
108 attr.root_dir = NULL;
109 attr.object_name = NULL;
111 attr.sec_desc = NULL;
114 r.in.system_name = &system_name;
116 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
117 r.out.handle = &lsa->handle;
119 status = dcerpc_lsa_OpenPolicy(lsa->pipe, lsa, &r);
120 if (!NT_STATUS_IS_OK(status)) {
132 return the set of privileges for the given sid
134 NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid,
136 struct lsa_RightSet *rights)
139 struct lsa_EnumAccountRights r;
141 status = smblsa_connect(cli);
142 if (!NT_STATUS_IS_OK(status)) {
146 r.in.handle = &cli->lsa->handle;
148 r.out.rights = rights;
150 return dcerpc_lsa_EnumAccountRights(cli->lsa->pipe, mem_ctx, &r);
155 check if a named sid has a particular named privilege
157 NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli,
159 const char *privilege)
161 struct lsa_RightSet rights;
163 TALLOC_CTX *mem_ctx = talloc_new(cli);
167 sid = dom_sid_parse_talloc(mem_ctx, sid_str);
169 talloc_free(mem_ctx);
170 return NT_STATUS_INVALID_SID;
173 status = smblsa_sid_privileges(cli, sid, mem_ctx, &rights);
174 if (!NT_STATUS_IS_OK(status)) {
175 talloc_free(mem_ctx);
179 for (i=0;i<rights.count;i++) {
180 if (strcmp(rights.names[i].string, privilege) == 0) {
181 talloc_free(mem_ctx);
186 talloc_free(mem_ctx);
187 return NT_STATUS_NOT_FOUND;
192 lookup a SID, returning its name
194 NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli,
199 struct lsa_LookupSids r;
200 struct lsa_TransNameArray names;
201 struct lsa_SidArray sids;
205 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
207 status = smblsa_connect(cli);
208 if (!NT_STATUS_IS_OK(status)) {
212 sid = dom_sid_parse_talloc(mem_ctx2, sid_str);
214 return NT_STATUS_INVALID_SID;
221 sids.sids = talloc(mem_ctx2, struct lsa_SidPtr);
222 sids.sids[0].sid = sid;
224 r.in.handle = &cli->lsa->handle;
229 r.out.count = &count;
230 r.out.names = &names;
232 status = dcerpc_lsa_LookupSids(cli->lsa->pipe, mem_ctx2, &r);
233 if (!NT_STATUS_IS_OK(status)) {
234 talloc_free(mem_ctx2);
237 if (names.count != 1) {
238 talloc_free(mem_ctx2);
239 return NT_STATUS_UNSUCCESSFUL;
242 (*name) = talloc_asprintf(mem_ctx, "%s\\%s",
243 r.out.domains->domains[0].name.string,
244 names.names[0].name.string);
246 talloc_free(mem_ctx2);
252 lookup a name, returning its sid
254 NTSTATUS smblsa_lookup_name(struct smbcli_state *cli,
257 const char **sid_str)
259 struct lsa_LookupNames r;
260 struct lsa_TransSidArray sids;
261 struct lsa_String names;
265 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
268 status = smblsa_connect(cli);
269 if (!NT_STATUS_IS_OK(status)) {
278 r.in.handle = &cli->lsa->handle;
284 r.out.count = &count;
287 status = dcerpc_lsa_LookupNames(cli->lsa->pipe, mem_ctx2, &r);
288 if (!NT_STATUS_IS_OK(status)) {
289 talloc_free(mem_ctx2);
292 if (sids.count != 1) {
293 talloc_free(mem_ctx2);
294 return NT_STATUS_UNSUCCESSFUL;
297 sid = r.out.domains->domains[0].sid;
298 rid = sids.sids[0].rid;
300 (*sid_str) = talloc_asprintf(mem_ctx, "%s-%u",
301 dom_sid_string(mem_ctx2, sid), rid);
303 talloc_free(mem_ctx2);
310 add a set of privileges to the given sid
312 NTSTATUS smblsa_sid_add_privileges(struct smbcli_state *cli, struct dom_sid *sid,
314 struct lsa_RightSet *rights)
317 struct lsa_AddAccountRights r;
319 status = smblsa_connect(cli);
320 if (!NT_STATUS_IS_OK(status)) {
324 r.in.handle = &cli->lsa->handle;
326 r.in.rights = rights;
328 return dcerpc_lsa_AddAccountRights(cli->lsa->pipe, mem_ctx, &r);
332 remove a set of privileges from the given sid
334 NTSTATUS smblsa_sid_del_privileges(struct smbcli_state *cli, struct dom_sid *sid,
336 struct lsa_RightSet *rights)
339 struct lsa_RemoveAccountRights r;
341 status = smblsa_connect(cli);
342 if (!NT_STATUS_IS_OK(status)) {
346 r.in.handle = &cli->lsa->handle;
349 r.in.rights = rights;
351 return dcerpc_lsa_RemoveAccountRights(cli->lsa->pipe, mem_ctx, &r);