2023-12-18 23:13:56 +03:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-12-03 05:18:14 +03:00
client security descriptor functions
Copyright ( C ) Andrew Tridgell 2000
2011-01-15 18:07:31 +03:00
2000-12-03 05:18:14 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2000-12-03 05:18:14 +03:00
( at your option ) any later version .
2011-01-15 18:07:31 +03:00
2000-12-03 05:18:14 +03:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2011-01-15 18:07:31 +03:00
2000-12-03 05:18:14 +03:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2000-12-03 05:18:14 +03:00
*/
# include "includes.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2011-05-30 07:23:56 +04:00
# include "../libcli/security/secdesc.h"
2013-08-08 22:00:08 +04:00
# include "../libcli/smb/smbXcli_base.h"
2020-11-09 23:37:10 +03:00
# include "lib/util/tevent_ntstatus.h"
2000-12-03 05:18:14 +03:00
2020-11-09 23:37:10 +03:00
struct cli_query_security_descriptor_state {
2011-07-22 17:11:31 +04:00
uint8_t param [ 8 ] ;
2020-11-09 23:37:10 +03:00
DATA_BLOB outbuf ;
} ;
static void cli_query_security_descriptor_done1 ( struct tevent_req * subreq ) ;
static void cli_query_security_descriptor_done2 ( struct tevent_req * subreq ) ;
struct tevent_req * cli_query_security_descriptor_send (
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct cli_state * cli ,
uint16_t fnum ,
uint32_t sec_info )
{
struct tevent_req * req = NULL , * subreq = NULL ;
struct cli_query_security_descriptor_state * state = NULL ;
req = tevent_req_create (
mem_ctx , & state , struct cli_query_security_descriptor_state ) ;
if ( req = = NULL ) {
return NULL ;
}
2011-07-22 17:11:31 +04:00
2013-08-08 22:00:08 +04:00
if ( smbXcli_conn_protocol ( cli - > conn ) > = PROTOCOL_SMB2_02 ) {
2020-11-09 23:37:10 +03:00
subreq = cli_smb2_query_info_fnum_send (
2024-05-09 10:37:51 +03:00
state , /* mem_ctx */
ev , /* ev */
cli , /* cli */
fnum , /* fnum */
SMB2_0_INFO_SECURITY , /* in_info_type */
0 , /* in_info_class */
0xFFFF , /* in_max_output_length */
NULL , /* in_input_buffer */
sec_info , /* in_additional_info */
0 ) ; /* in_flags */
2020-11-09 23:37:10 +03:00
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback (
subreq , cli_query_security_descriptor_done2 , req ) ;
return req ;
2013-08-08 22:00:08 +04:00
}
2020-11-09 23:37:10 +03:00
PUSH_LE_U32 ( state - > param , 0 , fnum ) ;
PUSH_LE_U32 ( state - > param , 4 , sec_info ) ;
subreq = cli_trans_send (
state , /* mem_ctx */
ev , /* ev */
cli , /* cli */
0 , /* additional_flags2 */
SMBnttrans , /* cmd */
NULL , /* pipe_name */
- 1 , /* fid */
NT_TRANSACT_QUERY_SECURITY_DESC , /* function */
0 , /* flags */
NULL , /* setup */
0 , /* num_setup */
0 , /* max_setup */
state - > param , /* param */
8 , /* num_param */
4 , /* max_param */
NULL , /* data */
0 , /* num_data */
0x10000 ) ; /* max_data */
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
2011-07-22 17:11:31 +04:00
}
2020-11-09 23:37:10 +03:00
tevent_req_set_callback (
subreq , cli_query_security_descriptor_done1 , req ) ;
return req ;
}
2011-07-22 17:11:31 +04:00
2020-11-09 23:37:10 +03:00
static void cli_query_security_descriptor_done1 ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct cli_query_security_descriptor_state * state = tevent_req_data (
req , struct cli_query_security_descriptor_state ) ;
NTSTATUS status ;
uint32_t len ;
status = cli_trans_recv (
subreq , /* req */
state , /* mem_ctx */
NULL , /* recv_flags2 */
NULL , /* setup */
0 , /* min_setup */
NULL , /* num_setup */
NULL , /* param */
0 , /* min_param */
NULL , /* num_param */
& state - > outbuf . data , /* data */
0 , /* min_data */
& len ) ; /* num_data */
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
return ;
2011-07-22 17:11:31 +04:00
}
2020-11-09 23:37:10 +03:00
state - > outbuf . length = len ; /* uint32_t -> size_t */
tevent_req_done ( req ) ;
}
2011-07-22 17:11:31 +04:00
2020-11-09 23:37:10 +03:00
static void cli_query_security_descriptor_done2 ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct cli_query_security_descriptor_state * state = tevent_req_data (
req , struct cli_query_security_descriptor_state ) ;
NTSTATUS status ;
status = cli_smb2_query_info_fnum_recv ( subreq , state , & state - > outbuf ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
return ;
2011-07-22 17:11:31 +04:00
}
2020-11-09 23:37:10 +03:00
tevent_req_done ( req ) ;
}
2011-07-22 17:11:31 +04:00
2020-11-09 23:37:10 +03:00
NTSTATUS cli_query_security_descriptor_recv (
struct tevent_req * req ,
TALLOC_CTX * mem_ctx ,
struct security_descriptor * * sd )
{
struct cli_query_security_descriptor_state * state = tevent_req_data (
req , struct cli_query_security_descriptor_state ) ;
NTSTATUS status = NT_STATUS_OK ;
2011-07-22 17:11:31 +04:00
2020-11-09 23:37:10 +03:00
if ( tevent_req_is_nterror ( req , & status ) ) {
goto done ;
}
if ( sd ! = NULL ) {
status = unmarshall_sec_desc (
mem_ctx , state - > outbuf . data , state - > outbuf . length , sd ) ;
}
done :
tevent_req_received ( req ) ;
return status ;
}
2011-07-22 17:11:31 +04:00
2020-11-09 23:37:10 +03:00
NTSTATUS cli_query_security_descriptor ( struct cli_state * cli ,
uint16_t fnum ,
uint32_t sec_info ,
TALLOC_CTX * mem_ctx ,
struct security_descriptor * * sd )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct tevent_context * ev = NULL ;
struct tevent_req * req = NULL ;
NTSTATUS status = NT_STATUS_NO_MEMORY ;
if ( smbXcli_conn_has_async_calls ( cli - > conn ) ) {
status = NT_STATUS_INVALID_PARAMETER ;
goto fail ;
}
ev = samba_tevent_context_init ( frame ) ;
if ( ev = = NULL ) {
goto fail ;
}
req = cli_query_security_descriptor_send (
frame , ev , cli , fnum , sec_info ) ;
if ( req = = NULL ) {
goto fail ;
}
if ( ! tevent_req_poll_ntstatus ( req , ev , & status ) ) {
goto fail ;
}
status = cli_query_security_descriptor_recv ( req , mem_ctx , sd ) ;
fail :
TALLOC_FREE ( frame ) ;
2011-07-22 17:11:31 +04:00
return status ;
}
2012-11-30 16:52:53 +04:00
NTSTATUS cli_query_secdesc ( struct cli_state * cli , uint16_t fnum ,
TALLOC_CTX * mem_ctx , struct security_descriptor * * sd )
{
uint32_t sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL ;
return cli_query_security_descriptor ( cli , fnum , sec_info , mem_ctx , sd ) ;
}
2019-03-01 11:49:17 +03:00
NTSTATUS cli_query_mxac ( struct cli_state * cli ,
const char * filename ,
uint32_t * mxac )
{
if ( smbXcli_conn_protocol ( cli - > conn ) < PROTOCOL_SMB2_02 ) {
return NT_STATUS_NOT_SUPPORTED ;
}
return cli_smb2_query_mxac ( cli , filename , mxac ) ;
}
2020-11-10 22:55:29 +03:00
struct cli_set_security_descriptor_state {
uint8_t param [ 8 ] ;
DATA_BLOB buf ;
} ;
static void cli_set_security_descriptor_done1 ( struct tevent_req * subreq ) ;
static void cli_set_security_descriptor_done2 ( struct tevent_req * subreq ) ;
struct tevent_req * cli_set_security_descriptor_send (
TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
struct cli_state * cli ,
uint16_t fnum ,
uint32_t sec_info ,
const struct security_descriptor * sd )
{
struct tevent_req * req = NULL , * subreq = NULL ;
struct cli_set_security_descriptor_state * state = NULL ;
NTSTATUS status ;
req = tevent_req_create (
mem_ctx , & state , struct cli_set_security_descriptor_state ) ;
if ( req = = NULL ) {
return NULL ;
}
status = marshall_sec_desc (
state , sd , & state - > buf . data , & state - > buf . length ) ;
if ( tevent_req_nterror ( req , status ) ) {
return tevent_req_post ( req , ev ) ;
}
if ( smbXcli_conn_protocol ( cli - > conn ) > = PROTOCOL_SMB2_02 ) {
subreq = cli_smb2_set_info_fnum_send (
2024-05-25 13:41:58 +03:00
state , /* mem_ctx */
ev , /* ev */
cli , /* cli */
fnum , /* fnum */
SMB2_0_INFO_SECURITY , /* in_info_type */
0 , /* in_file_info_class */
& state - > buf , /* in_input_buffer */
sec_info ) ; /* in_additional_info */
2020-11-10 22:55:29 +03:00
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback (
subreq , cli_set_security_descriptor_done2 , req ) ;
return req ;
}
SIVAL ( state - > param , 0 , fnum ) ;
SIVAL ( state - > param , 4 , sec_info ) ;
subreq = cli_trans_send (
state , /* mem_ctx */
ev , /* ev */
cli , /* cli */
0 , /* additional_flags2 */
SMBnttrans , /* cmd */
NULL , /* pipe_name */
- 1 , /* fid */
NT_TRANSACT_SET_SECURITY_DESC , /* function */
0 , /* flags */
NULL , /* setup */
0 , /* num_setup */
0 , /* max_setup */
state - > param , /* param */
8 , /* num_param */
0 , /* max_param */
state - > buf . data , /* data */
state - > buf . length , /* num_data */
0 ) ; /* max_data */
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback (
subreq , cli_set_security_descriptor_done1 , req ) ;
return req ;
}
static void cli_set_security_descriptor_done1 ( struct tevent_req * subreq )
{
NTSTATUS status = cli_trans_recv (
subreq , NULL , NULL , NULL , 0 , NULL , NULL , 0 , NULL ,
NULL , 0 , NULL ) ;
return tevent_req_simple_finish_ntstatus ( subreq , status ) ;
}
static void cli_set_security_descriptor_done2 ( struct tevent_req * subreq )
{
NTSTATUS status = cli_smb2_set_info_fnum_recv ( subreq ) ;
tevent_req_simple_finish_ntstatus ( subreq , status ) ;
}
NTSTATUS cli_set_security_descriptor_recv ( struct tevent_req * req )
{
return tevent_req_simple_recv_ntstatus ( req ) ;
}
2019-03-01 11:49:17 +03:00
2000-12-03 10:36:15 +03:00
/****************************************************************************
set the security descriptor for a open file
2001-07-05 12:24:03 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-11-30 16:52:53 +04:00
NTSTATUS cli_set_security_descriptor ( struct cli_state * cli ,
uint16_t fnum ,
uint32_t sec_info ,
const struct security_descriptor * sd )
2000-12-03 10:36:15 +03:00
{
2020-11-10 22:55:29 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
struct tevent_context * ev = NULL ;
struct tevent_req * req = NULL ;
NTSTATUS status = NT_STATUS_NO_MEMORY ;
2007-12-30 00:47:03 +03:00
2020-11-10 22:55:29 +03:00
if ( smbXcli_conn_has_async_calls ( cli - > conn ) ) {
status = NT_STATUS_INVALID_PARAMETER ;
goto fail ;
2013-08-08 22:00:49 +04:00
}
2020-11-10 22:55:29 +03:00
ev = samba_tevent_context_init ( frame ) ;
if ( ev = = NULL ) {
goto fail ;
2000-12-03 10:36:15 +03:00
}
2020-11-10 22:55:29 +03:00
req = cli_set_security_descriptor_send (
frame , ev , cli , fnum , sec_info , sd ) ;
if ( req = = NULL ) {
goto fail ;
2000-12-03 10:36:15 +03:00
}
2020-11-10 22:55:29 +03:00
if ( ! tevent_req_poll_ntstatus ( req , ev , & status ) ) {
goto fail ;
}
status = cli_set_security_descriptor_recv ( req ) ;
fail :
TALLOC_FREE ( frame ) ;
2011-01-15 18:20:37 +03:00
return status ;
2000-12-03 10:36:15 +03:00
}
2012-11-30 16:52:53 +04:00
NTSTATUS cli_set_secdesc ( struct cli_state * cli , uint16_t fnum ,
const struct security_descriptor * sd )
{
uint32_t sec_info = 0 ;
if ( sd - > dacl | | ( sd - > type & SEC_DESC_DACL_PRESENT ) ) {
sec_info | = SECINFO_DACL ;
}
if ( sd - > sacl | | ( sd - > type & SEC_DESC_SACL_PRESENT ) ) {
sec_info | = SECINFO_SACL ;
}
if ( sd - > owner_sid ) {
sec_info | = SECINFO_OWNER ;
}
if ( sd - > group_sid ) {
sec_info | = SECINFO_GROUP ;
}
return cli_set_security_descriptor ( cli , fnum , sec_info , sd ) ;
}