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 3 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, see <http://www.gnu.org/licenses/>.
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.
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"
36 struct dcerpc_pipe *pipe;
37 struct smbcli_tree *ipc_tree;
38 struct policy_handle handle;
42 establish the lsa pipe connection
44 static NTSTATUS smblsa_connect(struct smbcli_state *cli)
46 struct smblsa_state *lsa;
48 struct lsa_OpenPolicy r;
49 uint16_t system_name = '\\';
51 struct lsa_ObjectAttribute attr;
52 struct lsa_QosInfo qos;
54 if (cli->lsa != NULL) {
58 lsa = talloc(cli, struct smblsa_state);
60 return NT_STATUS_NO_MEMORY;
63 lsa->ipc_tree = smbcli_tree_init(cli->session, lsa, False);
64 if (lsa->ipc_tree == NULL) {
65 return NT_STATUS_NO_MEMORY;
69 tcon.generic.level = RAW_TCON_TCONX;
70 tcon.tconx.in.flags = 0;
71 tcon.tconx.in.password = data_blob(NULL, 0);
72 tcon.tconx.in.path = "ipc$";
73 tcon.tconx.in.device = "IPC";
74 status = smb_raw_tcon(lsa->ipc_tree, lsa, &tcon);
75 if (!NT_STATUS_IS_OK(status)) {
79 lsa->ipc_tree->tid = tcon.tconx.out.tid;
81 lsa->pipe = dcerpc_pipe_init(lsa, cli->transport->socket->event.ctx);
82 if (lsa->pipe == NULL) {
84 return NT_STATUS_NO_MEMORY;
87 /* open the LSA pipe */
88 status = dcerpc_pipe_open_smb(lsa->pipe, lsa->ipc_tree, DCERPC_LSARPC_NAME);
89 if (!NT_STATUS_IS_OK(status)) {
94 /* bind to the LSA pipe */
95 status = dcerpc_bind_auth_none(lsa->pipe, &dcerpc_table_lsarpc);
96 if (!NT_STATUS_IS_OK(status)) {
102 /* open a lsa policy handle */
104 qos.impersonation_level = 2;
105 qos.context_mode = 1;
106 qos.effective_only = 0;
109 attr.root_dir = NULL;
110 attr.object_name = NULL;
112 attr.sec_desc = NULL;
115 r.in.system_name = &system_name;
117 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
118 r.out.handle = &lsa->handle;
120 status = dcerpc_lsa_OpenPolicy(lsa->pipe, lsa, &r);
121 if (!NT_STATUS_IS_OK(status)) {
133 return the set of privileges for the given sid
135 NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid,
137 struct lsa_RightSet *rights)
140 struct lsa_EnumAccountRights r;
142 status = smblsa_connect(cli);
143 if (!NT_STATUS_IS_OK(status)) {
147 r.in.handle = &cli->lsa->handle;
149 r.out.rights = rights;
151 return dcerpc_lsa_EnumAccountRights(cli->lsa->pipe, mem_ctx, &r);
156 check if a named sid has a particular named privilege
158 NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli,
160 const char *privilege)
162 struct lsa_RightSet rights;
164 TALLOC_CTX *mem_ctx = talloc_new(cli);
168 sid = dom_sid_parse_talloc(mem_ctx, sid_str);
170 talloc_free(mem_ctx);
171 return NT_STATUS_INVALID_SID;
174 status = smblsa_sid_privileges(cli, sid, mem_ctx, &rights);
175 if (!NT_STATUS_IS_OK(status)) {
176 talloc_free(mem_ctx);
180 for (i=0;i<rights.count;i++) {
181 if (strcmp(rights.names[i].string, privilege) == 0) {
182 talloc_free(mem_ctx);
187 talloc_free(mem_ctx);
188 return NT_STATUS_NOT_FOUND;
193 lookup a SID, returning its name
195 NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli,
200 struct lsa_LookupSids r;
201 struct lsa_TransNameArray names;
202 struct lsa_SidArray sids;
206 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
208 status = smblsa_connect(cli);
209 if (!NT_STATUS_IS_OK(status)) {
213 sid = dom_sid_parse_talloc(mem_ctx2, sid_str);
215 return NT_STATUS_INVALID_SID;
222 sids.sids = talloc(mem_ctx2, struct lsa_SidPtr);
223 sids.sids[0].sid = sid;
225 r.in.handle = &cli->lsa->handle;
230 r.out.count = &count;
231 r.out.names = &names;
233 status = dcerpc_lsa_LookupSids(cli->lsa->pipe, mem_ctx2, &r);
234 if (!NT_STATUS_IS_OK(status)) {
235 talloc_free(mem_ctx2);
238 if (names.count != 1) {
239 talloc_free(mem_ctx2);
240 return NT_STATUS_UNSUCCESSFUL;
243 (*name) = talloc_asprintf(mem_ctx, "%s\\%s",
244 r.out.domains->domains[0].name.string,
245 names.names[0].name.string);
247 talloc_free(mem_ctx2);
253 lookup a name, returning its sid
255 NTSTATUS smblsa_lookup_name(struct smbcli_state *cli,
258 const char **sid_str)
260 struct lsa_LookupNames r;
261 struct lsa_TransSidArray sids;
262 struct lsa_String names;
266 TALLOC_CTX *mem_ctx2 = talloc_new(mem_ctx);
269 status = smblsa_connect(cli);
270 if (!NT_STATUS_IS_OK(status)) {
279 r.in.handle = &cli->lsa->handle;
285 r.out.count = &count;
288 status = dcerpc_lsa_LookupNames(cli->lsa->pipe, mem_ctx2, &r);
289 if (!NT_STATUS_IS_OK(status)) {
290 talloc_free(mem_ctx2);
293 if (sids.count != 1) {
294 talloc_free(mem_ctx2);
295 return NT_STATUS_UNSUCCESSFUL;
298 sid = r.out.domains->domains[0].sid;
299 rid = sids.sids[0].rid;
301 (*sid_str) = talloc_asprintf(mem_ctx, "%s-%u",
302 dom_sid_string(mem_ctx2, sid), rid);
304 talloc_free(mem_ctx2);
311 add a set of privileges to the given sid
313 NTSTATUS smblsa_sid_add_privileges(struct smbcli_state *cli, struct dom_sid *sid,
315 struct lsa_RightSet *rights)
318 struct lsa_AddAccountRights r;
320 status = smblsa_connect(cli);
321 if (!NT_STATUS_IS_OK(status)) {
325 r.in.handle = &cli->lsa->handle;
327 r.in.rights = rights;
329 return dcerpc_lsa_AddAccountRights(cli->lsa->pipe, mem_ctx, &r);
333 remove a set of privileges from the given sid
335 NTSTATUS smblsa_sid_del_privileges(struct smbcli_state *cli, struct dom_sid *sid,
337 struct lsa_RightSet *rights)
340 struct lsa_RemoveAccountRights r;
342 status = smblsa_connect(cli);
343 if (!NT_STATUS_IS_OK(status)) {
347 r.in.handle = &cli->lsa->handle;
350 r.in.rights = rights;
352 return dcerpc_lsa_RemoveAccountRights(cli->lsa->pipe, mem_ctx, &r);