2 Unix SMB/CIFS implementation.
3 client security descriptor functions
4 Copyright (C) Andrew Tridgell 2000
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "libsmb/libsmb.h"
22 #include "../libcli/security/secdesc.h"
23 #include "../libcli/smb/smbXcli_base.h"
24 #include "lib/util/tevent_ntstatus.h"
26 struct cli_query_security_descriptor_state {
31 static void cli_query_security_descriptor_done1(struct tevent_req *subreq);
32 static void cli_query_security_descriptor_done2(struct tevent_req *subreq);
34 struct tevent_req *cli_query_security_descriptor_send(
36 struct tevent_context *ev,
37 struct cli_state *cli,
41 struct tevent_req *req = NULL, *subreq = NULL;
42 struct cli_query_security_descriptor_state *state = NULL;
44 req = tevent_req_create(
45 mem_ctx, &state, struct cli_query_security_descriptor_state);
50 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
51 subreq = cli_smb2_query_info_fnum_send(
57 0, /* in_info_class */
58 0xFFFF, /* in_max_output_length */
59 NULL, /* in_input_buffer */
60 sec_info, /* in_additional_info */
62 if (tevent_req_nomem(subreq, req)) {
63 return tevent_req_post(req, ev);
65 tevent_req_set_callback(
66 subreq, cli_query_security_descriptor_done2, req);
70 PUSH_LE_U32(state->param, 0, fnum);
71 PUSH_LE_U32(state->param, 4, sec_info);
73 subreq = cli_trans_send(
77 0, /* additional_flags2 */
81 NT_TRANSACT_QUERY_SECURITY_DESC, /* function */
86 state->param, /* param */
91 0x10000); /* max_data */
92 if (tevent_req_nomem(subreq, req)) {
93 return tevent_req_post(req, ev);
95 tevent_req_set_callback(
96 subreq, cli_query_security_descriptor_done1, req);
100 static void cli_query_security_descriptor_done1(struct tevent_req *subreq)
102 struct tevent_req *req = tevent_req_callback_data(
103 subreq, struct tevent_req);
104 struct cli_query_security_descriptor_state *state = tevent_req_data(
105 req, struct cli_query_security_descriptor_state);
109 status = cli_trans_recv(
112 NULL, /* recv_flags2 */
115 NULL, /* num_setup */
118 NULL, /* num_param */
119 &state->outbuf.data, /* data */
121 &len); /* num_data */
123 if (tevent_req_nterror(req, status)) {
126 state->outbuf.length = len; /* uint32_t -> size_t */
127 tevent_req_done(req);
130 static void cli_query_security_descriptor_done2(struct tevent_req *subreq)
132 struct tevent_req *req = tevent_req_callback_data(
133 subreq, struct tevent_req);
134 struct cli_query_security_descriptor_state *state = tevent_req_data(
135 req, struct cli_query_security_descriptor_state);
138 status = cli_smb2_query_info_fnum_recv(subreq, state, &state->outbuf);
140 if (tevent_req_nterror(req, status)) {
143 tevent_req_done(req);
146 NTSTATUS cli_query_security_descriptor_recv(
147 struct tevent_req *req,
149 struct security_descriptor **sd)
151 struct cli_query_security_descriptor_state *state = tevent_req_data(
152 req, struct cli_query_security_descriptor_state);
153 NTSTATUS status = NT_STATUS_OK;
155 if (tevent_req_is_nterror(req, &status)) {
159 status = unmarshall_sec_desc(
160 mem_ctx, state->outbuf.data, state->outbuf.length, sd);
163 tevent_req_received(req);
167 NTSTATUS cli_query_security_descriptor(struct cli_state *cli,
171 struct security_descriptor **sd)
173 TALLOC_CTX *frame = talloc_stackframe();
174 struct tevent_context *ev = NULL;
175 struct tevent_req *req = NULL;
176 NTSTATUS status = NT_STATUS_NO_MEMORY;
178 if (smbXcli_conn_has_async_calls(cli->conn)) {
179 status = NT_STATUS_INVALID_PARAMETER;
182 ev = samba_tevent_context_init(frame);
186 req = cli_query_security_descriptor_send(
187 frame, ev, cli, fnum, sec_info);
191 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
194 status = cli_query_security_descriptor_recv(req, mem_ctx, sd);
200 NTSTATUS cli_query_secdesc(struct cli_state *cli, uint16_t fnum,
201 TALLOC_CTX *mem_ctx, struct security_descriptor **sd)
203 uint32_t sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
205 return cli_query_security_descriptor(cli, fnum, sec_info, mem_ctx, sd);
208 NTSTATUS cli_query_mxac(struct cli_state *cli,
209 const char *filename,
212 if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
213 return NT_STATUS_NOT_SUPPORTED;
216 return cli_smb2_query_mxac(cli, filename, mxac);
219 struct cli_set_security_descriptor_state {
224 static void cli_set_security_descriptor_done1(struct tevent_req *subreq);
225 static void cli_set_security_descriptor_done2(struct tevent_req *subreq);
227 struct tevent_req *cli_set_security_descriptor_send(
229 struct tevent_context *ev,
230 struct cli_state *cli,
233 const struct security_descriptor *sd)
235 struct tevent_req *req = NULL, *subreq = NULL;
236 struct cli_set_security_descriptor_state *state = NULL;
239 req = tevent_req_create(
240 mem_ctx, &state, struct cli_set_security_descriptor_state);
245 status = marshall_sec_desc(
246 state, sd, &state->buf.data, &state->buf.length);
247 if (tevent_req_nterror(req, status)) {
248 return tevent_req_post(req, ev);
251 if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
252 subreq = cli_smb2_set_info_fnum_send(
257 3, /* in_info_type */
258 0, /* in_file_info_class */
259 &state->buf, /* in_input_buffer */
260 sec_info); /* in_additional_info */
261 if (tevent_req_nomem(subreq, req)) {
262 return tevent_req_post(req, ev);
264 tevent_req_set_callback(
265 subreq, cli_set_security_descriptor_done2, req);
269 SIVAL(state->param, 0, fnum);
270 SIVAL(state->param, 4, sec_info);
272 subreq = cli_trans_send(
276 0, /* additional_flags2 */
277 SMBnttrans, /* cmd */
278 NULL, /* pipe_name */
280 NT_TRANSACT_SET_SECURITY_DESC, /* function */
285 state->param, /* param */
288 state->buf.data, /* data */
289 state->buf.length, /* num_data */
291 if (tevent_req_nomem(subreq, req)) {
292 return tevent_req_post(req, ev);
294 tevent_req_set_callback(
295 subreq, cli_set_security_descriptor_done1, req);
299 static void cli_set_security_descriptor_done1(struct tevent_req *subreq)
301 NTSTATUS status = cli_trans_recv(
302 subreq, NULL, NULL, NULL, 0, NULL, NULL, 0, NULL,
304 return tevent_req_simple_finish_ntstatus(subreq, status);
307 static void cli_set_security_descriptor_done2(struct tevent_req *subreq)
309 NTSTATUS status = cli_smb2_set_info_fnum_recv(subreq);
310 tevent_req_simple_finish_ntstatus(subreq, status);
313 NTSTATUS cli_set_security_descriptor_recv(struct tevent_req *req)
315 return tevent_req_simple_recv_ntstatus(req);
318 /****************************************************************************
319 set the security descriptor for a open file
320 ****************************************************************************/
321 NTSTATUS cli_set_security_descriptor(struct cli_state *cli,
324 const struct security_descriptor *sd)
326 TALLOC_CTX *frame = talloc_stackframe();
327 struct tevent_context *ev = NULL;
328 struct tevent_req *req = NULL;
329 NTSTATUS status = NT_STATUS_NO_MEMORY;
331 if (smbXcli_conn_has_async_calls(cli->conn)) {
332 status = NT_STATUS_INVALID_PARAMETER;
335 ev = samba_tevent_context_init(frame);
339 req = cli_set_security_descriptor_send(
340 frame, ev, cli, fnum, sec_info, sd);
344 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
347 status = cli_set_security_descriptor_recv(req);
353 NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum,
354 const struct security_descriptor *sd)
356 uint32_t sec_info = 0;
358 if (sd->dacl || (sd->type & SEC_DESC_DACL_PRESENT)) {
359 sec_info |= SECINFO_DACL;
361 if (sd->sacl || (sd->type & SEC_DESC_SACL_PRESENT)) {
362 sec_info |= SECINFO_SACL;
365 sec_info |= SECINFO_OWNER;
368 sec_info |= SECINFO_GROUP;
371 return cli_set_security_descriptor(cli, fnum, sec_info, sd);