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
);