LCOV - code coverage report
Current view: top level - source3/libsmb - clisecdesc.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 120 145 82.8 %
Date: 2024-05-31 13:13:24 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    client security descriptor functions
       4             :    Copyright (C) Andrew Tridgell 2000
       5             : 
       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.
      10             : 
      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.
      15             : 
      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/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      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"
      25             : 
      26             : struct cli_query_security_descriptor_state {
      27             :         uint8_t param[8];
      28             :         DATA_BLOB outbuf;
      29             : };
      30             : 
      31             : static void cli_query_security_descriptor_done1(struct tevent_req *subreq);
      32             : static void cli_query_security_descriptor_done2(struct tevent_req *subreq);
      33             : 
      34        3766 : struct tevent_req *cli_query_security_descriptor_send(
      35             :         TALLOC_CTX *mem_ctx,
      36             :         struct tevent_context *ev,
      37             :         struct cli_state *cli,
      38             :         uint16_t fnum,
      39             :         uint32_t sec_info)
      40             : {
      41        3766 :         struct tevent_req *req = NULL, *subreq = NULL;
      42        3766 :         struct cli_query_security_descriptor_state *state = NULL;
      43             : 
      44        3766 :         req = tevent_req_create(
      45             :                 mem_ctx, &state, struct cli_query_security_descriptor_state);
      46        3766 :         if (req == NULL) {
      47           0 :                 return NULL;
      48             :         }
      49             : 
      50        3766 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
      51        3700 :                 subreq = cli_smb2_query_info_fnum_send(
      52             :                         state,                /* mem_ctx */
      53             :                         ev,                   /* ev */
      54             :                         cli,                  /* cli */
      55             :                         fnum,                 /* fnum */
      56             :                         SMB2_0_INFO_SECURITY, /* in_info_type */
      57             :                         0,                    /* in_info_class */
      58             :                         0xFFFF,               /* in_max_output_length */
      59             :                         NULL,                 /* in_input_buffer */
      60             :                         sec_info,             /* in_additional_info */
      61             :                         0);                   /* in_flags */
      62        3700 :                 if (tevent_req_nomem(subreq, req)) {
      63           0 :                         return tevent_req_post(req, ev);
      64             :                 }
      65        3700 :                 tevent_req_set_callback(
      66             :                         subreq, cli_query_security_descriptor_done2, req);
      67        3700 :                 return req;
      68             :         }
      69             : 
      70          66 :         PUSH_LE_U32(state->param, 0, fnum);
      71          66 :         PUSH_LE_U32(state->param, 4, sec_info);
      72             : 
      73          66 :         subreq = cli_trans_send(
      74             :                 state,          /* mem_ctx */
      75             :                 ev,             /* ev */
      76             :                 cli,            /* cli */
      77             :                 0,              /* additional_flags2 */
      78             :                 SMBnttrans,     /* cmd */
      79             :                 NULL,           /* pipe_name */
      80             :                 -1,             /* fid */
      81             :                 NT_TRANSACT_QUERY_SECURITY_DESC, /* function */
      82             :                 0,              /* flags */
      83             :                 NULL,           /* setup */
      84             :                 0,              /* num_setup */
      85             :                 0,              /* max_setup */
      86          66 :                 state->param,        /* param */
      87             :                 8,              /* num_param */
      88             :                 4,              /* max_param */
      89             :                 NULL,           /* data */
      90             :                 0,              /* num_data */
      91             :                 0x10000);       /* max_data */
      92          66 :         if (tevent_req_nomem(subreq, req)) {
      93           0 :                 return tevent_req_post(req, ev);
      94             :         }
      95          66 :         tevent_req_set_callback(
      96             :                 subreq, cli_query_security_descriptor_done1, req);
      97          66 :         return req;
      98             : }
      99             : 
     100          66 : static void cli_query_security_descriptor_done1(struct tevent_req *subreq)
     101             : {
     102          66 :         struct tevent_req *req = tevent_req_callback_data(
     103             :                 subreq, struct tevent_req);
     104          66 :         struct cli_query_security_descriptor_state *state = tevent_req_data(
     105             :                 req, struct cli_query_security_descriptor_state);
     106           0 :         NTSTATUS status;
     107           0 :         uint32_t len;
     108             : 
     109          66 :         status = cli_trans_recv(
     110             :                 subreq,         /* req */
     111             :                 state,          /* mem_ctx */
     112             :                 NULL,           /* recv_flags2 */
     113             :                 NULL,           /* setup */
     114             :                 0,              /* min_setup */
     115             :                 NULL,           /* num_setup */
     116             :                 NULL,           /* param */
     117             :                 0,              /* min_param */
     118             :                 NULL,           /* num_param */
     119             :                 &state->outbuf.data, /* data */
     120             :                 0,              /* min_data */
     121             :                 &len);              /* num_data */
     122          66 :         TALLOC_FREE(subreq);
     123          66 :         if (tevent_req_nterror(req, status)) {
     124           0 :                 return;
     125             :         }
     126          66 :         state->outbuf.length = len; /* uint32_t -> size_t */
     127          66 :         tevent_req_done(req);
     128             : }
     129             : 
     130        3700 : static void cli_query_security_descriptor_done2(struct tevent_req *subreq)
     131             : {
     132        3700 :         struct tevent_req *req = tevent_req_callback_data(
     133             :                 subreq, struct tevent_req);
     134        3700 :         struct cli_query_security_descriptor_state *state = tevent_req_data(
     135             :                 req, struct cli_query_security_descriptor_state);
     136           0 :         NTSTATUS status;
     137             : 
     138        3700 :         status = cli_smb2_query_info_fnum_recv(subreq, state, &state->outbuf);
     139        3700 :         TALLOC_FREE(subreq);
     140        3700 :         if (tevent_req_nterror(req, status)) {
     141           8 :                 return;
     142             :         }
     143        3692 :         tevent_req_done(req);
     144             : }
     145             : 
     146        3766 : NTSTATUS cli_query_security_descriptor_recv(
     147             :         struct tevent_req *req,
     148             :         TALLOC_CTX *mem_ctx,
     149             :         struct security_descriptor **sd)
     150             : {
     151        3766 :         struct cli_query_security_descriptor_state *state = tevent_req_data(
     152             :                 req, struct cli_query_security_descriptor_state);
     153        3766 :         NTSTATUS status = NT_STATUS_OK;
     154             : 
     155        3766 :         if (tevent_req_is_nterror(req, &status)) {
     156           8 :                 goto done;
     157             :         }
     158        3758 :         if (sd != NULL) {
     159        3758 :                 status = unmarshall_sec_desc(
     160             :                         mem_ctx, state->outbuf.data, state->outbuf.length, sd);
     161             :         }
     162           0 : done:
     163        3766 :         tevent_req_received(req);
     164        3766 :         return status;
     165             : }
     166             : 
     167        3412 : NTSTATUS cli_query_security_descriptor(struct cli_state *cli,
     168             :                                        uint16_t fnum,
     169             :                                        uint32_t sec_info,
     170             :                                        TALLOC_CTX *mem_ctx,
     171             :                                        struct security_descriptor **sd)
     172             : {
     173        3412 :         TALLOC_CTX *frame = talloc_stackframe();
     174        3412 :         struct tevent_context *ev = NULL;
     175        3412 :         struct tevent_req *req = NULL;
     176        3412 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     177             : 
     178        3412 :         if (smbXcli_conn_has_async_calls(cli->conn)) {
     179           0 :                 status = NT_STATUS_INVALID_PARAMETER;
     180           0 :                 goto fail;
     181             :         }
     182        3412 :         ev = samba_tevent_context_init(frame);
     183        3412 :         if (ev == NULL) {
     184           0 :                 goto fail;
     185             :         }
     186        3412 :         req = cli_query_security_descriptor_send(
     187             :                 frame, ev, cli, fnum, sec_info);
     188        3412 :         if (req == NULL) {
     189           0 :                 goto fail;
     190             :         }
     191        3412 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     192           0 :                 goto fail;
     193             :         }
     194        3412 :         status = cli_query_security_descriptor_recv(req, mem_ctx, sd);
     195        3412 :  fail:
     196        3412 :         TALLOC_FREE(frame);
     197        3412 :         return status;
     198             : }
     199             : 
     200          34 : NTSTATUS cli_query_secdesc(struct cli_state *cli, uint16_t fnum,
     201             :                            TALLOC_CTX *mem_ctx, struct security_descriptor **sd)
     202             : {
     203          34 :         uint32_t sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL;
     204             : 
     205          34 :         return cli_query_security_descriptor(cli, fnum, sec_info, mem_ctx, sd);
     206             : }
     207             : 
     208           4 : NTSTATUS cli_query_mxac(struct cli_state *cli,
     209             :                         const char *filename,
     210             :                         uint32_t *mxac)
     211             : {
     212           4 :         if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
     213           0 :                 return NT_STATUS_NOT_SUPPORTED;
     214             :         }
     215             : 
     216           4 :         return cli_smb2_query_mxac(cli, filename, mxac);
     217             : }
     218             : 
     219             : struct cli_set_security_descriptor_state {
     220             :         uint8_t param[8];
     221             :         DATA_BLOB buf;
     222             : };
     223             : 
     224             : static void cli_set_security_descriptor_done1(struct tevent_req *subreq);
     225             : static void cli_set_security_descriptor_done2(struct tevent_req *subreq);
     226             : 
     227        2660 : struct tevent_req *cli_set_security_descriptor_send(
     228             :         TALLOC_CTX *mem_ctx,
     229             :         struct tevent_context *ev,
     230             :         struct cli_state *cli,
     231             :         uint16_t fnum,
     232             :         uint32_t sec_info,
     233             :         const struct security_descriptor *sd)
     234             : {
     235        2660 :         struct tevent_req *req = NULL, *subreq = NULL;
     236        2660 :         struct cli_set_security_descriptor_state *state = NULL;
     237           0 :         NTSTATUS status;
     238             : 
     239        2660 :         req = tevent_req_create(
     240             :                 mem_ctx, &state, struct cli_set_security_descriptor_state);
     241        2660 :         if (req == NULL) {
     242           0 :                 return NULL;
     243             :         }
     244             : 
     245        2660 :         status = marshall_sec_desc(
     246        2660 :                 state, sd, &state->buf.data, &state->buf.length);
     247        2660 :         if (tevent_req_nterror(req, status)) {
     248           0 :                 return tevent_req_post(req, ev);
     249             :         }
     250             : 
     251        2660 :         if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
     252        2608 :                 subreq = cli_smb2_set_info_fnum_send(
     253             :                         state,  /* mem_ctx */
     254             :                         ev,     /* ev */
     255             :                         cli,    /* cli */
     256             :                         fnum,   /* fnum */
     257             :                         3,      /* in_info_type */
     258             :                         0,      /* in_file_info_class */
     259        2608 :                         &state->buf, /* in_input_buffer */
     260             :                         sec_info); /* in_additional_info */
     261        2608 :                 if (tevent_req_nomem(subreq, req)) {
     262           0 :                         return tevent_req_post(req, ev);
     263             :                 }
     264        2608 :                 tevent_req_set_callback(
     265             :                         subreq, cli_set_security_descriptor_done2, req);
     266        2608 :                 return req;
     267             :         }
     268             : 
     269          52 :         SIVAL(state->param, 0, fnum);
     270          52 :         SIVAL(state->param, 4, sec_info);
     271             : 
     272          52 :         subreq = cli_trans_send(
     273             :                 state,          /* mem_ctx */
     274             :                 ev,             /* ev */
     275             :                 cli,            /* cli */
     276             :                 0,              /* additional_flags2 */
     277             :                 SMBnttrans,     /* cmd */
     278             :                 NULL,           /* pipe_name */
     279             :                 -1,             /* fid */
     280             :                 NT_TRANSACT_SET_SECURITY_DESC, /* function */
     281             :                 0,              /* flags */
     282             :                 NULL,           /* setup */
     283             :                 0,              /* num_setup */
     284             :                 0,              /* max_setup */
     285          52 :                 state->param,        /* param */
     286             :                 8,              /* num_param */
     287             :                 0,              /* max_param */
     288          52 :                 state->buf.data, /* data */
     289          52 :                 state->buf.length, /* num_data */
     290             :                 0);             /* max_data */
     291          52 :         if (tevent_req_nomem(subreq, req)) {
     292           0 :                 return tevent_req_post(req, ev);
     293             :         }
     294          52 :         tevent_req_set_callback(
     295             :                 subreq, cli_set_security_descriptor_done1, req);
     296          52 :         return req;
     297             : }
     298             : 
     299          52 : static void cli_set_security_descriptor_done1(struct tevent_req *subreq)
     300             : {
     301          52 :         NTSTATUS status = cli_trans_recv(
     302             :                 subreq, NULL, NULL, NULL, 0, NULL, NULL, 0, NULL,
     303             :                 NULL, 0, NULL);
     304          52 :         return tevent_req_simple_finish_ntstatus(subreq, status);
     305             : }
     306             : 
     307        2608 : static void cli_set_security_descriptor_done2(struct tevent_req *subreq)
     308             : {
     309        2608 :         NTSTATUS status = cli_smb2_set_info_fnum_recv(subreq);
     310        2608 :         tevent_req_simple_finish_ntstatus(subreq, status);
     311        2608 : }
     312             : 
     313        2660 : NTSTATUS cli_set_security_descriptor_recv(struct tevent_req *req)
     314             : {
     315        2660 :         return tevent_req_simple_recv_ntstatus(req);
     316             : }
     317             : 
     318             : /****************************************************************************
     319             :   set the security descriptor for a open file
     320             :  ****************************************************************************/
     321        2206 : NTSTATUS cli_set_security_descriptor(struct cli_state *cli,
     322             :                                      uint16_t fnum,
     323             :                                      uint32_t sec_info,
     324             :                                      const struct security_descriptor *sd)
     325             : {
     326        2206 :         TALLOC_CTX *frame = talloc_stackframe();
     327        2206 :         struct tevent_context *ev = NULL;
     328        2206 :         struct tevent_req *req = NULL;
     329        2206 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     330             : 
     331        2206 :         if (smbXcli_conn_has_async_calls(cli->conn)) {
     332           0 :                 status = NT_STATUS_INVALID_PARAMETER;
     333           0 :                 goto fail;
     334             :         }
     335        2206 :         ev = samba_tevent_context_init(frame);
     336        2206 :         if (ev == NULL) {
     337           0 :                 goto fail;
     338             :         }
     339        2206 :         req = cli_set_security_descriptor_send(
     340             :                 frame, ev, cli, fnum, sec_info, sd);
     341        2206 :         if (req == NULL) {
     342           0 :                 goto fail;
     343             :         }
     344        2206 :         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
     345           0 :                 goto fail;
     346             :         }
     347        2206 :         status = cli_set_security_descriptor_recv(req);
     348        2206 :  fail:
     349        2206 :         TALLOC_FREE(frame);
     350        2206 :         return status;
     351             : }
     352             : 
     353          16 : NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum,
     354             :                          const struct security_descriptor *sd)
     355             : {
     356          16 :         uint32_t sec_info = 0;
     357             : 
     358          16 :         if (sd->dacl || (sd->type & SEC_DESC_DACL_PRESENT)) {
     359          16 :                 sec_info |= SECINFO_DACL;
     360             :         }
     361          16 :         if (sd->sacl || (sd->type & SEC_DESC_SACL_PRESENT)) {
     362           0 :                 sec_info |= SECINFO_SACL;
     363             :         }
     364          16 :         if (sd->owner_sid) {
     365          16 :                 sec_info |= SECINFO_OWNER;
     366             :         }
     367          16 :         if (sd->group_sid) {
     368          16 :                 sec_info |= SECINFO_GROUP;
     369             :         }
     370             : 
     371          16 :         return cli_set_security_descriptor(cli, fnum, sec_info, sd);
     372             : }

Generated by: LCOV version 1.14