LCOV - code coverage report
Current view: top level - source4/torture/smb2 - util.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 382 436 87.6 %
Date: 2021-08-25 13:27:56 Functions: 37 37 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       37256 : 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             :         struct smb2_write w;
      50             : 
      51       37256 :         ZERO_STRUCT(w);
      52       37256 :         w.in.file.handle = handle;
      53       37256 :         w.in.offset      = offset;
      54       37256 :         w.in.data        = data_blob_const(buf, size);
      55             : 
      56       37256 :         return smb2_write(tree, &w);
      57             : }
      58             : 
      59             : /*
      60             :   create a complex file/dir using the SMB2 protocol
      61             : */
      62         223 : 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         223 :         TALLOC_CTX *tmp_ctx = talloc_new(tree);
      69         223 :         char buf[7] = "abc";
      70             :         struct smb2_create io;
      71             :         union smb_setfileinfo setfile;
      72             :         union smb_fileinfo fileinfo;
      73         223 :         time_t t = (time(NULL) & ~1);
      74             :         NTSTATUS status;
      75             : 
      76         223 :         smb2_util_unlink(tree, fname);
      77         223 :         ZERO_STRUCT(io);
      78         223 :         io.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
      79         223 :         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
      80         223 :         io.in.create_disposition = NTCREATEX_DISP_OVERWRITE_IF;
      81         223 :         io.in.share_access = 
      82             :                 NTCREATEX_SHARE_ACCESS_DELETE|
      83             :                 NTCREATEX_SHARE_ACCESS_READ|
      84             :                 NTCREATEX_SHARE_ACCESS_WRITE;
      85         223 :         io.in.create_options = 0;
      86         223 :         io.in.fname = fname;
      87         223 :         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         223 :         if (strchr(fname, ':') == NULL) {
      96             :                 /* setup some EAs */
      97         221 :                 io.in.eas.num_eas = 2;
      98         221 :                 io.in.eas.eas = talloc_array(tmp_ctx, struct ea_struct, 2);
      99         221 :                 io.in.eas.eas[0].flags = 0;
     100         221 :                 io.in.eas.eas[0].name.s = "EAONE";
     101         221 :                 io.in.eas.eas[0].value = data_blob_talloc(tmp_ctx, "VALUE1", 6);
     102         221 :                 io.in.eas.eas[1].flags = 0;
     103         221 :                 io.in.eas.eas[1].name.s = "SECONDEA";
     104         221 :                 io.in.eas.eas[1].value = data_blob_talloc(tmp_ctx, "ValueTwo", 8);
     105             :         }
     106             : 
     107         223 :         status = smb2_create(tree, tmp_ctx, &io);
     108         223 :         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         223 :         talloc_free(tmp_ctx);
     116         223 :         NT_STATUS_NOT_OK_RETURN(status);
     117             : 
     118         222 :         *handle = io.out.file.handle;
     119             : 
     120         222 :         if (!dir) {
     121         221 :                 status = smb2_util_write(tree, *handle, buf, 0, sizeof(buf));
     122         221 :                 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         222 :         setfile.generic.level = RAW_SFILEINFO_BASIC_INFORMATION;
     128         222 :         setfile.generic.in.file.handle = *handle;
     129             : 
     130         222 :         unix_to_nt_time(&setfile.basic_info.in.create_time, t + 9*30*24*60*60);
     131         222 :         unix_to_nt_time(&setfile.basic_info.in.access_time, t + 6*30*24*60*60);
     132         222 :         unix_to_nt_time(&setfile.basic_info.in.write_time,  t + 3*30*24*60*60);
     133         222 :         unix_to_nt_time(&setfile.basic_info.in.change_time, t + 1*30*24*60*60);
     134         222 :         setfile.basic_info.in.attrib      = FILE_ATTRIBUTE_NORMAL;
     135             : 
     136         222 :         status = smb2_setinfo_file(tree, &setfile);
     137         222 :         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         222 :         fileinfo.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     144         222 :         fileinfo.generic.in.file.handle = *handle;
     145             : 
     146         222 :         status = smb2_getinfo_file(tree, tree, &fileinfo);
     147         222 :         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         222 :         CHECK_TIME(create_time);
     166         222 :         CHECK_TIME(access_time);
     167         222 :         CHECK_TIME(write_time);
     168         222 :         CHECK_TIME(change_time);
     169             : 
     170         222 :         return status;
     171             : }
     172             : 
     173             : /*
     174             :   create a complex file using the SMB2 protocol
     175             : */
     176         222 : NTSTATUS smb2_create_complex_file(struct torture_context *tctx,
     177             :                                   struct smb2_tree *tree, const char *fname,
     178             :                                   struct smb2_handle *handle)
     179             : {
     180         222 :         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          11 : void torture_smb2_all_info(struct torture_context *tctx,
     197             :                            struct smb2_tree *tree, struct smb2_handle handle)
     198             : {
     199             :         NTSTATUS status;
     200          11 :         TALLOC_CTX *tmp_ctx = talloc_new(tree);
     201             :         union smb_fileinfo io;
     202             : 
     203          11 :         io.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     204          11 :         io.generic.in.file.handle = handle;
     205             : 
     206          11 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     207          11 :         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          11 :         torture_comment(tctx, "all_info for '%s'\n", io.all_info2.out.fname.s);
     214          11 :         torture_comment(tctx, "\tcreate_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.create_time));
     215          11 :         torture_comment(tctx, "\taccess_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.access_time));
     216          11 :         torture_comment(tctx, "\twrite_time:     %s\n", nt_time_string(tmp_ctx, io.all_info2.out.write_time));
     217          11 :         torture_comment(tctx, "\tchange_time:    %s\n", nt_time_string(tmp_ctx, io.all_info2.out.change_time));
     218          11 :         torture_comment(tctx, "\tattrib:         0x%x\n", io.all_info2.out.attrib);
     219          11 :         torture_comment(tctx, "\tunknown1:       0x%x\n", io.all_info2.out.unknown1);
     220          11 :         torture_comment(tctx, "\talloc_size:     %llu\n", (long long)io.all_info2.out.alloc_size);
     221          11 :         torture_comment(tctx, "\tsize:           %llu\n", (long long)io.all_info2.out.size);
     222          11 :         torture_comment(tctx, "\tnlink:          %u\n", io.all_info2.out.nlink);
     223          11 :         torture_comment(tctx, "\tdelete_pending: %u\n", io.all_info2.out.delete_pending);
     224          11 :         torture_comment(tctx, "\tdirectory:      %u\n", io.all_info2.out.directory);
     225          11 :         torture_comment(tctx, "\tfile_id:        %llu\n", (long long)io.all_info2.out.file_id);
     226          11 :         torture_comment(tctx, "\tea_size:        %u\n", io.all_info2.out.ea_size);
     227          11 :         torture_comment(tctx, "\taccess_mask:    0x%08x\n", io.all_info2.out.access_mask);
     228          11 :         torture_comment(tctx, "\tposition:       0x%llx\n", (long long)io.all_info2.out.position);
     229          11 :         torture_comment(tctx, "\tmode:           0x%llx\n", (long long)io.all_info2.out.mode);
     230             : 
     231             :         /* short name, if any */
     232          11 :         io.generic.level = RAW_FILEINFO_ALT_NAME_INFORMATION;
     233          11 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     234          11 :         if (NT_STATUS_IS_OK(status)) {
     235          11 :                 torture_comment(tctx, "\tshort name:     '%s'\n", io.alt_name_info.out.fname.s);
     236             :         }
     237             : 
     238             :         /* the EAs, if any */
     239          11 :         io.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
     240          11 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     241          11 :         if (NT_STATUS_IS_OK(status)) {
     242             :                 int i;
     243           3 :                 for (i=0;i<io.all_eas.out.num_eas;i++) {
     244           6 :                         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          11 :         io.generic.level = RAW_FILEINFO_STREAM_INFORMATION;
     253          11 :         status = smb2_getinfo_file(tree, tmp_ctx, &io);
     254          11 :         if (NT_STATUS_IS_OK(status)) {
     255             :                 int i;
     256          22 :                 for (i=0;i<io.stream_info.out.num_streams;i++) {
     257          11 :                         torture_comment(tctx, "\tstream %d:\n", i);
     258          11 :                         torture_comment(tctx, "\t\tsize       %ld\n",
     259          11 :                                  (long)io.stream_info.out.streams[i].size);
     260          11 :                         torture_comment(tctx, "\t\talloc size %ld\n",
     261          11 :                                  (long)io.stream_info.out.streams[i].alloc_size);
     262          11 :                         torture_comment(tctx, "\t\tname       %s\n", io.stream_info.out.streams[i].stream_name.s);
     263             :                 }
     264             :         }       
     265             : 
     266          11 :         if (DEBUGLVL(1)) {
     267             :                 /* the security descriptor */
     268          11 :                 io.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     269          11 :                 io.query_secdesc.in.secinfo_flags = 
     270             :                         SECINFO_OWNER|SECINFO_GROUP|
     271             :                         SECINFO_DACL;
     272          11 :                 status = smb2_getinfo_file(tree, tmp_ctx, &io);
     273          11 :                 if (NT_STATUS_IS_OK(status)) {
     274          11 :                         NDR_PRINT_DEBUG(security_descriptor, io.query_secdesc.out.sd);
     275             :                 }
     276             :         }
     277             : 
     278          11 :         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             :         NTSTATUS status;
     289          10 :         TALLOC_CTX *tmp_ctx = talloc_new(tree);
     290             :         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          42 : 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             :         NTSTATUS status;
     317          42 :         const char *host = torture_setting_string(tctx, "host", NULL);
     318          42 :         const char *share = torture_setting_string(tctx, "share", NULL);
     319             :         const char *unc;
     320             :         struct smb2_tree *tree;
     321             :         struct tevent_req *subreq;
     322             :         uint32_t timeout_msec;
     323             : 
     324          42 :         unc = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
     325          42 :         torture_assert(tctx, unc != NULL, "talloc_asprintf");
     326             : 
     327          42 :         tree = smb2_tree_init(session, mem_ctx, false);
     328          42 :         torture_assert(tctx, tree != NULL, "smb2_tree_init");
     329             : 
     330          42 :         timeout_msec = session->transport->options.request_timeout * 1000;
     331             : 
     332          84 :         subreq = smb2cli_tcon_send(tree, tctx->ev,
     333          42 :                                    session->transport->conn,
     334             :                                    timeout_msec,
     335             :                                    session->smbXcli,
     336             :                                    tree->smbXcli,
     337             :                                    0, /* flags */
     338             :                                    unc);
     339          42 :         torture_assert(tctx, subreq != NULL, "smb2cli_tcon_send");
     340             : 
     341          42 :         torture_assert(tctx,
     342             :                        tevent_req_poll_ntstatus(subreq, tctx->ev, &status),
     343             :                        "tevent_req_poll_ntstatus");
     344             : 
     345          42 :         status = smb2cli_tcon_recv(subreq);
     346          42 :         TALLOC_FREE(subreq);
     347          42 :         torture_assert_ntstatus_ok(tctx, status, "smb2cli_tcon_recv");
     348             : 
     349          42 :         *_tree = tree;
     350             : 
     351          42 :         return true;
     352             : }
     353             : 
     354             : /**
     355             :  * do a smb2 session setup (without a tree connect)
     356             :  */
     357          16 : 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             :         NTSTATUS status;
     364             :         struct smb2_session *session;
     365             : 
     366          16 :         session = smb2_session_init(transport,
     367             :                                     lpcfg_gensec_settings(tctx, tctx->lp_ctx),
     368             :                                     mem_ctx);
     369             : 
     370          16 :         if (session == NULL) {
     371           0 :                 return false;
     372             :         }
     373             : 
     374          16 :         status = smb2_session_setup_spnego(session,
     375             :                                            samba_cmdline_get_creds(),
     376             :                                            previous_session_id);
     377          16 :         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          16 :         *_session = session;
     384             : 
     385          16 :         return true;
     386             : }
     387             : 
     388             : /*
     389             :   open a smb2 connection
     390             : */
     391        3736 : 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             :         NTSTATUS status;
     397        3736 :         const char *host = torture_setting_string(tctx, "host", NULL);
     398        3736 :         const char *share = torture_setting_string(tctx, "share", NULL);
     399        3736 :         const char *p = torture_setting_string(tctx, "unclist", NULL);
     400        3736 :         TALLOC_CTX *mem_ctx = NULL;
     401             :         bool ok;
     402             : 
     403        3736 :         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        3736 :         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             :                                   previous_session_id,
     430             :                                   tree,
     431             :                                   tctx->ev,
     432             :                                   options,
     433             :                                   lpcfg_socket_options(tctx->lp_ctx),
     434             :                                   lpcfg_gensec_settings(tctx, tctx->lp_ctx)
     435             :                                   );
     436        3736 :         if (!NT_STATUS_IS_OK(status)) {
     437           0 :                 torture_comment(tctx, "Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
     438             :                        host, share, nt_errstr(status));
     439           0 :                 TALLOC_FREE(mem_ctx);
     440           0 :                 return false;
     441             :         }
     442             : 
     443        3736 :         TALLOC_FREE(mem_ctx);
     444        3736 :         return true;
     445             : }
     446             : 
     447        3578 : bool torture_smb2_connection(struct torture_context *tctx, struct smb2_tree **tree)
     448             : {
     449             :         bool ret;
     450             :         struct smbcli_options options;
     451             : 
     452        3578 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
     453             : 
     454        3578 :         ret = torture_smb2_connection_ext(tctx, 0, &options, tree);
     455             : 
     456        3578 :         return ret;
     457             : }
     458             : 
     459             : /**
     460             :  * SMB2 connect with share from soption
     461             :  **/
     462          18 : bool torture_smb2_con_sopt(struct torture_context *tctx,
     463             :                            const char *soption,
     464             :                            struct smb2_tree **tree)
     465             : {
     466             :         struct smbcli_options options;
     467             :         NTSTATUS status;
     468          18 :         const char *host = torture_setting_string(tctx, "host", NULL);
     469          18 :         const char *share = torture_setting_string(tctx, soption, NULL);
     470             : 
     471          18 :         lpcfg_smbcli_options(tctx->lp_ctx, &options);
     472             : 
     473          18 :         if (share == NULL) {
     474           0 :                 torture_comment(tctx, "No share for option %s\n", soption);
     475           0 :                 return false;
     476             :         }
     477             : 
     478          18 :         status = smb2_connect_ext(tctx,
     479             :                                   host,
     480             :                                   lpcfg_smb_ports(tctx->lp_ctx),
     481             :                                   share,
     482             :                                   lpcfg_resolve_context(tctx->lp_ctx),
     483             :                                   samba_cmdline_get_creds(),
     484             :                                   0,
     485             :                                   tree,
     486             :                                   tctx->ev,
     487             :                                   &options,
     488             :                                   lpcfg_socket_options(tctx->lp_ctx),
     489             :                                   lpcfg_gensec_settings(tctx, tctx->lp_ctx)
     490             :                                   );
     491          18 :         if (!NT_STATUS_IS_OK(status)) {
     492           0 :                 torture_comment(tctx, "Failed to connect to SMB2 share \\\\%s\\%s - %s\n",
     493             :                        host, share, nt_errstr(status));
     494           0 :                 return false;
     495             :         }
     496          18 :         return true;
     497             : }
     498             : 
     499             : /*
     500             :   create and return a handle to a test file
     501             :   with a specific access mask
     502             : */
     503         763 : NTSTATUS torture_smb2_testfile_access(struct smb2_tree *tree, const char *fname,
     504             :                                       struct smb2_handle *handle,
     505             :                                       uint32_t desired_access)
     506             : {
     507             :         struct smb2_create io;
     508             :         NTSTATUS status;
     509             : 
     510         763 :         ZERO_STRUCT(io);
     511         763 :         io.in.oplock_level = 0;
     512         763 :         io.in.desired_access = desired_access;
     513         763 :         io.in.file_attributes   = FILE_ATTRIBUTE_NORMAL;
     514         763 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     515         763 :         io.in.share_access = 
     516             :                 NTCREATEX_SHARE_ACCESS_DELETE|
     517             :                 NTCREATEX_SHARE_ACCESS_READ|
     518             :                 NTCREATEX_SHARE_ACCESS_WRITE;
     519         763 :         io.in.create_options = 0;
     520         763 :         io.in.fname = fname;
     521             : 
     522         763 :         status = smb2_create(tree, tree, &io);
     523         763 :         NT_STATUS_NOT_OK_RETURN(status);
     524             : 
     525         763 :         *handle = io.out.file.handle;
     526             : 
     527         763 :         return NT_STATUS_OK;
     528             : }
     529             : 
     530             : /*
     531             :   create and return a handle to a test file
     532             : */
     533         369 : NTSTATUS torture_smb2_testfile(struct smb2_tree *tree, const char *fname,
     534             :                                struct smb2_handle *handle)
     535             : {
     536         369 :         return torture_smb2_testfile_access(tree, fname, handle,
     537             :                                             SEC_RIGHTS_FILE_ALL);
     538             : }
     539             : 
     540             : /*
     541             :   create and return a handle to a test file
     542             :   with a specific access mask
     543             : */
     544         690 : NTSTATUS torture_smb2_open(struct smb2_tree *tree,
     545             :                            const char *fname,
     546             :                            uint32_t desired_access,
     547             :                            struct smb2_handle *handle)
     548             : {
     549             :         struct smb2_create io;
     550             :         NTSTATUS status;
     551             : 
     552         690 :         io = (struct smb2_create) {
     553             :                 .in.fname = fname,
     554             :                 .in.desired_access = desired_access,
     555             :                 .in.file_attributes = FILE_ATTRIBUTE_NORMAL,
     556             :                 .in.create_disposition = NTCREATEX_DISP_OPEN,
     557             :                 .in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
     558             :         };
     559             : 
     560         690 :         status = smb2_create(tree, tree, &io);
     561         690 :         if (!NT_STATUS_IS_OK(status)) {
     562         432 :                 return status;
     563             :         }
     564             : 
     565         258 :         *handle = io.out.file.handle;
     566             : 
     567         258 :         return NT_STATUS_OK;
     568             : }
     569             : 
     570             : /*
     571             :   create and return a handle to a test directory
     572             :   with specific desired access
     573             : */
     574         892 : NTSTATUS torture_smb2_testdir_access(struct smb2_tree *tree, const char *fname,
     575             :                                      struct smb2_handle *handle,
     576             :                                      uint32_t desired_access)
     577             : {
     578             :         struct smb2_create io;
     579             :         NTSTATUS status;
     580             : 
     581         892 :         ZERO_STRUCT(io);
     582         892 :         io.in.oplock_level = 0;
     583         892 :         io.in.desired_access = desired_access;
     584         892 :         io.in.file_attributes   = FILE_ATTRIBUTE_DIRECTORY;
     585         892 :         io.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
     586         892 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE;
     587         892 :         io.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     588         892 :         io.in.fname = fname;
     589             : 
     590         892 :         status = smb2_create(tree, tree, &io);
     591         892 :         NT_STATUS_NOT_OK_RETURN(status);
     592             : 
     593         892 :         *handle = io.out.file.handle;
     594             : 
     595         892 :         return NT_STATUS_OK;
     596             : }
     597             : 
     598             : /*
     599             :   create and return a handle to a test directory
     600             : */
     601         887 : NTSTATUS torture_smb2_testdir(struct smb2_tree *tree, const char *fname,
     602             :                               struct smb2_handle *handle)
     603             : {
     604         887 :         return torture_smb2_testdir_access(tree, fname, handle,
     605             :                                            SEC_RIGHTS_DIR_ALL);
     606             : }
     607             : 
     608             : /*
     609             :   create a simple file using the SMB2 protocol
     610             : */
     611          13 : NTSTATUS smb2_create_simple_file(struct torture_context *tctx,
     612             :                                  struct smb2_tree *tree, const char *fname,
     613             :                                  struct smb2_handle *handle)
     614             : {
     615          13 :         char buf[7] = "abc";
     616             :         NTSTATUS status;
     617             : 
     618          13 :         smb2_util_unlink(tree, fname);
     619          13 :         status = torture_smb2_testfile_access(tree,
     620             :                                               fname, handle,
     621             :                                               SEC_FLAG_MAXIMUM_ALLOWED);
     622          13 :         NT_STATUS_NOT_OK_RETURN(status);
     623             : 
     624          13 :         status = smb2_util_write(tree, *handle, buf, 0, sizeof(buf));
     625          13 :         NT_STATUS_NOT_OK_RETURN(status);
     626             : 
     627          13 :         return NT_STATUS_OK;
     628             : }
     629             : 
     630             : /*
     631             :   create a simple file using SMB2.
     632             : */
     633          13 : NTSTATUS torture_setup_simple_file(struct torture_context *tctx,
     634             :                                    struct smb2_tree *tree, const char *fname)
     635             : {
     636             :         struct smb2_handle handle;
     637          13 :         NTSTATUS status = smb2_create_simple_file(tctx, tree, fname, &handle);
     638          13 :         NT_STATUS_NOT_OK_RETURN(status);
     639          13 :         return smb2_util_close(tree, handle);
     640             : }
     641             : 
     642             : /*
     643             :   create a complex file using SMB2, to make it easier to
     644             :   find fields in SMB2 getinfo levels
     645             : */
     646           7 : NTSTATUS torture_setup_complex_file(struct torture_context *tctx,
     647             :                                     struct smb2_tree *tree, const char *fname)
     648             : {
     649             :         struct smb2_handle handle;
     650           7 :         NTSTATUS status = smb2_create_complex_file(tctx, tree, fname, &handle);
     651           7 :         NT_STATUS_NOT_OK_RETURN(status);
     652           2 :         return smb2_util_close(tree, handle);
     653             : }
     654             : 
     655             : 
     656             : /*
     657             :   create a complex dir using SMB2, to make it easier to
     658             :   find fields in SMB2 getinfo levels
     659             : */
     660           1 : NTSTATUS torture_setup_complex_dir(struct torture_context *tctx,
     661             :                                    struct smb2_tree *tree, const char *fname)
     662             : {
     663             :         struct smb2_handle handle;
     664           1 :         NTSTATUS status = smb2_create_complex_dir(tctx, tree, fname, &handle);
     665           1 :         NT_STATUS_NOT_OK_RETURN(status);
     666           1 :         return smb2_util_close(tree, handle);
     667             : }
     668             : 
     669             : 
     670             : /*
     671             :   return a handle to the root of the share
     672             : */
     673         103 : NTSTATUS smb2_util_roothandle(struct smb2_tree *tree, struct smb2_handle *handle)
     674             : {
     675             :         struct smb2_create io;
     676             :         NTSTATUS status;
     677             : 
     678         103 :         ZERO_STRUCT(io);
     679         103 :         io.in.oplock_level = 0;
     680         103 :         io.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE | SEC_DIR_LIST;
     681         103 :         io.in.file_attributes   = 0;
     682         103 :         io.in.create_disposition = NTCREATEX_DISP_OPEN;
     683         103 :         io.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE;
     684         103 :         io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT;
     685         103 :         io.in.fname = "";
     686             : 
     687         103 :         status = smb2_create(tree, tree, &io);
     688         103 :         NT_STATUS_NOT_OK_RETURN(status);
     689             : 
     690          95 :         *handle = io.out.file.handle;
     691             : 
     692          95 :         return NT_STATUS_OK;
     693             : }
     694             : 
     695             : /* Comparable to torture_setup_dir, but for SMB2. */
     696          94 : bool smb2_util_setup_dir(struct torture_context *tctx, struct smb2_tree *tree,
     697             :     const char *dname)
     698             : {
     699             :         NTSTATUS status;
     700             : 
     701             :         /* XXX: smb_raw_exit equivalent?
     702             :         smb_raw_exit(cli->session); */
     703          94 :         if (smb2_deltree(tree, dname) == -1) {
     704           0 :                 torture_result(tctx, TORTURE_ERROR, "Unable to deltree when setting up %s.\n", dname);
     705           0 :                 return false;
     706             :         }
     707             : 
     708          94 :         status = smb2_util_mkdir(tree, dname);
     709          94 :         if (NT_STATUS_IS_ERR(status)) {
     710           0 :                 torture_result(tctx, TORTURE_ERROR, "Unable to mkdir when setting up %s - %s\n", dname,
     711             :                     nt_errstr(status));
     712           0 :                 return false;
     713             :         }
     714             : 
     715          94 :         return true;
     716             : }
     717             : 
     718             : #define CHECK_STATUS(status, correct) do { \
     719             :         if (!NT_STATUS_EQUAL(status, correct)) { \
     720             :                 torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
     721             :                        __location__, nt_errstr(status), nt_errstr(correct)); \
     722             :                 ret = false; \
     723             :                 goto done; \
     724             :         }} while (0)
     725             : 
     726             : /*
     727             :  * Helper function to verify a security descriptor, by querying
     728             :  * and comparing against the passed in sd.
     729             :  */
     730          36 : bool smb2_util_verify_sd(TALLOC_CTX *tctx, struct smb2_tree *tree,
     731             :     struct smb2_handle handle, struct security_descriptor *sd)
     732             : {
     733             :         NTSTATUS status;
     734          36 :         bool ret = true;
     735          36 :         union smb_fileinfo q = {};
     736             : 
     737          36 :         q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
     738          36 :         q.query_secdesc.in.file.handle = handle;
     739          36 :         q.query_secdesc.in.secinfo_flags =
     740             :             SECINFO_OWNER |
     741             :             SECINFO_GROUP |
     742             :             SECINFO_DACL;
     743          36 :         status = smb2_getinfo_file(tree, tctx, &q);
     744          36 :         CHECK_STATUS(status, NT_STATUS_OK);
     745             : 
     746          36 :         if (!security_acl_equal(
     747          36 :             q.query_secdesc.out.sd->dacl, sd->dacl)) {
     748           0 :                 torture_warning(tctx, "%s: security descriptors don't match!\n",
     749             :                     __location__);
     750           0 :                 torture_warning(tctx, "got:\n");
     751           0 :                 NDR_PRINT_DEBUG(security_descriptor,
     752             :                     q.query_secdesc.out.sd);
     753           0 :                 torture_warning(tctx, "expected:\n");
     754           0 :                 NDR_PRINT_DEBUG(security_descriptor, sd);
     755           0 :                 ret = false;
     756             :         }
     757             : 
     758          72 :  done:
     759          36 :         return ret;
     760             : }
     761             : 
     762             : /*
     763             :  * Helper function to verify attributes, by querying
     764             :  * and comparing against the passed in attrib.
     765             :  */
     766          34 : bool smb2_util_verify_attrib(TALLOC_CTX *tctx, struct smb2_tree *tree,
     767             :     struct smb2_handle handle, uint32_t attrib)
     768             : {
     769             :         NTSTATUS status;
     770          34 :         bool ret = true;
     771          34 :         union smb_fileinfo q = {};
     772             : 
     773          34 :         q.standard.level = RAW_FILEINFO_SMB2_ALL_INFORMATION;
     774          34 :         q.standard.in.file.handle = handle;
     775          34 :         status = smb2_getinfo_file(tree, tctx, &q);
     776          34 :         CHECK_STATUS(status, NT_STATUS_OK);
     777             : 
     778          34 :         q.all_info2.out.attrib &= ~(FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_NONINDEXED);
     779             : 
     780          34 :         if (q.all_info2.out.attrib != attrib) {
     781           1 :                 torture_warning(tctx, "%s: attributes don't match! "
     782             :                     "got %x, expected %x\n", __location__,
     783           1 :                     (uint32_t)q.standard.out.attrib,
     784             :                     (uint32_t)attrib);
     785           1 :                 ret = false;
     786             :         }
     787             : 
     788          67 :  done:
     789          34 :         return ret;
     790             : }
     791             : 
     792             : 
     793        2862 : uint32_t smb2_util_lease_state(const char *ls)
     794             : {
     795        2862 :         uint32_t val = 0;
     796             :         int i;
     797             : 
     798        8408 :         for (i = 0; i < strlen(ls); i++) {
     799        5546 :                 switch (ls[i]) {
     800        2594 :                 case 'R':
     801        2594 :                         val |= SMB2_LEASE_READ;
     802        2594 :                         break;
     803        1734 :                 case 'H':
     804        1734 :                         val |= SMB2_LEASE_HANDLE;
     805        1734 :                         break;
     806        1218 :                 case 'W':
     807        1218 :                         val |= SMB2_LEASE_WRITE;
     808        1218 :                         break;
     809             :                 }
     810             :         }
     811             : 
     812        2862 :         return val;
     813             : }
     814             : 
     815         250 : char *smb2_util_lease_state_string(TALLOC_CTX *mem_ctx, uint32_t ls)
     816             : {
     817         750 :         return talloc_asprintf(mem_ctx, "0x%0x (%s%s%s)",
     818             :                                (unsigned)ls,
     819         250 :                                ls & SMB2_LEASE_READ ? "R": "",
     820         250 :                                ls & SMB2_LEASE_HANDLE ? "H": "",
     821         250 :                                ls & SMB2_LEASE_WRITE ? "W": "");
     822             : }
     823             : 
     824        3865 : uint32_t smb2_util_share_access(const char *sharemode)
     825             : {
     826        3865 :         uint32_t val = NTCREATEX_SHARE_ACCESS_NONE; /* 0 */
     827             :         int i;
     828             : 
     829       10574 :         for (i = 0; i < strlen(sharemode); i++) {
     830        6709 :                 switch(sharemode[i]) {
     831        2289 :                 case 'R':
     832        2289 :                         val |= NTCREATEX_SHARE_ACCESS_READ;
     833        2289 :                         break;
     834        2262 :                 case 'W':
     835        2262 :                         val |= NTCREATEX_SHARE_ACCESS_WRITE;
     836        2262 :                         break;
     837        2158 :                 case 'D':
     838        2158 :                         val |= NTCREATEX_SHARE_ACCESS_DELETE;
     839        2158 :                         break;
     840             :                 }
     841             :         }
     842             : 
     843        3865 :         return val;
     844             : }
     845             : 
     846        2799 : uint8_t smb2_util_oplock_level(const char *op)
     847             : {
     848        2799 :         uint8_t val = SMB2_OPLOCK_LEVEL_NONE;
     849             :         int i;
     850             : 
     851        2799 :         for (i = 0; i < strlen(op); i++) {
     852        2499 :                 switch (op[i]) {
     853         436 :                 case 's':
     854         436 :                         return SMB2_OPLOCK_LEVEL_II;
     855         240 :                 case 'x':
     856         240 :                         return SMB2_OPLOCK_LEVEL_EXCLUSIVE;
     857        1823 :                 case 'b':
     858        1823 :                         return SMB2_OPLOCK_LEVEL_BATCH;
     859           0 :                 default:
     860           0 :                         continue;
     861             :                 }
     862             :         }
     863             : 
     864         300 :         return val;
     865             : }
     866             : 
     867             : /**
     868             :  * Helper functions to fill a smb2_create struct for several
     869             :  * open scenarios.
     870             :  */
     871        2422 : void smb2_generic_create_share(struct smb2_create *io, struct smb2_lease *ls,
     872             :                                bool dir, const char *name, uint32_t disposition,
     873             :                                uint32_t share_access,
     874             :                                uint8_t oplock, uint64_t leasekey,
     875             :                                uint32_t leasestate)
     876             : {
     877        2422 :         ZERO_STRUCT(*io);
     878        2422 :         io->in.security_flags                = 0x00;
     879        2422 :         io->in.oplock_level          = oplock;
     880        2422 :         io->in.impersonation_level   = NTCREATEX_IMPERSONATION_IMPERSONATION;
     881        2422 :         io->in.create_flags          = 0x00000000;
     882        2422 :         io->in.reserved                      = 0x00000000;
     883        2422 :         io->in.desired_access                = SEC_RIGHTS_FILE_ALL;
     884        2422 :         io->in.file_attributes               = FILE_ATTRIBUTE_NORMAL;
     885        2422 :         io->in.share_access          = share_access;
     886        2422 :         io->in.create_disposition    = disposition;
     887        2422 :         io->in.create_options                = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
     888             :                                           NTCREATEX_OPTIONS_ASYNC_ALERT |
     889             :                                           NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
     890             :                                           0x00200000;
     891        2422 :         io->in.fname                 = name;
     892             : 
     893        2422 :         if (dir) {
     894           4 :                 io->in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
     895           4 :                 io->in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
     896           4 :                 io->in.create_disposition = NTCREATEX_DISP_CREATE;
     897             :         }
     898             : 
     899        2422 :         if (ls) {
     900         876 :                 ZERO_STRUCTPN(ls);
     901         876 :                 ls->lease_key.data[0] = leasekey;
     902         876 :                 ls->lease_key.data[1] = ~leasekey;
     903         876 :                 ls->lease_state = leasestate;
     904         876 :                 io->in.lease_request = ls;
     905             :         }
     906        2422 : }
     907             : 
     908           4 : void smb2_generic_create(struct smb2_create *io, struct smb2_lease *ls,
     909             :                          bool dir, const char *name, uint32_t disposition,
     910             :                          uint8_t oplock, uint64_t leasekey,
     911             :                          uint32_t leasestate)
     912             : {
     913           4 :         smb2_generic_create_share(io, ls, dir, name, disposition,
     914             :                                   smb2_util_share_access("RWD"),
     915             :                                   oplock,
     916             :                                   leasekey, leasestate);
     917           4 : }
     918             : 
     919         876 : void smb2_lease_create_share(struct smb2_create *io, struct smb2_lease *ls,
     920             :                              bool dir, const char *name, uint32_t share_access,
     921             :                              uint64_t leasekey, uint32_t leasestate)
     922             : {
     923         876 :         smb2_generic_create_share(io, ls, dir, name, NTCREATEX_DISP_OPEN_IF,
     924             :                                   share_access, SMB2_OPLOCK_LEVEL_LEASE,
     925             :                                   leasekey, leasestate);
     926         876 : }
     927             : 
     928         562 : void smb2_lease_create(struct smb2_create *io, struct smb2_lease *ls,
     929             :                        bool dir, const char *name, uint64_t leasekey,
     930             :                        uint32_t leasestate)
     931             : {
     932         562 :         smb2_lease_create_share(io, ls, dir, name,
     933             :                                 smb2_util_share_access("RWD"),
     934             :                                 leasekey, leasestate);
     935         562 : }
     936             : 
     937         114 : void smb2_lease_v2_create_share(struct smb2_create *io,
     938             :                                 struct smb2_lease *ls,
     939             :                                 bool dir,
     940             :                                 const char *name,
     941             :                                 uint32_t share_access,
     942             :                                 uint64_t leasekey,
     943             :                                 const uint64_t *parentleasekey,
     944             :                                 uint32_t leasestate,
     945             :                                 uint16_t lease_epoch)
     946             : {
     947         114 :         smb2_generic_create_share(io, NULL, dir, name, NTCREATEX_DISP_OPEN_IF,
     948             :                                   share_access, SMB2_OPLOCK_LEVEL_LEASE, 0, 0);
     949             : 
     950         114 :         if (ls) {
     951         114 :                 ZERO_STRUCT(*ls);
     952         114 :                 ls->lease_key.data[0] = leasekey;
     953         114 :                 ls->lease_key.data[1] = ~leasekey;
     954         114 :                 ls->lease_state = leasestate;
     955         114 :                 if (parentleasekey != NULL) {
     956           0 :                         ls->lease_flags |= SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET;
     957           0 :                         ls->parent_lease_key.data[0] = *parentleasekey;
     958           0 :                         ls->parent_lease_key.data[1] = ~(*parentleasekey);
     959             :                 }
     960         114 :                 ls->lease_epoch = lease_epoch;
     961         114 :                 io->in.lease_request_v2 = ls;
     962             :         }
     963         114 : }
     964             : 
     965          86 : void smb2_lease_v2_create(struct smb2_create *io,
     966             :                           struct smb2_lease *ls,
     967             :                           bool dir,
     968             :                           const char *name,
     969             :                           uint64_t leasekey,
     970             :                           const uint64_t *parentleasekey,
     971             :                           uint32_t leasestate,
     972             :                           uint16_t lease_epoch)
     973             : {
     974          86 :         smb2_lease_v2_create_share(io, ls, dir, name,
     975             :                                    smb2_util_share_access("RWD"),
     976             :                                    leasekey, parentleasekey,
     977             :                                    leasestate, lease_epoch);
     978          86 : }
     979             : 
     980             : 
     981        1428 : void smb2_oplock_create_share(struct smb2_create *io, const char *name,
     982             :                               uint32_t share_access, uint8_t oplock)
     983             : {
     984        1428 :         smb2_generic_create_share(io, NULL, false, name, NTCREATEX_DISP_OPEN_IF,
     985             :                                   share_access, oplock, 0, 0);
     986        1428 : }
     987         232 : void smb2_oplock_create(struct smb2_create *io, const char *name, uint8_t oplock)
     988             : {
     989         232 :         smb2_oplock_create_share(io, name, smb2_util_share_access("RWD"),
     990             :                                  oplock);
     991         232 : }
     992             : 
     993             : /*
     994             :    a wrapper around smblsa_sid_check_privilege, that tries to take
     995             :    account of the fact that the lsa privileges calls don't expand
     996             :    group memberships, using an explicit check for administrator. There
     997             :    must be a better way ...
     998             :  */
     999          15 : NTSTATUS torture_smb2_check_privilege(struct smb2_tree *tree,
    1000             :                                      const char *sid_str,
    1001             :                                      const char *privilege)
    1002             : {
    1003          15 :         struct dom_sid *sid = NULL;
    1004          15 :         TALLOC_CTX *tmp_ctx = NULL;
    1005             :         uint32_t rid;
    1006             :         NTSTATUS status;
    1007             : 
    1008          15 :         tmp_ctx = talloc_new(tree);
    1009          15 :         if (tmp_ctx == NULL) {
    1010           0 :                 return NT_STATUS_NO_MEMORY;
    1011             :         }
    1012             : 
    1013          15 :         sid = dom_sid_parse_talloc(tmp_ctx, sid_str);
    1014          15 :         if (sid == NULL) {
    1015           0 :                 talloc_free(tmp_ctx);
    1016           0 :                 return NT_STATUS_INVALID_SID;
    1017             :         }
    1018             : 
    1019          15 :         status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
    1020          15 :         if (!NT_STATUS_IS_OK(status)) {
    1021           0 :                 TALLOC_FREE(tmp_ctx);
    1022           0 :                 return status;
    1023             :         }
    1024             : 
    1025          15 :         if (rid == DOMAIN_RID_ADMINISTRATOR) {
    1026             :                 /* assume the administrator has them all */
    1027           9 :                 TALLOC_FREE(tmp_ctx);
    1028           9 :                 return NT_STATUS_OK;
    1029             :         }
    1030             : 
    1031           6 :         talloc_free(tmp_ctx);
    1032             : 
    1033           6 :         return smb2lsa_sid_check_privilege(tree, sid_str, privilege);
    1034             : }

Generated by: LCOV version 1.13