LCOV - code coverage report
Current view: top level - source4/torture/smb2 - util.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 398 480 82.9 %
Date: 2024-04-21 15:09:00 Functions: 38 38 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    helper functions for SMB2 test suite
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2005
       7             :    
       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.
      12             :    
      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.
      17             :    
      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/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/security/security_descriptor.h"
      24             : #include "libcli/smb2/smb2.h"
      25             : #include "libcli/smb2/smb2_calls.h"
      26             : #include "../libcli/smb/smbXcli_base.h"
      27             : #include "lib/cmdline/cmdline.h"
      28             : #include "system/time.h"
      29             : #include "librpc/gen_ndr/ndr_security.h"
      30             : #include "param/param.h"
      31             : #include "libcli/resolve/resolve.h"
      32             : #include "lib/util/tevent_ntstatus.h"
      33             : 
      34             : #include "torture/torture.h"
      35             : #include "torture/smb2/proto.h"
      36             : #include "source4/torture/util.h"
      37             : #include "libcli/security/dom_sid.h"
      38             : #include "librpc/gen_ndr/lsa.h"
      39             : #include "libcli/util/clilsa.h"
      40             : 
      41             : 
      42             : /*
      43             :   write to a file on SMB2
      44             : */
      45       53932 : NTSTATUS smb2_util_write(struct smb2_tree *tree,
      46             :                          struct smb2_handle handle, 
      47             :                          const void *buf, off_t offset, size_t size)
      48             : {
      49           2 :         struct smb2_write w;
      50             : 
      51       53932 :         ZERO_STRUCT(w);
      52       53932 :         w.in.file.handle = handle;
      53       53932 :         w.in.offset      = offset;
      54       53932 :         w.in.data        = data_blob_const(buf, size);
      55             : 
      56       53932 :         return smb2_write(tree, &w);
      57             : }
      58             : 
      59             : /*
      60             :   create a complex file/dir using the SMB2 protocol
      61             : */
      62         228 : static NTSTATUS smb2_create_complex(struct torture_context *tctx,
      63             :                                     struct smb2_tree *tree,
      64             :                                     const char *fname,
      65             :                                     struct smb2_handle *handle,
      66             :                                     bool dir)
      67             : {
      68         228 :         TALLOC_CTX *tmp_ctx = talloc_new(tree);
      69         228 :         char buf[7] = "abc";
      70           0 :         struct smb2_create io;
      71           0 :         union smb_setfileinfo setfile;
      72           0 :         union smb_fileinfo fileinfo;
      73         228 :         time_t t = (time(NULL) & ~1);
      74           0 :         NTSTATUS status;
      75             : 
      76         228 :         smb2_util_unlink(tree, fname);
      77         228 :         ZERO_STRUCT(io);
      78         228 :         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
      79         228 :         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
      80         228 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
      81         228 :         io.in.share_access = 
      82             :                 NTCREATEX_SHARE_ACCESS_DELETE|
      83             :                 NTCREATEX_SHARE_ACCESS_READ|
      84             :                 NTCREATEX_SHARE_ACCESS_WRITE;
      85         228 :         io.in.create_options = 0;
      86         228 :         io.in.fname = fname;
      87         228 :         if (dir) {
      88           1 :                 io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
      89           1 :                 io.in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
      90           1 :                 io.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
      91           1 :                 io.in.create_disposition = NTCREATEX_DISP_CREATE;
      92             :         }
      93             : 
      94             :         /* it seems vista is now fussier about alignment? */
      95         228 :         if (strchr(fname, ':') == NULL) {
      96             :                 /* setup some EAs */
      97         226 :                 io.in.eas.num_eas = 2;
      98         226 :                 io.in.eas.eas = talloc_array(tmp_ctx, struct ea_struct, 2);
      99         226 :                 io.in.eas.eas[0].flags = 0;
     100         226 :                 io.in.eas.eas[0].name.s = "EAONE";
     101         226 :                 io.in.eas.eas[0].value = data_blob_talloc(tmp_ctx, "VALUE1", 6);
     102         226 :                 io.in.eas.eas[1].flags = 0;
     103         226 :                 io.in.eas.eas[1].name.s = "SECONDEA";
     104         226 :                 io.in.eas.eas[1].value = data_blob_talloc(tmp_ctx, "ValueTwo", 8);
     105             :         }
     106             : 
     107         228 :         status = smb2_create(tree, tmp_ctx, &io);
     108         228 :         if (NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)) {
     109           0 :                 torture_comment(
     110             :                         tctx, "EAs not supported, creating: %s\n", fname);
     111           0 :                 io.in.eas.num_eas = 0;
     112           0 :                 status = smb2_create(tree, tmp_ctx, &io);
     113             :         }
     114             : 
     115         228 :         talloc_free(tmp_ctx);
     116         228 :         NT_STATUS_NOT_OK_RETURN(status);
     117             : 
     118         227 :         *handle = io.out.file.handle;
     119             : 
     120         227 :         if (!dir) {
     121         226 :                 status = smb2_util_write(tree, *handle, buf, 0, sizeof(buf));
     122         226 :                 NT_STATUS_NOT_OK_RETURN(status);
     123             :         }
     124             : 
     125             :         /* make sure all the timestamps aren't the same, and are also 
     126             :            in different DST zones*/
     127         227 :         setfile.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
     128         227 :         setfile.generic.in.file.handle = *handle;
     129             : 
     130         227 :         unix_to_nt_time(&setfile.basic_info.in.create_time, t + 9*30*24*60*60);
     131         227 :         unix_to_nt_time(&setfile.basic_info.in.access_time, t + 6*30*24*60*60);
     132         227 :         unix_to_nt_time(&setfile.basic_info.in.write_time,  t + 3*30*24*60*60);
     133         227 :         unix_to_nt_time(&setfile.basic_info.in.change_time, t + 1*30*24*60*60);
     134         227 :         setfile.basic_info.in.attrib      = FILE_ATTRIBUTE_NORMAL;
     135             : 
     136         227 :         status = smb2_setinfo_file(tree, &setfile);
     137         227 :         if (!NT_STATUS_IS_OK(status)) {
     138           0 :                 torture_comment(tctx, "Failed to setup file times - %s\n", nt_errstr(status));
     139           0 :                 return status;
     140             :         }
     141             : 
     142             :         /* make sure all the timestamps aren't the same */
     143         227 :         fileinfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     144         227 :         fileinfo.generic.in.file.handle = *handle;
     145             : 
     146         227 :         status = smb2_getinfo_file(tree, tree, &fileinfo);
     147         227 :         if (!NT_STATUS_IS_OK(status)) {
     148           0 :                 torture_comment(tctx, "Failed to query file times - %s\n", nt_errstr(status));
     149           0 :                 return status;
     150             :                 
     151             :         }
     152             : 
     153             : #define CHECK_TIME(field) do {\
     154             :         if (setfile.basic_info.in.field != fileinfo.all_info2.out.field) { \
     155             :                 torture_comment(tctx, "(%s) " #field " not setup correctly: %s(%llu) => %s(%llu)\n", \
     156             :                         __location__, \
     157             :                         nt_time_string(tree, setfile.basic_info.in.field), \
     158             :                         (unsigned long long)setfile.basic_info.in.field, \
     159             :                         nt_time_string(tree, fileinfo.basic_info.out.field), \
     160             :                         (unsigned long long)fileinfo.basic_info.out.field); \
     161             :                 status = NT_STATUS_INVALID_PARAMETER; \
     162             :         } \
     163             : } while (0)
     164             : 
     165         227 :         CHECK_TIME(create_time);
     166         227 :         CHECK_TIME(access_time);
     167         227 :         CHECK_TIME(write_time);
     168         227 :         CHECK_TIME(change_time);
     169             : 
     170         227 :         return status;
     171             : }
     172             : 
     173             : /*
     174             :   create a complex file using the SMB2 protocol
     175             : */
     176         227 : NTSTATUS smb2_create_complex_file(struct torture_context *tctx,
     177             :                                   struct smb2_tree *tree, const char *fname,
     178             :                                   struct smb2_handle *handle)
     179             : {
     180         227 :         return smb2_create_complex(tctx, tree, fname, handle, false);
     181             : }
     182             : 
     183             : /*
     184             :   create a complex dir using the SMB2 protocol
     185             : */
     186           1 : NTSTATUS smb2_create_complex_dir(struct torture_context *tctx,
     187             :                                  struct smb2_tree *tree, const char *fname,
     188             :                                  struct smb2_handle *handle)
     189             : {
     190           1 :         return smb2_create_complex(tctx, tree, fname, handle, true);
     191             : }
     192             : 
     193             : /*
     194             :   show lots of information about a file
     195             : */
     196          15 : void torture_smb2_all_info(struct torture_context *tctx,
     197             :                            struct smb2_tree *tree, struct smb2_handle handle)
     198             : {
     199           0 :         NTSTATUS status;
     200          15 :         TALLOC_CTX *tmp_ctx = talloc_new(tree);
     201           0 :         union smb_fileinfo io;
     202             : 
     203          15 :         io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     204          15 :         io.generic.in.file.handle = handle;
     205             : 
     206          15 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     207          15 :         if (!NT_STATUS_IS_OK(status)) {
     208           0 :                 DEBUG(0,("getinfo failed - %s\n", nt_errstr(status)));
     209           0 :                 talloc_free(tmp_ctx);
     210           0 :                 return;
     211             :         }
     212             : 
     213          15 :         torture_comment(tctx, "all_info for '%s'\n", io.all_info2.out.fname.s);
     214          15 :         torture_comment(tctx, "\tcreate_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.create_time));
     215          15 :         torture_comment(tctx, "\taccess_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.access_time));
     216          15 :         torture_comment(tctx, "\twrite_time:     %s\n", nt_time_string(tmp_ctx, io.all_info2.out.write_time));
     217          15 :         torture_comment(tctx, "\tchange_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.change_time));
     218          15 :         torture_comment(tctx, "\tattrib:         0x%x\n", io.all_info2.out.attrib);
     219          15 :         torture_comment(tctx, "\tunknown1:       0x%x\n", io.all_info2.out.unknown1);
     220          15 :         torture_comment(tctx, "\talloc_size:     %llu\n", (long long)io.all_info2.out.alloc_size);
     221          15 :         torture_comment(tctx, "\tsize:           %llu\n", (long long)io.all_info2.out.size);
     222          15 :         torture_comment(tctx, "\tnlink:          %u\n", io.all_info2.out.nlink);
     223          15 :         torture_comment(tctx, "\tdelete_pending: %u\n", io.all_info2.out.delete_pending);
     224          15 :         torture_comment(tctx, "\tdirectory:      %u\n", io.all_info2.out.directory);
     225          15 :         torture_comment(tctx, "\tfile_id:        %llu\n", (long long)io.all_info2.out.file_id);
     226          15 :         torture_comment(tctx, "\tea_size:        %u\n", io.all_info2.out.ea_size);
     227          15 :         torture_comment(tctx, "\taccess_mask:    0x%08x\n", io.all_info2.out.access_mask);
     228          15 :         torture_comment(tctx, "\tposition:       0x%llx\n", (long long)io.all_info2.out.position);
     229          15 :         torture_comment(tctx, "\tmode:           0x%llx\n", (long long)io.all_info2.out.mode);
     230             : 
     231             :         /* short name, if any */
     232          15 :         io.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
     233          15 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     234          15 :         if (NT_STATUS_IS_OK(status)) {
     235          15 :                 torture_comment(tctx, "\tshort name:     '%s'\n", io.alt_name_info.out.fname.s);
     236             :         }
     237             : 
     238             :         /* the EAs, if any */
     239          15 :         io.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
     240          15 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     241          15 :         if (NT_STATUS_IS_OK(status)) {
     242             :                 int i;
     243           3 :                 for (i=0;i<io.all_eas.out.num_eas;i++) {
     244           2 :                         torture_comment(tctx, "\tEA[%d] flags=%d len=%d '%s'\n", i,
     245           2 :                                  io.all_eas.out.eas[i].flags,
     246           2 :                                  (int)io.all_eas.out.eas[i].value.length,
     247           2 :                                  io.all_eas.out.eas[i].name.s);
     248             :                 }
     249             :         }
     250             : 
     251             :         /* streams, if available */
     252          15 :         io.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
     253          15 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     254          15 :         if (NT_STATUS_IS_OK(status)) {
     255             :                 int i;
     256          30 :                 for (i=0;i<io.stream_info.out.num_streams;i++) {
     257          15 :                         torture_comment(tctx, "\tstream %d:\n", i);
     258          15 :                         torture_comment(tctx, "\t\tsize       %ld\n",
     259          15 :                                  (long)io.stream_info.out.streams[i].size);
     260          15 :                         torture_comment(tctx, "\t\talloc size %ld\n",
     261          15 :                                  (long)io.stream_info.out.streams[i].alloc_size);
     262          15 :                         torture_comment(tctx, "\t\tname       %s\n", io.stream_info.out.streams[i].stream_name.s);
     263             :                 }
     264             :         }       
     265             : 
     266          15 :         if (DEBUGLVL(1)) {
     267             :                 /* the security descriptor */
     268          15 :                 io.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     269          15 :                 io.query_secdesc.in.secinfo_flags = 
     270             :                         SECINFO_OWNER|SECINFO_GROUP|
     271             :                         SECINFO_DACL;
     272          15 :                 status = smb2_getinfo_file(tree, tmp_ctx, &io);
     273          15 :                 if (NT_STATUS_IS_OK(status)) {
     274          15 :                         NDR_PRINT_DEBUG(security_descriptor, io.query_secdesc.out.sd);
     275             :                 }
     276             :         }
     277             : 
     278          15 :         talloc_free(tmp_ctx);   
     279             : }
     280             : 
     281             : /*
     282             :   get granted access of a file handle
     283             : */
     284          10 : NTSTATUS torture_smb2_get_allinfo_access(struct smb2_tree *tree,
     285             :                                          struct smb2_handle handle,
     286             :                                          uint32_t *granted_access)
     287             : {
     288           0 :         NTSTATUS status;
     289          10 :         TALLOC_CTX *tmp_ctx = talloc_new(tree);
     290           0 :         union smb_fileinfo io;
     291             : 
     292          10 :         io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     293          10 :         io.generic.in.file.handle = handle;
     294             : 
     295          10 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     296          10 :         if (!NT_STATUS_IS_OK(status)) {
     297           0 :                 DEBUG(0, ("getinfo failed - %s\n", nt_errstr(status)));
     298           0 :                 goto out;
     299             :         }
     300             : 
     301          10 :         *granted_access = io.all_info2.out.access_mask;
     302             : 
     303          10 : out:
     304          10 :         talloc_free(tmp_ctx);
     305          10 :         return status;
     306             : }
     307             : 
     308             : /**
     309             :  * open a smb2 tree connect
     310             :  */
     311          48 : bool torture_smb2_tree_connect(struct torture_context *tctx,
     312             :                                struct smb2_session *session,
     313             :                                TALLOC_CTX *mem_ctx,
     314             :                                struct smb2_tree **_tree)
     315             : {
     316           0 :         NTSTATUS status;
     317          48 :         const char *host = torture_setting_string(tctx, "host", NULL);
     318          48 :         const char *share = torture_setting_string(tctx, "share", NULL);
     319           0 :         const char *unc;
     320           0 :         struct smb2_tree *tree;
     321           0 :         struct tevent_req *subreq;
     322           0 :         uint32_t timeout_msec;
     323             : 
     324          48 :         unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
     325          48 :         torture_assert(tctx, unc != NULL, "talloc_asprintf");
     326             : 
     327          48 :         tree = smb2_tree_init(session, mem_ctx, false);
     328          48 :         torture_assert(tctx, tree != NULL, "smb2_tree_init");
     329             : 
     330          48 :         timeout_msec = session->transport->options.request_timeout * 1000;
     331             : 
     332          48 :         subreq = smb2cli_tcon_send(tree, tctx->ev,
     333          48 :                                    session->transport->conn,
     334             :                                    timeout_msec,
     335             :                                    session->smbXcli,
     336             :                                    tree->smbXcli,
     337             :                                    0, /* flags */
     338             :                                    unc);
     339          48 :         torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send");
     340             : 
     341          48 :         torture_assert(tctx,
     342             :                        tevent_req_poll_ntstatus(subreq, tctx->ev, &status),
     343             :                        "tevent_req_poll_ntstatus");
     344             : 
     345          48 :         status = smb2cli_tcon_recv(subreq);
     346          48 :         TALLOC_FREE(subreq);
     347          48 :         torture_assert_ntstatus_ok(tctx, status, "smb2cli_tcon_recv");
     348             : 
     349          48 :         *_tree = tree;
     350             : 
     351          48 :         return true;
     352             : }
     353             : 
     354             : /**
     355             :  * do a smb2 session setup (without a tree connect)
     356             :  */
     357          18 : bool torture_smb2_session_setup(struct torture_context *tctx,
     358             :                                 struct smb2_transport *transport,
     359             :                                 uint64_t previous_session_id,
     360             :                                 TALLOC_CTX *mem_ctx,
     361             :                                 struct smb2_session **_session)
     362             : {
     363           2 :         NTSTATUS status;
     364           2 :         struct smb2_session *session;
     365             : 
     366          18 :         session = smb2_session_init(transport,
     367             :                                     lpcfg_gensec_settings(tctx, tctx->lp_ctx),
     368             :                                     mem_ctx);
     369             : 
     370          18 :         if (session == NULL) {
     371           0 :                 return false;
     372             :         }
     373             : 
     374          18 :         status = smb2_session_setup_spnego(session,
     375             :                                            samba_cmdline_get_creds(),
     376             :                                            previous_session_id);
     377          18 :         if (!NT_STATUS_IS_OK(status)) {
     378           0 :                 torture_comment(tctx, "session setup failed: %s\n", nt_errstr(status));
     379           0 :                 talloc_free(session);
     380           0 :                 return false;
     381             :         }
     382             : 
     383          18 :         *_session = session;
     384             : 
     385          18 :         return true;
     386             : }
     387             : 
     388             : /*
     389             :   open a smb2 connection
     390             : */
     391        4169 : bool torture_smb2_connection_ext(struct torture_context *tctx,
     392             :                                  uint64_t previous_session_id,
     393             :                                  const struct smbcli_options *options,
     394             :                                  struct smb2_tree **tree)
     395             : {
     396         125 :         NTSTATUS status;
     397        4169 :         const char *host = torture_setting_string(tctx, "host", NULL);
     398        4169 :         const char *share = torture_setting_string(tctx, "share", NULL);
     399        4169 :         const char *p = torture_setting_string(tctx, "unclist", NULL);
     400        4169 :         TALLOC_CTX *mem_ctx = NULL;
     401         125 :         bool ok;
     402             : 
     403        4169 :         if (p != NULL) {
     404           0 :                 char *host2 = NULL;
     405           0 :                 char *share2 = NULL;
     406             : 
     407           0 :                 mem_ctx = talloc_new(tctx);
     408           0 :                 if (mem_ctx == NULL) {
     409           0 :                         return false;
     410             :                 }
     411             : 
     412           0 :                 ok = torture_get_conn_index(tctx->conn_index++, mem_ctx, tctx,
     413             :                                             &host2, &share2);
     414           0 :                 if (!ok) {
     415           0 :                         TALLOC_FREE(mem_ctx);
     416           0 :                         return false;
     417             :                 }
     418             : 
     419           0 :                 host = host2;
     420           0 :                 share = share2;
     421             :         }
     422             : 
     423        4169 :         status = smb2_connect_ext(tctx,
     424             :                                   host,
     425             :                                   lpcfg_smb_ports(tctx->lp_ctx),
     426             :                                   share,
     427             :                                   lpcfg_resolve_context(tctx->lp_ctx),
     428             :                                   samba_cmdline_get_creds(),
     429             :                                   NULL, /* existing_conn */
     430             :                                   previous_session_id,
     431             :                                   tree,
     432             :                                   tctx->ev,
     433             :                                   options,
     434             :                                   lpcfg_socket_options(tctx->lp_ctx),
     435             :                                   lpcfg_gensec_settings(tctx, tctx->lp_ctx)
     436             :                                   );
     437        4169 :         if (!NT_STATUS_IS_OK(status)) {
     438           0 :                 torture_comment(tctx, "Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
     439             :                        host, share, nt_errstr(status));
     440           0 :                 TALLOC_FREE(mem_ctx);
     441           0 :                 return false;
     442             :         }
     443             : 
     444        4169 :         TALLOC_FREE(mem_ctx);
     445        4044 :         return true;
     446             : }
     447             : 
     448        3999 : bool torture_smb2_connection(struct torture_context *tctx, struct smb2_tree **tree)
     449             : {
     450         121 :         bool ret;
     451         121 :         struct smbcli_options options;
     452             : 
     453        3999 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
     454             : 
     455        3999 :         ret = torture_smb2_connection_ext(tctx, 0, &options, tree);
     456             : 
     457        3999 :         return ret;
     458             : }
     459             : 
     460             : /**
     461             :  * SMB2 connect with share from soption
     462             :  **/
     463          26 : bool torture_smb2_con_share(struct torture_context *tctx,
     464             :                             const char *share,
     465             :                             struct smb2_tree **tree)
     466             : {
     467           0 :         struct smbcli_options options;
     468           0 :         NTSTATUS status;
     469          26 :         const char *host = torture_setting_string(tctx, "host", NULL);
     470             : 
     471          26 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
     472             : 
     473          26 :         status = smb2_connect(tctx,
     474             :                               host,
     475             :                               lpcfg_smb_ports(tctx->lp_ctx),
     476             :                               share,
     477             :                               lpcfg_resolve_context(tctx->lp_ctx),
     478             :                               samba_cmdline_get_creds(),
     479             :                               tree,
     480             :                               tctx->ev,
     481             :                               &options,
     482             :                               lpcfg_socket_options(tctx->lp_ctx),
     483             :                               lpcfg_gensec_settings(tctx, tctx->lp_ctx)
     484             :                               );
     485          26 :         if (!NT_STATUS_IS_OK(status)) {
     486           0 :                 torture_comment(tctx, "Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
     487             :                        host, share, nt_errstr(status));
     488           0 :                 return false;
     489             :         }
     490          26 :         return true;
     491             : }
     492             : 
     493             : /**
     494             :  * SMB2 connect with share from soption
     495             :  **/
     496          18 : bool torture_smb2_con_sopt(struct torture_context *tctx,
     497             :                            const char *soption,
     498             :                            struct smb2_tree **tree)
     499             : {
     500          18 :         const char *share = torture_setting_string(tctx, soption, NULL);
     501             : 
     502          18 :         if (share == NULL) {
     503           0 :                 torture_comment(tctx, "No share for option %s\n", soption);
     504           0 :                 return false;
     505             :         }
     506             : 
     507          18 :         return torture_smb2_con_share(tctx, share, tree);
     508             : }
     509             : 
     510             : /*
     511             :   create and return a handle to a test file
     512             :   with a specific access mask
     513             : */
     514         959 : NTSTATUS torture_smb2_testfile_access(struct smb2_tree *tree, const char *fname,
     515             :                                       struct smb2_handle *handle,
     516             :                                       uint32_t desired_access)
     517             : {
     518           0 :         struct smb2_create io;
     519           0 :         NTSTATUS status;
     520             : 
     521         959 :         ZERO_STRUCT(io);
     522         959 :         io.in.oplock_level = 0;
     523         959 :         io.in.desired_access = desired_access;
     524         959 :         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
     525         959 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     526         959 :         io.in.share_access = 
     527             :                 NTCREATEX_SHARE_ACCESS_DELETE|
     528             :                 NTCREATEX_SHARE_ACCESS_READ|
     529             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     530         959 :         io.in.create_options = 0;
     531         959 :         io.in.fname = fname;
     532             : 
     533         959 :         status = smb2_create(tree, tree, &io);
     534         959 :         NT_STATUS_NOT_OK_RETURN(status);
     535             : 
     536         958 :         *handle = io.out.file.handle;
     537             : 
     538         958 :         return NT_STATUS_OK;
     539             : }
     540             : 
     541             : /*
     542             :   create and return a handle to a test file
     543             : */
     544         392 : NTSTATUS torture_smb2_testfile(struct smb2_tree *tree, const char *fname,
     545             :                                struct smb2_handle *handle)
     546             : {
     547         392 :         return torture_smb2_testfile_access(tree, fname, handle,
     548             :                                             SEC_RIGHTS_FILE_ALL);
     549             : }
     550             : 
     551             : /*
     552             :   create and return a handle to a test file
     553             :   with a specific access mask
     554             : */
     555         690 : NTSTATUS torture_smb2_open(struct smb2_tree *tree,
     556             :                            const char *fname,
     557             :                            uint32_t desired_access,
     558             :                            struct smb2_handle *handle)
     559             : {
     560           0 :         struct smb2_create io;
     561           0 :         NTSTATUS status;
     562             : 
     563         690 :         io = (struct smb2_create) {
     564             :                 .in.fname = fname,
     565             :                 .in.desired_access = desired_access,
     566             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
     567             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
     568             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
     569             :         };
     570             : 
     571         690 :         status = smb2_create(tree, tree, &io);
     572         690 :         if (!NT_STATUS_IS_OK(status)) {
     573         432 :                 return status;
     574             :         }
     575             : 
     576         258 :         *handle = io.out.file.handle;
     577             : 
     578         258 :         return NT_STATUS_OK;
     579             : }
     580             : 
     581             : /*
     582             :   create and return a handle to a test directory
     583             :   with specific desired access
     584             : */
     585         954 : NTSTATUS torture_smb2_testdir_access(struct smb2_tree *tree, const char *fname,
     586             :                                      struct smb2_handle *handle,
     587             :                                      uint32_t desired_access)
     588             : {
     589           2 :         struct smb2_create io;
     590           2 :         NTSTATUS status;
     591             : 
     592         954 :         ZERO_STRUCT(io);
     593         954 :         io.in.oplock_level = 0;
     594         954 :         io.in.desired_access = desired_access;
     595         954 :         io.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
     596         954 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     597         954 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE;
     598         954 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     599         954 :         io.in.fname = fname;
     600             : 
     601         954 :         status = smb2_create(tree, tree, &io);
     602         954 :         NT_STATUS_NOT_OK_RETURN(status);
     603             : 
     604         954 :         *handle = io.out.file.handle;
     605             : 
     606         954 :         return NT_STATUS_OK;
     607             : }
     608             : 
     609             : /*
     610             :   create and return a handle to a test directory
     611             : */
     612         949 : NTSTATUS torture_smb2_testdir(struct smb2_tree *tree, const char *fname,
     613             :                               struct smb2_handle *handle)
     614             : {
     615         949 :         return torture_smb2_testdir_access(tree, fname, handle,
     616             :                                            SEC_RIGHTS_DIR_ALL);
     617             : }
     618             : 
     619             : /*
     620             :   create a simple file using the SMB2 protocol
     621             : */
     622          13 : NTSTATUS smb2_create_simple_file(struct torture_context *tctx,
     623             :                                  struct smb2_tree *tree, const char *fname,
     624             :                                  struct smb2_handle *handle)
     625             : {
     626          13 :         char buf[7] = "abc";
     627           0 :         NTSTATUS status;
     628             : 
     629          13 :         smb2_util_unlink(tree, fname);
     630          13 :         status = torture_smb2_testfile_access(tree,
     631             :                                               fname, handle,
     632             :                                               SEC_FLAG_MAXIMUM_ALLOWED);
     633          13 :         NT_STATUS_NOT_OK_RETURN(status);
     634             : 
     635          13 :         status = smb2_util_write(tree, *handle, buf, 0, sizeof(buf));
     636          13 :         NT_STATUS_NOT_OK_RETURN(status);
     637             : 
     638          13 :         return NT_STATUS_OK;
     639             : }
     640             : 
     641             : /*
     642             :   create a simple file using SMB2.
     643             : */
     644          13 : NTSTATUS torture_setup_simple_file(struct torture_context *tctx,
     645             :                                    struct smb2_tree *tree, const char *fname)
     646             : {
     647           0 :         struct smb2_handle handle;
     648          13 :         NTSTATUS status = smb2_create_simple_file(tctx, tree, fname, &handle);
     649          13 :         NT_STATUS_NOT_OK_RETURN(status);
     650          13 :         return smb2_util_close(tree, handle);
     651             : }
     652             : 
     653             : /*
     654             :   create a complex file using SMB2, to make it easier to
     655             :   find fields in SMB2 getinfo levels
     656             : */
     657          12 : NTSTATUS torture_setup_complex_file(struct torture_context *tctx,
     658             :                                     struct smb2_tree *tree, const char *fname)
     659             : {
     660           0 :         struct smb2_handle handle;
     661          12 :         NTSTATUS status = smb2_create_complex_file(tctx, tree, fname, &handle);
     662          12 :         NT_STATUS_NOT_OK_RETURN(status);
     663           3 :         return smb2_util_close(tree, handle);
     664             : }
     665             : 
     666             : 
     667             : /*
     668             :   create a complex dir using SMB2, to make it easier to
     669             :   find fields in SMB2 getinfo levels
     670             : */
     671           1 : NTSTATUS torture_setup_complex_dir(struct torture_context *tctx,
     672             :                                    struct smb2_tree *tree, const char *fname)
     673             : {
     674           0 :         struct smb2_handle handle;
     675           1 :         NTSTATUS status = smb2_create_complex_dir(tctx, tree, fname, &handle);
     676           1 :         NT_STATUS_NOT_OK_RETURN(status);
     677           1 :         return smb2_util_close(tree, handle);
     678             : }
     679             : 
     680             : 
     681             : /*
     682             :   return a handle to the root of the share
     683             : */
     684         125 : NTSTATUS smb2_util_roothandle(struct smb2_tree *tree, struct smb2_handle *handle)
     685             : {
     686          18 :         struct smb2_create io;
     687          18 :         NTSTATUS status;
     688             : 
     689         125 :         ZERO_STRUCT(io);
     690         125 :         io.in.oplock_level = 0;
     691         125 :         io.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE | SEC_DIR_LIST;
     692         125 :         io.in.file_attributes   = 0;
     693         125 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
     694         125 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE;
     695         125 :         io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT;
     696         125 :         io.in.fname = "";
     697             : 
     698         125 :         status = smb2_create(tree, tree, &io);
     699         125 :         NT_STATUS_NOT_OK_RETURN(status);
     700             : 
     701         115 :         *handle = io.out.file.handle;
     702             : 
     703         115 :         return NT_STATUS_OK;
     704             : }
     705             : 
     706             : /* Comparable to torture_setup_dir, but for SMB2. */
     707         101 : bool smb2_util_setup_dir(struct torture_context *tctx, struct smb2_tree *tree,
     708             :     const char *dname)
     709             : {
     710           2 :         NTSTATUS status;
     711             : 
     712             :         /* XXX: smb_raw_exit equivalent?
     713             :         smb_raw_exit(cli->session); */
     714         101 :         if (smb2_deltree(tree, dname) == -1) {
     715           0 :                 torture_result(tctx, TORTURE_ERROR, "Unable to deltree when setting up %s.\n", dname);
     716           0 :                 return false;
     717             :         }
     718             : 
     719         101 :         status = smb2_util_mkdir(tree, dname);
     720         101 :         if (NT_STATUS_IS_ERR(status)) {
     721           0 :                 torture_result(tctx, TORTURE_ERROR, "Unable to mkdir when setting up %s - %s\n", dname,
     722             :                     nt_errstr(status));
     723           0 :                 return false;
     724             :         }
     725             : 
     726          99 :         return true;
     727             : }
     728             : 
     729             : #define CHECK_STATUS(status, correct) do { \
     730             :         if (!NT_STATUS_EQUAL(status, correct)) { \
     731             :                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
     732             :                        __location__, nt_errstr(status), nt_errstr(correct)); \
     733             :                 ret = false; \
     734             :                 goto done; \
     735             :         }} while (0)
     736             : 
     737             : /*
     738             :  * Helper function to verify a security descriptor, by querying
     739             :  * and comparing against the passed in sd.
     740             :  */
     741          36 : bool smb2_util_verify_sd(TALLOC_CTX *tctx, struct smb2_tree *tree,
     742             :     struct smb2_handle handle, struct security_descriptor *sd)
     743             : {
     744           0 :         NTSTATUS status;
     745          36 :         bool ret = true;
     746          36 :         union smb_fileinfo q = {};
     747             : 
     748          36 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     749          36 :         q.query_secdesc.in.file.handle = handle;
     750          36 :         q.query_secdesc.in.secinfo_flags =
     751             :             SECINFO_OWNER |
     752             :             SECINFO_GROUP |
     753             :             SECINFO_DACL;
     754          36 :         status = smb2_getinfo_file(tree, tctx, &q);
     755          36 :         CHECK_STATUS(status, NT_STATUS_OK);
     756             : 
     757          36 :         if (!security_acl_equal(
     758          36 :             q.query_secdesc.out.sd->dacl, sd->dacl)) {
     759           0 :                 torture_warning(tctx, "%s: security descriptors don't match!\n",
     760             :                     __location__);
     761           0 :                 torture_warning(tctx, "got:\n");
     762           0 :                 NDR_PRINT_DEBUG(security_descriptor,
     763             :                     q.query_secdesc.out.sd);
     764           0 :                 torture_warning(tctx, "expected:\n");
     765           0 :                 NDR_PRINT_DEBUG(security_descriptor, sd);
     766           0 :                 ret = false;
     767             :         }
     768             : 
     769          36 :  done:
     770          36 :         return ret;
     771             : }
     772             : 
     773             : /*
     774             :  * Helper function to verify attributes, by querying
     775             :  * and comparing against the passed in attrib.
     776             :  */
     777          34 : bool smb2_util_verify_attrib(TALLOC_CTX *tctx, struct smb2_tree *tree,
     778             :     struct smb2_handle handle, uint32_t attrib)
     779             : {
     780           0 :         NTSTATUS status;
     781          34 :         bool ret = true;
     782          34 :         union smb_fileinfo q = {};
     783             : 
     784          34 :         q.standard.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     785          34 :         q.standard.in.file.handle = handle;
     786          34 :         status = smb2_getinfo_file(tree, tctx, &q);
     787          34 :         CHECK_STATUS(status, NT_STATUS_OK);
     788             : 
     789          34 :         q.all_info2.out.attrib &= ~(FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_NONINDEXED);
     790             : 
     791          34 :         if (q.all_info2.out.attrib != attrib) {
     792           1 :                 torture_warning(tctx, "%s: attributes don't match! "
     793             :                     "got %x, expected %x\n", __location__,
     794           1 :                     (uint32_t)q.standard.out.attrib,
     795             :                     (uint32_t)attrib);
     796           1 :                 ret = false;
     797             :         }
     798             : 
     799          33 :  done:
     800          34 :         return ret;
     801             : }
     802             : 
     803             : 
     804        2918 : uint32_t smb2_util_lease_state(const char *ls)
     805             : {
     806        2918 :         uint32_t val = 0;
     807           0 :         int i;
     808             : 
     809        8550 :         for (i = 0; i < strlen(ls); i++) {
     810        5632 :                 switch (ls[i]) {
     811        2640 :                 case 'R':
     812        2640 :                         val |= SMB2_LEASE_READ;
     813        2640 :                         break;
     814        1756 :                 case 'H':
     815        1756 :                         val |= SMB2_LEASE_HANDLE;
     816        1756 :                         break;
     817        1236 :                 case 'W':
     818        1236 :                         val |= SMB2_LEASE_WRITE;
     819        1236 :                         break;
     820             :                 }
     821             :         }
     822             : 
     823        2918 :         return val;
     824             : }
     825             : 
     826         258 : char *smb2_util_lease_state_string(TALLOC_CTX *mem_ctx, uint32_t ls)
     827             : {
     828         774 :         return talloc_asprintf(mem_ctx, "0x%0x (%s%s%s)",
     829             :                                (unsigned)ls,
     830         258 :                                ls & SMB2_LEASE_READ ? "R": "",
     831         258 :                                ls & SMB2_LEASE_HANDLE ? "H": "",
     832         258 :                                ls & SMB2_LEASE_WRITE ? "W": "");
     833             : }
     834             : 
     835        4023 : uint32_t smb2_util_share_access(const char *sharemode)
     836             : {
     837        4023 :         uint32_t val = NTCREATEX_SHARE_ACCESS_NONE; /* 0 */
     838         130 :         int i;
     839             : 
     840       10816 :         for (i = 0; i < strlen(sharemode); i++) {
     841        6793 :                 switch(sharemode[i]) {
     842        2317 :                 case 'R':
     843        2317 :                         val |= NTCREATEX_SHARE_ACCESS_READ;
     844        2317 :                         break;
     845        2290 :                 case 'W':
     846        2290 :                         val |= NTCREATEX_SHARE_ACCESS_WRITE;
     847        2290 :                         break;
     848        2186 :                 case 'D':
     849        2186 :                         val |= NTCREATEX_SHARE_ACCESS_DELETE;
     850        2186 :                         break;
     851             :                 }
     852             :         }
     853             : 
     854        4023 :         return val;
     855             : }
     856             : 
     857        3056 : uint8_t smb2_util_oplock_level(const char *op)
     858             : {
     859        3056 :         uint8_t val = SMB2_OPLOCK_LEVEL_NONE;
     860         257 :         int i;
     861             : 
     862        3056 :         for (i = 0; i < strlen(op); i++) {
     863        2742 :                 switch (op[i]) {
     864         436 :                 case 's':
     865         436 :                         return SMB2_OPLOCK_LEVEL_II;
     866         240 :                 case 'x':
     867         240 :                         return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
     868        2066 :                 case 'b':
     869        2066 :                         return SMB2_OPLOCK_LEVEL_BATCH;
     870           0 :                 default:
     871           0 :                         continue;
     872             :                 }
     873             :         }
     874             : 
     875         300 :         return val;
     876             : }
     877             : 
     878             : /**
     879             :  * Helper functions to fill a smb2_create struct for several
     880             :  * open scenarios.
     881             :  */
     882        2580 : void smb2_generic_create_share(struct smb2_create *io, struct smb2_lease *ls,
     883             :                                bool dir, const char *name, uint32_t disposition,
     884             :                                uint32_t share_access,
     885             :                                uint8_t oplock, uint64_t leasekey,
     886             :                                uint32_t leasestate)
     887             : {
     888        2580 :         ZERO_STRUCT(*io);
     889        2580 :         io->in.security_flags                = 0x00;
     890        2580 :         io->in.oplock_level          = oplock;
     891        2580 :         io->in.impersonation_level   = NTCREATEX_IMPERSONATION_IMPERSONATION;
     892        2580 :         io->in.create_flags          = 0x00000000;
     893        2580 :         io->in.reserved                      = 0x00000000;
     894        2580 :         io->in.desired_access                = SEC_RIGHTS_FILE_ALL;
     895        2580 :         io->in.file_attributes               = FILE_ATTRIBUTE_NORMAL;
     896        2580 :         io->in.share_access          = share_access;
     897        2580 :         io->in.create_disposition    = disposition;
     898        2580 :         io->in.create_options                = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
     899             :                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
     900             :                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
     901             :                                           0x00200000;
     902        2580 :         io->in.fname                 = name;
     903             : 
     904        2580 :         if (dir) {
     905           4 :                 io->in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     906           4 :                 io->in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     907           4 :                 io->in.create_disposition = NTCREATEX_DISP_CREATE;
     908             :         }
     909             : 
     910        2580 :         if (ls) {
     911         892 :                 ZERO_STRUCTPN(ls);
     912         892 :                 ls->lease_key.data[0] = leasekey;
     913         892 :                 ls->lease_key.data[1] = ~leasekey;
     914         892 :                 ls->lease_state = leasestate;
     915         892 :                 io->in.lease_request = ls;
     916             :         }
     917        2580 : }
     918             : 
     919           4 : void smb2_generic_create(struct smb2_create *io, struct smb2_lease *ls,
     920             :                          bool dir, const char *name, uint32_t disposition,
     921             :                          uint8_t oplock, uint64_t leasekey,
     922             :                          uint32_t leasestate)
     923             : {
     924           4 :         smb2_generic_create_share(io, ls, dir, name, disposition,
     925             :                                   smb2_util_share_access("RWD"),
     926             :                                   oplock,
     927             :                                   leasekey, leasestate);
     928           4 : }
     929             : 
     930         894 : void smb2_lease_create_share(struct smb2_create *io, struct smb2_lease *ls,
     931             :                              bool dir, const char *name, uint32_t share_access,
     932             :                              uint64_t leasekey, uint32_t leasestate)
     933             : {
     934         894 :         smb2_generic_create_share(io, ls, dir, name, NTCREATEX_DISP_OPEN_IF,
     935             :                                   share_access, SMB2_OPLOCK_LEVEL_LEASE,
     936             :                                   leasekey, leasestate);
     937         894 : }
     938             : 
     939         580 : void smb2_lease_create(struct smb2_create *io, struct smb2_lease *ls,
     940             :                        bool dir, const char *name, uint64_t leasekey,
     941             :                        uint32_t leasestate)
     942             : {
     943         580 :         smb2_lease_create_share(io, ls, dir, name,
     944             :                                 smb2_util_share_access("RWD"),
     945             :                                 leasekey, leasestate);
     946         580 : }
     947             : 
     948         120 : void smb2_lease_v2_create_share(struct smb2_create *io,
     949             :                                 struct smb2_lease *ls,
     950             :                                 bool dir,
     951             :                                 const char *name,
     952             :                                 uint32_t share_access,
     953             :                                 uint64_t leasekey,
     954             :                                 const uint64_t *parentleasekey,
     955             :                                 uint32_t leasestate,
     956             :                                 uint16_t lease_epoch)
     957             : {
     958         120 :         smb2_generic_create_share(io, NULL, dir, name, NTCREATEX_DISP_OPEN_IF,
     959             :                                   share_access, SMB2_OPLOCK_LEVEL_LEASE, 0, 0);
     960             : 
     961         120 :         if (ls) {
     962         120 :                 ZERO_STRUCT(*ls);
     963         120 :                 ls->lease_key.data[0] = leasekey;
     964         120 :                 ls->lease_key.data[1] = ~leasekey;
     965         120 :                 ls->lease_state = leasestate;
     966         120 :                 if (parentleasekey != NULL) {
     967           0 :                         ls->lease_flags |= SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET;
     968           0 :                         ls->parent_lease_key.data[0] = *parentleasekey;
     969           0 :                         ls->parent_lease_key.data[1] = ~(*parentleasekey);
     970             :                 }
     971         120 :                 ls->lease_epoch = lease_epoch;
     972         120 :                 io->in.lease_request_v2 = ls;
     973             :         }
     974         120 : }
     975             : 
     976          92 : void smb2_lease_v2_create(struct smb2_create *io,
     977             :                           struct smb2_lease *ls,
     978             :                           bool dir,
     979             :                           const char *name,
     980             :                           uint64_t leasekey,
     981             :                           const uint64_t *parentleasekey,
     982             :                           uint32_t leasestate,
     983             :                           uint16_t lease_epoch)
     984             : {
     985          92 :         smb2_lease_v2_create_share(io, ls, dir, name,
     986             :                                    smb2_util_share_access("RWD"),
     987             :                                    leasekey, parentleasekey,
     988             :                                    leasestate, lease_epoch);
     989          92 : }
     990             : 
     991             : 
     992        1562 : void smb2_oplock_create_share(struct smb2_create *io, const char *name,
     993             :                               uint32_t share_access, uint8_t oplock)
     994             : {
     995        1562 :         smb2_generic_create_share(io, NULL, false, name, NTCREATEX_DISP_OPEN_IF,
     996             :                                   share_access, oplock, 0, 0);
     997        1562 : }
     998         236 : void smb2_oplock_create(struct smb2_create *io, const char *name, uint8_t oplock)
     999             : {
    1000         236 :         smb2_oplock_create_share(io, name, smb2_util_share_access("RWD"),
    1001             :                                  oplock);
    1002         236 : }
    1003             : 
    1004             : /*
    1005             :    a wrapper around smblsa_sid_check_privilege, that tries to take
    1006             :    account of the fact that the lsa privileges calls don't expand
    1007             :    group memberships, using an explicit check for administrator. There
    1008             :    must be a better way ...
    1009             :  */
    1010          15 : NTSTATUS torture_smb2_check_privilege(struct smb2_tree *tree,
    1011             :                                      const char *sid_str,
    1012             :                                      const char *privilege)
    1013             : {
    1014          15 :         struct dom_sid *sid = NULL;
    1015          15 :         TALLOC_CTX *tmp_ctx = NULL;
    1016           0 :         uint32_t rid;
    1017           0 :         NTSTATUS status;
    1018             : 
    1019          15 :         tmp_ctx = talloc_new(tree);
    1020          15 :         if (tmp_ctx == NULL) {
    1021           0 :                 return NT_STATUS_NO_MEMORY;
    1022             :         }
    1023             : 
    1024          15 :         sid = dom_sid_parse_talloc(tmp_ctx, sid_str);
    1025          15 :         if (sid == NULL) {
    1026           0 :                 talloc_free(tmp_ctx);
    1027           0 :                 return NT_STATUS_INVALID_SID;
    1028             :         }
    1029             : 
    1030          15 :         status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
    1031          15 :         if (!NT_STATUS_IS_OK(status)) {
    1032           0 :                 TALLOC_FREE(tmp_ctx);
    1033           0 :                 return status;
    1034             :         }
    1035             : 
    1036          15 :         if (rid == DOMAIN_RID_ADMINISTRATOR) {
    1037             :                 /* assume the administrator has them all */
    1038           9 :                 TALLOC_FREE(tmp_ctx);
    1039           9 :                 return NT_STATUS_OK;
    1040             :         }
    1041             : 
    1042           6 :         talloc_free(tmp_ctx);
    1043             : 
    1044           6 :         return smb2lsa_sid_check_privilege(tree, sid_str, privilege);
    1045             : }

Generated by: LCOV version 1.14