LCOV - code coverage report
Current view: top level - source4/torture/raw - qfileinfo.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 253 312 81.1 %
Date: 2024-04-21 15:09:00 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    RAW_FILEINFO_* individual test suite
       4             :    Copyright (C) Andrew Tridgell 2003
       5             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2007
       6             :    
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             :    
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             :    
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "libcli/raw/libcliraw.h"
      23             : #include "libcli/raw/raw_proto.h"
      24             : #include "libcli/libcli.h"
      25             : #include "torture/util.h"
      26             : #include "torture/rpc/torture_rpc.h"
      27             : #include "param/param.h"
      28             : #include "torture/raw/proto.h"
      29             : 
      30             : static struct {
      31             :         const char *name;
      32             :         enum smb_fileinfo_level level;
      33             :         unsigned int only_paths:1;
      34             :         unsigned int only_handles:1;
      35             :         uint32_t capability_mask;
      36             :         unsigned int expected_ipc_access_denied:1;
      37             :         NTSTATUS expected_ipc_fnum_status;
      38             :         NTSTATUS fnum_status, fname_status;
      39             :         union smb_fileinfo fnum_finfo, fname_finfo;
      40             : } levels[] = {
      41             :         {
      42             :                 .name = "GETATTR",
      43             :                 .level = RAW_FILEINFO_GETATTR,
      44             :                 .only_paths = 1,
      45             :                 .only_handles = 0,
      46             :                 .expected_ipc_access_denied = 1,
      47             :         },
      48             :         {
      49             :                 .name ="GETATTRE",
      50             :                 .level = RAW_FILEINFO_GETATTRE,
      51             :                 .only_paths = 0,
      52             :                 .only_handles = 1,
      53             :         },
      54             :         {
      55             :                 .name ="STANDARD",
      56             :                 .level = RAW_FILEINFO_STANDARD,
      57             :         },
      58             :         {
      59             :                 .name ="EA_SIZE",
      60             :                 .level = RAW_FILEINFO_EA_SIZE,
      61             :         },
      62             :         {
      63             :                 .name ="ALL_EAS",
      64             :                 .level = RAW_FILEINFO_ALL_EAS,
      65             :                 .expected_ipc_fnum_status = NT_STATUS_ACCESS_DENIED,
      66             :                 .fnum_status = NT_STATUS_SUCCESS,
      67             :                 .fname_status = NT_STATUS_SUCCESS,
      68             :                 .fnum_finfo = {
      69             :                         .generic = {
      70             :                                 .level = 0,
      71             :                         },
      72             :                 },
      73             :                 .fname_finfo = {
      74             :                         .generic = {
      75             :                                 .level = 0,
      76             :                         },
      77             :                 },
      78             :         },
      79             :         {
      80             :                 .name ="IS_NAME_VALID",
      81             :                 .level =  RAW_FILEINFO_IS_NAME_VALID,
      82             :                 .only_paths =  1,
      83             :                 .only_handles =  0,
      84             :         },
      85             :         {
      86             :                 .name ="BASIC_INFO",
      87             :                 .level =  RAW_FILEINFO_BASIC_INFO,
      88             :         },
      89             :         {
      90             :                 .name ="STANDARD_INFO",
      91             :                 .level =  RAW_FILEINFO_STANDARD_INFO,
      92             :         },
      93             :         {
      94             :                 .name ="EA_INFO",
      95             :                 .level =  RAW_FILEINFO_EA_INFO,
      96             :         },
      97             :         {
      98             :                 .name ="NAME_INFO",
      99             :                 .level =  RAW_FILEINFO_NAME_INFO,
     100             :         },
     101             :         {
     102             :                 .name ="ALL_INFO",
     103             :                 .level =  RAW_FILEINFO_ALL_INFO,
     104             :         },
     105             :         {
     106             :                 .name ="ALT_NAME_INFO",
     107             :                 .level =  RAW_FILEINFO_ALT_NAME_INFO,
     108             :                 .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER,
     109             :                 .fnum_status = NT_STATUS_SUCCESS,
     110             :                 .fname_status = NT_STATUS_SUCCESS,
     111             :                 .fnum_finfo = {
     112             :                         .generic = {
     113             :                                 .level = 0,
     114             :                         },
     115             :                 },
     116             :                 .fname_finfo = {
     117             :                         .generic = {
     118             :                                 .level = 0,
     119             :                         },
     120             :                 },
     121             :         },
     122             :         {
     123             :                 .name ="STREAM_INFO",
     124             :                 .level =  RAW_FILEINFO_STREAM_INFO,
     125             :                 .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER,
     126             :                 .fnum_status = NT_STATUS_SUCCESS,
     127             :                 .fname_status = NT_STATUS_SUCCESS,
     128             :                 .fnum_finfo = {
     129             :                         .generic = {
     130             :                                 .level = 0,
     131             :                         },
     132             :                 },
     133             :                 .fname_finfo = {
     134             :                         .generic = {
     135             :                                 .level = 0,
     136             :                         },
     137             :                 },
     138             :         },
     139             :         {
     140             :                 .name ="COMPRESSION_INFO",
     141             :                 .level =  RAW_FILEINFO_COMPRESSION_INFO,
     142             :                 .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER,
     143             :                 .fnum_status = NT_STATUS_SUCCESS,
     144             :                 .fname_status = NT_STATUS_SUCCESS,
     145             :                 .fnum_finfo = {
     146             :                         .generic = {
     147             :                                 .level = 0,
     148             :                         },
     149             :                 },
     150             :                 .fname_finfo = {
     151             :                         .generic = {
     152             :                                 .level = 0,
     153             :                         },
     154             :                 },
     155             :         },
     156             :         {
     157             :                 .name ="UNIX_BASIC_INFO",
     158             :                 .level =  RAW_FILEINFO_UNIX_BASIC,
     159             :                 .only_paths =  0,
     160             :                 .only_handles = 0,
     161             :                 .capability_mask = CAP_UNIX,
     162             :         },
     163             :         {
     164             :                 .name ="UNIX_LINK_INFO",
     165             :                 .level =  RAW_FILEINFO_UNIX_LINK,
     166             :                 .only_paths = 0,
     167             :                 .only_handles = 0,
     168             :                 .capability_mask = CAP_UNIX,
     169             :         },
     170             :         {
     171             :                 .name ="BASIC_INFORMATION",
     172             :                 .level =  RAW_FILEINFO_BASIC_INFORMATION,
     173             :         },
     174             :         {
     175             :                 .name ="STANDARD_INFORMATION",
     176             :                 .level =  RAW_FILEINFO_STANDARD_INFORMATION,
     177             :         },
     178             :         {
     179             :                 .name ="INTERNAL_INFORMATION",
     180             :                 .level =  RAW_FILEINFO_INTERNAL_INFORMATION,
     181             :         },
     182             :         {
     183             :                 .name ="EA_INFORMATION",
     184             :                 .level =  RAW_FILEINFO_EA_INFORMATION,
     185             :         },
     186             :         {
     187             :                 .name = "ACCESS_INFORMATION",
     188             :                 .level =  RAW_FILEINFO_ACCESS_INFORMATION,
     189             :         },
     190             :         {
     191             :                 .name = "NAME_INFORMATION",
     192             :                 .level =  RAW_FILEINFO_NAME_INFORMATION,
     193             :         },
     194             :         {
     195             :                 .name ="POSITION_INFORMATION",
     196             :                 .level =  RAW_FILEINFO_POSITION_INFORMATION,
     197             :         },
     198             :         {
     199             :                 .name ="MODE_INFORMATION",
     200             :                 .level =  RAW_FILEINFO_MODE_INFORMATION,
     201             :         },
     202             :         {
     203             :                 .name ="ALIGNMENT_INFORMATION",
     204             :                 .level =  RAW_FILEINFO_ALIGNMENT_INFORMATION,
     205             :         },
     206             :         {
     207             :                 .name ="ALL_INFORMATION",
     208             :                 .level =  RAW_FILEINFO_ALL_INFORMATION,
     209             :         },
     210             :         {
     211             :                 .name ="ALT_NAME_INFORMATION",
     212             :                 .level =  RAW_FILEINFO_ALT_NAME_INFORMATION,
     213             :                 .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER,
     214             :                 .fnum_status = NT_STATUS_SUCCESS,
     215             :                 .fname_status = NT_STATUS_SUCCESS,
     216             :                 .fnum_finfo = {
     217             :                         .generic = {
     218             :                                 .level = 0,
     219             :                         },
     220             :                 },
     221             :                 .fname_finfo = {
     222             :                         .generic = {
     223             :                                 .level = 0,
     224             :                         },
     225             :                 },
     226             :         },
     227             :         {
     228             :                 .name ="STREAM_INFORMATION",
     229             :                 .level =  RAW_FILEINFO_STREAM_INFORMATION,
     230             :                 .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER,
     231             :                 .fnum_status = NT_STATUS_SUCCESS,
     232             :                 .fname_status = NT_STATUS_SUCCESS,
     233             :                 .fnum_finfo = {
     234             :                         .generic = {
     235             :                                 .level = 0,
     236             :                         },
     237             :                 },
     238             :                 .fname_finfo = {
     239             :                         .generic = {
     240             :                                 .level = 0,
     241             :                         },
     242             :                 },
     243             :         },
     244             :         {
     245             :                 .name = "COMPRESSION_INFORMATION",
     246             :                 .level =  RAW_FILEINFO_COMPRESSION_INFORMATION,
     247             :                 .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER,
     248             :                 .fnum_status = NT_STATUS_SUCCESS,
     249             :                 .fname_status = NT_STATUS_SUCCESS,
     250             :                 .fnum_finfo = {
     251             :                         .generic = {
     252             :                                 .level = 0,
     253             :                         },
     254             :                 },
     255             :                 .fname_finfo = {
     256             :                         .generic = {
     257             :                                 .level = 0,
     258             :                         },
     259             :                 },
     260             :         },
     261             :         {
     262             :                 .name ="NETWORK_OPEN_INFORMATION",
     263             :                 .level =  RAW_FILEINFO_NETWORK_OPEN_INFORMATION,
     264             :                 .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER,
     265             :                 .fnum_status = NT_STATUS_SUCCESS,
     266             :                 .fname_status = NT_STATUS_SUCCESS,
     267             :                 .fnum_finfo = {
     268             :                         .generic = {
     269             :                                 .level = 0,
     270             :                         },
     271             :                 },
     272             :                 .fname_finfo = {
     273             :                         .generic = {
     274             :                                 .level = 0,
     275             :                         },
     276             :                 },
     277             :         },
     278             :         {
     279             :                 .name = "ATTRIBUTE_TAG_INFORMATION",
     280             :                 .level =  RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION,
     281             :                 .expected_ipc_fnum_status = NT_STATUS_INVALID_PARAMETER,
     282             :                 .fnum_status = NT_STATUS_SUCCESS,
     283             :                 .fname_status = NT_STATUS_SUCCESS,
     284             :                 .fnum_finfo = {
     285             :                         .generic = {
     286             :                                 .level = 0,
     287             :                         },
     288             :                 },
     289             :                 .fname_finfo = {
     290             :                         .generic = {
     291             :                                 .level = 0,
     292             :                         },
     293             :                 },
     294             :         },
     295             :         { .name = NULL, },
     296             : };
     297             : 
     298             : /*
     299             :   compare a dos time (2 second resolution) to a nt time
     300             : */
     301          25 : static int dos_nt_time_cmp(time_t t, NTTIME nt)
     302             : {
     303          25 :         time_t t2 = nt_time_to_unix(nt);
     304          25 :         if (labs(t2 - t) <= 2) return 0;
     305           0 :         return t2 > t ? 1 : -1;
     306             : }
     307             : 
     308             : 
     309             : /*
     310             :   find a level in the levels[] table
     311             : */
     312         241 : static union smb_fileinfo *fnum_find(const char *name)
     313             : {
     314           0 :         int i;
     315        3511 :         for (i=0; levels[i].name; i++) {
     316        3482 :                 if (NT_STATUS_IS_OK(levels[i].fnum_status) &&
     317        2936 :                     strcmp(name, levels[i].name) == 0 && 
     318         218 :                     !levels[i].only_paths) {
     319         212 :                         return &levels[i].fnum_finfo;
     320             :                 }
     321             :         }
     322          29 :         return NULL;
     323             : }
     324             : 
     325             : /*
     326             :   find a level in the levels[] table
     327             : */
     328         213 : static union smb_fileinfo *fname_find(bool is_ipc, const char *name)
     329             : {
     330           0 :         int i;
     331         213 :         if (is_ipc) {
     332         100 :                 return NULL;
     333             :         }
     334        1773 :         for (i=0; levels[i].name; i++) {
     335        1767 :                 if (NT_STATUS_IS_OK(levels[i].fname_status) &&
     336        1667 :                     strcmp(name, levels[i].name) == 0 && 
     337         113 :                     !levels[i].only_handles) {
     338         107 :                         return &levels[i].fname_finfo;
     339             :                 }
     340             :         }
     341           6 :         return NULL;
     342             : }
     343             : 
     344             : /* local macros to make the code below more readable */
     345             : #define VAL_EQUAL(n1, v1, n2, v2) do {if (s1->n1.out.v1 != s2->n2.out.v2) { \
     346             :         printf("%s/%s [%u] != %s/%s [%u] at %s(%d)\n", \
     347             :                #n1, #v1, (unsigned int)s1->n1.out.v1, \
     348             :                #n2, #v2, (unsigned int)s2->n2.out.v2, \
     349             :                __FILE__, __LINE__); \
     350             :         ret = false; \
     351             : }} while(0)
     352             : 
     353             : #define STR_EQUAL(n1, v1, n2, v2) do {if (strcmp_safe(s1->n1.out.v1.s, s2->n2.out.v2.s) || \
     354             :                                           s1->n1.out.v1.private_length != s2->n2.out.v2.private_length) { \
     355             :         printf("%s/%s [%s/%d] != %s/%s [%s/%d] at %s(%d)\n", \
     356             :                #n1, #v1, s1->n1.out.v1.s, s1->n1.out.v1.private_length, \
     357             :                #n2, #v2, s2->n2.out.v2.s, s2->n2.out.v2.private_length, \
     358             :                __FILE__, __LINE__); \
     359             :         ret = false; \
     360             : }} while(0)
     361             : 
     362             : #define STRUCT_EQUAL(n1, v1, n2, v2) do {if (memcmp(&s1->n1.out.v1,&s2->n2.out.v2,sizeof(s1->n1.out.v1))) { \
     363             :         printf("%s/%s != %s/%s at %s(%d)\n", \
     364             :                #n1, #v1, \
     365             :                #n2, #v2, \
     366             :                __FILE__, __LINE__); \
     367             :         ret = false; \
     368             : }} while(0)
     369             : 
     370             : /* used to find hints on unknown values - and to make sure 
     371             :    we zero-fill */
     372             : #if 0 /* unused */
     373             : #define VAL_UNKNOWN(n1, v1) do {if (s1->n1.out.v1 != 0) { \
     374             :         printf("%s/%s non-zero unknown - %u (0x%x) at %s(%d)\n", \
     375             :                #n1, #v1, \
     376             :                (unsigned int)s1->n1.out.v1, \
     377             :                (unsigned int)s1->n1.out.v1, \
     378             :                __FILE__, __LINE__); \
     379             :         ret = false; \
     380             : }} while(0)
     381             : #endif
     382             : 
     383             : /* basic testing of all RAW_FILEINFO_* calls 
     384             :    for each call we test that it succeeds, and where possible test 
     385             :    for consistency between the calls. 
     386             : */
     387           2 : static bool torture_raw_qfileinfo_internals(struct torture_context *torture, 
     388             :                                             TALLOC_CTX *mem_ctx,        
     389             :                                             struct smbcli_tree *tree, 
     390             :                                             int fnum, const char *fname,
     391             :                                             bool is_ipc)
     392             : {
     393           0 :         size_t i;
     394           2 :         bool ret = true;
     395           0 :         size_t count;
     396           0 :         union smb_fileinfo *s1, *s2;    
     397           0 :         NTTIME correct_time;
     398           0 :         uint64_t correct_size;
     399           0 :         uint32_t correct_attrib;
     400           0 :         const char *correct_name;
     401           2 :         bool skip_streams = false;
     402             : 
     403             :         /* scan all the fileinfo and pathinfo levels */
     404          64 :         for (i=0; levels[i].name; i++) {
     405          62 :                 if (!levels[i].only_paths) {
     406          58 :                         levels[i].fnum_finfo.generic.level = levels[i].level;
     407          58 :                         levels[i].fnum_finfo.generic.in.file.fnum = fnum;
     408          58 :                         levels[i].fnum_status = smb_raw_fileinfo(tree, mem_ctx, 
     409             :                                                                  &levels[i].fnum_finfo);
     410             :                 }
     411             : 
     412          62 :                 if (!levels[i].only_handles) {
     413          60 :                         levels[i].fname_finfo.generic.level = levels[i].level;
     414          60 :                         levels[i].fname_finfo.generic.in.file.path = talloc_strdup(mem_ctx, fname);
     415          60 :                         levels[i].fname_status = smb_raw_pathinfo(tree, mem_ctx, 
     416             :                                                                   &levels[i].fname_finfo);
     417             :                 }
     418             :         }
     419             : 
     420             :         /* check for completely broken levels */
     421          64 :         for (count=i=0; levels[i].name; i++) {
     422          62 :                 uint32_t cap = tree->session->transport->negotiate.capabilities;
     423             :                 /* see if this server claims to support this level */
     424          62 :                 if ((cap & levels[i].capability_mask) != levels[i].capability_mask) {
     425           4 :                         continue;
     426             :                 }
     427             : 
     428          58 :                 if (is_ipc) {
     429          29 :                         if (levels[i].expected_ipc_access_denied && NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, levels[i].fname_status)) {
     430          28 :                         } else if (!levels[i].only_handles &&
     431          27 :                                    NT_STATUS_EQUAL(levels[i].fname_status,
     432             :                                    NT_STATUS_NOT_SUPPORTED)) {
     433           0 :                                 torture_warning(torture, "fname level %s %s",
     434             :                                         levels[i].name,
     435             :                                         nt_errstr(levels[i].fname_status));
     436           0 :                                 continue;
     437          28 :                         } else if (!levels[i].only_handles && !NT_STATUS_EQUAL(NT_STATUS_INVALID_DEVICE_REQUEST, levels[i].fname_status)) {
     438           0 :                                 printf("ERROR: fname level %s failed, expected NT_STATUS_INVALID_DEVICE_REQUEST - %s\n", 
     439             :                                        levels[i].name, nt_errstr(levels[i].fname_status));
     440           0 :                                 count++;
     441             :                         }
     442          29 :                         if (!levels[i].only_paths &&
     443          27 :                            (NT_STATUS_EQUAL(levels[i].fnum_status,
     444          27 :                             NT_STATUS_NOT_SUPPORTED) ||
     445          27 :                             NT_STATUS_EQUAL(levels[i].fnum_status,
     446             :                             NT_STATUS_NOT_IMPLEMENTED))) {
     447           0 :                                 torture_warning(torture, "fnum level %s %s",
     448             :                                         levels[i].name,
     449             :                                         nt_errstr(levels[i].fnum_status));
     450           0 :                                 continue;
     451             :                         }
     452          29 :                         if (!levels[i].only_paths && !NT_STATUS_EQUAL(levels[i].expected_ipc_fnum_status, levels[i].fnum_status)) {
     453           0 :                                 printf("ERROR: fnum level %s failed, expected %s - %s\n", 
     454             :                                        levels[i].name, nt_errstr(levels[i].expected_ipc_fnum_status), 
     455             :                                        nt_errstr(levels[i].fnum_status));
     456           0 :                                 count++;
     457             :                         }
     458             :                 } else {
     459          29 :                         if (!levels[i].only_paths &&
     460          27 :                            (NT_STATUS_EQUAL(levels[i].fnum_status,
     461          27 :                             NT_STATUS_NOT_SUPPORTED) ||
     462          27 :                             NT_STATUS_EQUAL(levels[i].fnum_status,
     463             :                             NT_STATUS_NOT_IMPLEMENTED))) {
     464           0 :                                 torture_warning(torture, "fnum level %s %s",
     465             :                                         levels[i].name,
     466             :                                         nt_errstr(levels[i].fnum_status));
     467           0 :                                 continue;
     468             :                         }
     469             : 
     470          29 :                         if (!levels[i].only_handles &&
     471          28 :                            (NT_STATUS_EQUAL(levels[i].fname_status,
     472          28 :                             NT_STATUS_NOT_SUPPORTED) ||
     473          28 :                             NT_STATUS_EQUAL(levels[i].fname_status,
     474             :                             NT_STATUS_NOT_IMPLEMENTED))) {
     475           0 :                                 torture_warning(torture, "fname level %s %s",
     476             :                                         levels[i].name,
     477             :                                         nt_errstr(levels[i].fname_status));
     478           0 :                                 continue;
     479             :                         }
     480             : 
     481          29 :                         if (!levels[i].only_paths && !NT_STATUS_IS_OK(levels[i].fnum_status)) {
     482           0 :                                 printf("ERROR: fnum level %s failed - %s\n", 
     483             :                                        levels[i].name, nt_errstr(levels[i].fnum_status));
     484           0 :                                 count++;
     485             :                         }
     486          29 :                         if (!levels[i].only_handles && !NT_STATUS_IS_OK(levels[i].fname_status)) {
     487           0 :                                 printf("ERROR: fname level %s failed - %s\n", 
     488             :                                        levels[i].name, nt_errstr(levels[i].fname_status));
     489           0 :                                 count++;
     490             :                         }
     491             :                 }
     492             :                 
     493             :         }
     494             : 
     495           2 :         if (count != 0) {
     496           0 :                 ret = false;
     497           0 :                 printf("%zu levels failed\n", count);
     498           0 :                 if (count > 35) {
     499           0 :                         torture_fail(torture, "too many level failures - giving up");
     500             :                 }
     501             :         }
     502             : 
     503             :         /* see if we can do streams */
     504           2 :         s1 = fnum_find("STREAM_INFO");
     505           2 :         if (!s1 || s1->stream_info.out.num_streams == 0) {
     506           1 :                 if (!is_ipc) {
     507           0 :                         printf("STREAM_INFO broken (%d) - skipping streams checks\n",
     508             :                                s1 ? s1->stream_info.out.num_streams : -1);
     509             :                 }
     510           1 :                 skip_streams = true;
     511             :         }       
     512             : 
     513             : 
     514             :         /* this code is incredibly repititive but doesn't lend itself to loops, so
     515             :            we use lots of macros to make it less painful */
     516             : 
     517             :         /* first off we check the levels that are supposed to be aliases. It will be quite rare for 
     518             :            this code to fail, but we need to check it for completeness */
     519             : 
     520             : 
     521             : 
     522             : #define ALIAS_CHECK(sname1, sname2) \
     523             :         do { \
     524             :                 s1 = fnum_find(sname1);  s2 = fnum_find(sname2); \
     525             :                 if (s1 && s2) { INFO_CHECK } \
     526             :                 s1 = fname_find(is_ipc, sname1); s2 = fname_find(is_ipc, sname2); \
     527             :                 if (s1 && s2) { INFO_CHECK } \
     528             :                 s1 = fnum_find(sname1);  s2 = fname_find(is_ipc, sname2); \
     529             :                 if (s1 && s2) { INFO_CHECK } \
     530             :         } while (0)
     531             : 
     532             : #define INFO_CHECK \
     533             :                 STRUCT_EQUAL(basic_info,  create_time, basic_info, create_time); \
     534             :                 STRUCT_EQUAL(basic_info,  access_time, basic_info, access_time); \
     535             :                 STRUCT_EQUAL(basic_info,  write_time,  basic_info, write_time); \
     536             :                 STRUCT_EQUAL(basic_info,  change_time, basic_info, change_time); \
     537             :                 VAL_EQUAL   (basic_info,  attrib,      basic_info, attrib);
     538             : 
     539           2 :         ALIAS_CHECK("BASIC_INFO", "BASIC_INFORMATION");
     540             : 
     541             : #undef INFO_CHECK
     542             : #define INFO_CHECK \
     543             :                 VAL_EQUAL(standard_info,  alloc_size,     standard_info, alloc_size); \
     544             :                 VAL_EQUAL(standard_info,  size,           standard_info, size); \
     545             :                 VAL_EQUAL(standard_info,  nlink,          standard_info, nlink); \
     546             :                 VAL_EQUAL(standard_info,  delete_pending, standard_info, delete_pending); \
     547             :                 VAL_EQUAL(standard_info,  directory,      standard_info, directory);
     548             : 
     549           2 :         ALIAS_CHECK("STANDARD_INFO", "STANDARD_INFORMATION");
     550             : 
     551             : #undef INFO_CHECK
     552             : #define INFO_CHECK \
     553             :                 VAL_EQUAL(ea_info,  ea_size,     ea_info, ea_size);
     554             : 
     555           2 :         ALIAS_CHECK("EA_INFO", "EA_INFORMATION");
     556             : 
     557             : #undef INFO_CHECK
     558             : #define INFO_CHECK \
     559             :                 STR_EQUAL(name_info,  fname,   name_info, fname);
     560             : 
     561           2 :         ALIAS_CHECK("NAME_INFO", "NAME_INFORMATION");
     562             : 
     563             : #undef INFO_CHECK
     564             : #define INFO_CHECK \
     565             :                 STRUCT_EQUAL(all_info,  create_time,           all_info, create_time); \
     566             :                 STRUCT_EQUAL(all_info,  access_time,           all_info, access_time); \
     567             :                 STRUCT_EQUAL(all_info,  write_time,            all_info, write_time); \
     568             :                 STRUCT_EQUAL(all_info,  change_time,           all_info, change_time); \
     569             :                    VAL_EQUAL(all_info,  attrib,                all_info, attrib); \
     570             :                    VAL_EQUAL(all_info,  alloc_size,            all_info, alloc_size); \
     571             :                    VAL_EQUAL(all_info,  size,                  all_info, size); \
     572             :                    VAL_EQUAL(all_info,  nlink,                 all_info, nlink); \
     573             :                    VAL_EQUAL(all_info,  delete_pending,        all_info, delete_pending); \
     574             :                    VAL_EQUAL(all_info,  directory,             all_info, directory); \
     575             :                    VAL_EQUAL(all_info,  ea_size,               all_info, ea_size); \
     576             :                    STR_EQUAL(all_info,  fname,                 all_info, fname);
     577             : 
     578           2 :         ALIAS_CHECK("ALL_INFO", "ALL_INFORMATION");
     579             : 
     580             : #undef INFO_CHECK
     581             : #define INFO_CHECK \
     582             :                 VAL_EQUAL(compression_info, compressed_size,compression_info, compressed_size); \
     583             :                 VAL_EQUAL(compression_info, format,         compression_info, format); \
     584             :                 VAL_EQUAL(compression_info, unit_shift,     compression_info, unit_shift); \
     585             :                 VAL_EQUAL(compression_info, chunk_shift,    compression_info, chunk_shift); \
     586             :                 VAL_EQUAL(compression_info, cluster_shift,  compression_info, cluster_shift);
     587             : 
     588           2 :         ALIAS_CHECK("COMPRESSION_INFO", "COMPRESSION_INFORMATION");
     589             : 
     590             : 
     591             : #undef INFO_CHECK
     592             : #define INFO_CHECK \
     593             :                 STR_EQUAL(alt_name_info,  fname,   alt_name_info, fname);
     594             : 
     595           2 :         ALIAS_CHECK("ALT_NAME_INFO", "ALT_NAME_INFORMATION");
     596             : 
     597             : 
     598             : #define TIME_CHECK_NT(sname, stype, tfield) do { \
     599             :         s1 = fnum_find(sname); \
     600             :         if (s1 && memcmp(&s1->stype.out.tfield, &correct_time, sizeof(correct_time)) != 0) { \
     601             :                 printf("(%d) handle %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
     602             :                        nt_time_string(mem_ctx, s1->stype.out.tfield), \
     603             :                        nt_time_string(mem_ctx, correct_time)); \
     604             :                 ret = false; \
     605             :         } \
     606             :         s1 = fname_find(is_ipc, sname); \
     607             :         if (s1 && memcmp(&s1->stype.out.tfield, &correct_time, sizeof(correct_time)) != 0) { \
     608             :                 printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
     609             :                        nt_time_string(mem_ctx, s1->stype.out.tfield), \
     610             :                        nt_time_string(mem_ctx, correct_time)); \
     611             :                 ret = false; \
     612             :         }} while (0)
     613             : 
     614             : #define TIME_CHECK_DOS(sname, stype, tfield) do { \
     615             :         s1 = fnum_find(sname); \
     616             :         if (s1 && dos_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
     617             :                 printf("(%d) handle %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
     618             :                        timestring(mem_ctx, s1->stype.out.tfield), \
     619             :                        nt_time_string(mem_ctx, correct_time)); \
     620             :                 ret = false; \
     621             :         } \
     622             :         s1 = fname_find(is_ipc, sname); \
     623             :         if (s1 && dos_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
     624             :                 printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
     625             :                        timestring(mem_ctx, s1->stype.out.tfield), \
     626             :                        nt_time_string(mem_ctx, correct_time)); \
     627             :                 ret = false; \
     628             :         }} while (0)
     629             : 
     630             : #if 0 /* unused */
     631             : #define TIME_CHECK_UNX(sname, stype, tfield) do { \
     632             :         s1 = fnum_find(sname); \
     633             :         if (s1 && unx_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
     634             :                 printf("(%d) handle %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
     635             :                        timestring(mem_ctx, s1->stype.out.tfield), \
     636             :                        nt_time_string(mem_ctx, correct_time)); \
     637             :                 ret = false; \
     638             :         } \
     639             :         s1 = fname_find(is_ipc, sname); \
     640             :         if (s1 && unx_nt_time_cmp(s1->stype.out.tfield, correct_time) != 0) { \
     641             :                 printf("(%d) path %s/%s incorrect - %s should be %s\n", __LINE__, #stype, #tfield,  \
     642             :                        timestring(mem_ctx, s1->stype.out.tfield), \
     643             :                        nt_time_string(mem_ctx, correct_time)); \
     644             :                 ret = false; \
     645             :         }} while (0)
     646             : #endif
     647             : 
     648             :         /* now check that all the times that are supposed to be equal are correct */
     649           2 :         s1 = fnum_find("BASIC_INFO");
     650           2 :         correct_time = s1->basic_info.out.create_time;
     651           2 :         torture_comment(torture, "create_time: %s\n", nt_time_string(mem_ctx, correct_time));
     652             : 
     653           2 :         TIME_CHECK_NT ("BASIC_INFO",               basic_info, create_time);
     654           2 :         TIME_CHECK_NT ("BASIC_INFORMATION",        basic_info, create_time);
     655           2 :         TIME_CHECK_DOS("GETATTRE",                 getattre,   create_time);
     656           2 :         TIME_CHECK_DOS("STANDARD",                 standard,   create_time);
     657           2 :         TIME_CHECK_DOS("EA_SIZE",                  ea_size,    create_time);
     658           2 :         TIME_CHECK_NT ("ALL_INFO",                 all_info,   create_time);
     659           2 :         TIME_CHECK_NT ("NETWORK_OPEN_INFORMATION", network_open_information, create_time);
     660             : 
     661           2 :         s1 = fnum_find("BASIC_INFO");
     662           2 :         correct_time = s1->basic_info.out.access_time;
     663           2 :         torture_comment(torture, "access_time: %s\n", nt_time_string(mem_ctx, correct_time));
     664             : 
     665           2 :         TIME_CHECK_NT ("BASIC_INFO",               basic_info, access_time);
     666           2 :         TIME_CHECK_NT ("BASIC_INFORMATION",        basic_info, access_time);
     667           2 :         TIME_CHECK_DOS("GETATTRE",                 getattre,   access_time);
     668           2 :         TIME_CHECK_DOS("STANDARD",                 standard,   access_time);
     669           2 :         TIME_CHECK_DOS("EA_SIZE",                  ea_size,    access_time);
     670           2 :         TIME_CHECK_NT ("ALL_INFO",                 all_info,   access_time);
     671           2 :         TIME_CHECK_NT ("NETWORK_OPEN_INFORMATION", network_open_information, access_time);
     672             : 
     673           2 :         s1 = fnum_find("BASIC_INFO");
     674           2 :         correct_time = s1->basic_info.out.write_time;
     675           2 :         torture_comment(torture, "write_time : %s\n", nt_time_string(mem_ctx, correct_time));
     676             : 
     677           2 :         TIME_CHECK_NT ("BASIC_INFO",               basic_info, write_time);
     678           2 :         TIME_CHECK_NT ("BASIC_INFORMATION",        basic_info, write_time);
     679           2 :         TIME_CHECK_DOS("GETATTR",                  getattr,    write_time);
     680           2 :         TIME_CHECK_DOS("GETATTRE",                 getattre,   write_time);
     681           2 :         TIME_CHECK_DOS("STANDARD",                 standard,   write_time);
     682           2 :         TIME_CHECK_DOS("EA_SIZE",                  ea_size,    write_time);
     683           2 :         TIME_CHECK_NT ("ALL_INFO",                 all_info,   write_time);
     684           2 :         TIME_CHECK_NT ("NETWORK_OPEN_INFORMATION", network_open_information, write_time);
     685             : 
     686           2 :         s1 = fnum_find("BASIC_INFO");
     687           2 :         correct_time = s1->basic_info.out.change_time;
     688           2 :         torture_comment(torture, "change_time: %s\n", nt_time_string(mem_ctx, correct_time));
     689             : 
     690           2 :         TIME_CHECK_NT ("BASIC_INFO",               basic_info, change_time);
     691           2 :         TIME_CHECK_NT ("BASIC_INFORMATION",        basic_info, change_time);
     692           2 :         TIME_CHECK_NT ("ALL_INFO",                 all_info,   change_time);
     693           2 :         TIME_CHECK_NT ("NETWORK_OPEN_INFORMATION", network_open_information, change_time);
     694             : 
     695             : 
     696             : #define SIZE_CHECK(sname, stype, tfield) do { \
     697             :         s1 = fnum_find(sname); \
     698             :         if (s1 && s1->stype.out.tfield != correct_size) { \
     699             :                 printf("(%d) handle %s/%s incorrect - %u should be %u\n", __LINE__, #stype, #tfield,  \
     700             :                        (unsigned int)s1->stype.out.tfield, \
     701             :                        (unsigned int)correct_size); \
     702             :                 ret = false; \
     703             :         } \
     704             :         s1 = fname_find(is_ipc, sname); \
     705             :         if (s1 && s1->stype.out.tfield != correct_size) { \
     706             :                 printf("(%d) path %s/%s incorrect - %u should be %u\n", __LINE__, #stype, #tfield,  \
     707             :                        (unsigned int)s1->stype.out.tfield, \
     708             :                        (unsigned int)correct_size); \
     709             :                 ret = false; \
     710             :         }} while (0)
     711             : 
     712           2 :         s1 = fnum_find("STANDARD_INFO");
     713           2 :         correct_size = s1->standard_info.out.size;
     714           2 :         torture_comment(torture, "size: %u\n", (unsigned int)correct_size);
     715             :         
     716           2 :         SIZE_CHECK("GETATTR",                  getattr,                  size);
     717           2 :         SIZE_CHECK("GETATTRE",                 getattre,                 size);
     718           2 :         SIZE_CHECK("STANDARD",                 standard,                 size);
     719           2 :         SIZE_CHECK("EA_SIZE",                  ea_size,                  size);
     720           2 :         SIZE_CHECK("STANDARD_INFO",            standard_info,            size);
     721           2 :         SIZE_CHECK("STANDARD_INFORMATION",     standard_info,            size);
     722           2 :         SIZE_CHECK("ALL_INFO",                 all_info,                 size);
     723           2 :         SIZE_CHECK("ALL_INFORMATION",          all_info,                 size);
     724           2 :         SIZE_CHECK("COMPRESSION_INFO",         compression_info,         compressed_size);
     725           2 :         SIZE_CHECK("COMPRESSION_INFORMATION",  compression_info,         compressed_size);
     726           2 :         SIZE_CHECK("NETWORK_OPEN_INFORMATION", network_open_information, size);
     727           2 :         if (!skip_streams) {
     728           1 :                 SIZE_CHECK("STREAM_INFO",              stream_info,   streams[0].size);
     729           1 :                 SIZE_CHECK("STREAM_INFORMATION",       stream_info,   streams[0].size);
     730             :         }
     731             : 
     732             : 
     733           2 :         s1 = fnum_find("STANDARD_INFO");
     734           2 :         correct_size = s1->standard_info.out.alloc_size;
     735           2 :         torture_comment(torture, "alloc_size: %u\n", (unsigned int)correct_size);
     736             :         
     737           2 :         SIZE_CHECK("GETATTRE",                 getattre,                 alloc_size);
     738           2 :         SIZE_CHECK("STANDARD",                 standard,                 alloc_size);
     739           2 :         SIZE_CHECK("EA_SIZE",                  ea_size,                  alloc_size);
     740           2 :         SIZE_CHECK("STANDARD_INFO",            standard_info,            alloc_size);
     741           2 :         SIZE_CHECK("STANDARD_INFORMATION",     standard_info,            alloc_size);
     742           2 :         SIZE_CHECK("ALL_INFO",                 all_info,                 alloc_size);
     743           2 :         SIZE_CHECK("ALL_INFORMATION",          all_info,                 alloc_size);
     744           2 :         SIZE_CHECK("NETWORK_OPEN_INFORMATION", network_open_information, alloc_size);
     745           2 :         if (!skip_streams) {
     746           1 :                 SIZE_CHECK("STREAM_INFO",              stream_info,   streams[0].alloc_size);
     747           1 :                 SIZE_CHECK("STREAM_INFORMATION",       stream_info,   streams[0].alloc_size);
     748             :         }
     749             : 
     750             : #define ATTRIB_CHECK(sname, stype, tfield) do { \
     751             :         s1 = fnum_find(sname); \
     752             :         if (s1 && s1->stype.out.tfield != correct_attrib) { \
     753             :                 printf("(%d) handle %s/%s incorrect - 0x%x should be 0x%x\n", __LINE__, #stype, #tfield,  \
     754             :                        (unsigned int)s1->stype.out.tfield, \
     755             :                        (unsigned int)correct_attrib); \
     756             :                 ret = false; \
     757             :         } \
     758             :         s1 = fname_find(is_ipc, sname); \
     759             :         if (s1 && s1->stype.out.tfield != correct_attrib) { \
     760             :                 printf("(%d) path %s/%s incorrect - 0x%x should be 0x%x\n", __LINE__, #stype, #tfield,  \
     761             :                        (unsigned int)s1->stype.out.tfield, \
     762             :                        (unsigned int)correct_attrib); \
     763             :                 ret = false; \
     764             :         }} while (0)
     765             : 
     766           2 :         s1 = fnum_find("BASIC_INFO");
     767           2 :         correct_attrib = s1->basic_info.out.attrib;
     768           2 :         torture_comment(torture, "attrib: 0x%x\n", (unsigned int)correct_attrib);
     769             :         
     770           2 :         ATTRIB_CHECK("GETATTR",                   getattr,                   attrib);
     771           2 :         if (!is_ipc) {
     772           1 :                 ATTRIB_CHECK("GETATTRE",                  getattre,                  attrib);
     773           1 :                 ATTRIB_CHECK("STANDARD",                  standard,                  attrib);
     774           1 :                 ATTRIB_CHECK("EA_SIZE",                   ea_size,                   attrib);
     775             :         }
     776           2 :         ATTRIB_CHECK("BASIC_INFO",                basic_info,                attrib);
     777           2 :         ATTRIB_CHECK("BASIC_INFORMATION",         basic_info,                attrib);
     778           2 :         ATTRIB_CHECK("ALL_INFO",                  all_info,                  attrib);
     779           2 :         ATTRIB_CHECK("ALL_INFORMATION",           all_info,                  attrib);
     780           2 :         ATTRIB_CHECK("NETWORK_OPEN_INFORMATION",  network_open_information,  attrib);
     781           2 :         ATTRIB_CHECK("ATTRIBUTE_TAG_INFORMATION", attribute_tag_information, attrib);
     782             : 
     783           2 :         correct_name = fname;
     784           2 :         torture_comment(torture, "name: %s\n", correct_name);
     785             : 
     786             : #define NAME_CHECK(sname, stype, tfield, flags) do { \
     787             :         s1 = fnum_find(sname); \
     788             :         if (s1 && (strcmp_safe(s1->stype.out.tfield.s, correct_name) != 0 || \
     789             :                         wire_bad_flags(&s1->stype.out.tfield, flags, tree->session->transport))) { \
     790             :                 printf("(%d) handle %s/%s incorrect - '%s/%d'\n", __LINE__, #stype, #tfield,  \
     791             :                        s1->stype.out.tfield.s, s1->stype.out.tfield.private_length); \
     792             :                 ret = false; \
     793             :         } \
     794             :         s1 = fname_find(is_ipc, sname); \
     795             :         if (s1 && (strcmp_safe(s1->stype.out.tfield.s, correct_name) != 0 || \
     796             :                         wire_bad_flags(&s1->stype.out.tfield, flags, tree->session->transport))) { \
     797             :                 printf("(%d) path %s/%s incorrect - '%s/%d'\n", __LINE__, #stype, #tfield,  \
     798             :                        s1->stype.out.tfield.s, s1->stype.out.tfield.private_length); \
     799             :                 ret = false; \
     800             :         }} while (0)
     801             : 
     802           2 :         NAME_CHECK("NAME_INFO",        name_info, fname, STR_UNICODE);
     803           2 :         NAME_CHECK("NAME_INFORMATION", name_info, fname, STR_UNICODE);
     804             : 
     805             :         /* the ALL_INFO file name is the full path on the filesystem */
     806           2 :         s1 = fnum_find("ALL_INFO");
     807           2 :         if (s1 && !s1->all_info.out.fname.s) {
     808           0 :                 torture_fail(torture, "ALL_INFO didn't give a filename");
     809             :         }
     810           2 :         if (s1 && s1->all_info.out.fname.s) {
     811           2 :                 char *p = strrchr(s1->all_info.out.fname.s, '\\');
     812           2 :                 if (!p) {
     813           0 :                         printf("Not a full path in all_info/fname? - '%s'\n", 
     814             :                                s1->all_info.out.fname.s);
     815           0 :                         ret = false;
     816             :                 } else {
     817           2 :                         if (strcmp_safe(correct_name, p) != 0) {
     818           0 :                                 printf("incorrect basename in all_info/fname - '%s'\n",
     819             :                                        s1->all_info.out.fname.s);
     820           0 :                                 ret = false;
     821             :                         }
     822             :                 }
     823           2 :                 if (wire_bad_flags(&s1->all_info.out.fname, STR_UNICODE, tree->session->transport)) {
     824           0 :                         printf("Should not null terminate all_info/fname\n");
     825           0 :                         ret = false;
     826             :                 }
     827             :         }
     828             : 
     829           2 :         s1 = fnum_find("ALT_NAME_INFO");
     830           2 :         if (s1) {
     831           1 :                 correct_name = s1->alt_name_info.out.fname.s;
     832             :         }
     833             : 
     834           2 :         if (!correct_name) {
     835           0 :                 torture_comment(torture, "no alternate name information\n");
     836             :         } else {
     837           2 :                 torture_comment(torture, "alt_name: %s\n", correct_name);
     838             :                 
     839           2 :                 NAME_CHECK("ALT_NAME_INFO",        alt_name_info, fname, STR_UNICODE);
     840           2 :                 NAME_CHECK("ALT_NAME_INFORMATION", alt_name_info, fname, STR_UNICODE);
     841             :                 
     842             :                 /* and make sure we can open by alternate name */
     843           2 :                 smbcli_close(tree, fnum);
     844           2 :                 fnum = smbcli_nt_create_full(tree, correct_name, 0, 
     845             :                                              SEC_RIGHTS_FILE_ALL,
     846             :                                              FILE_ATTRIBUTE_NORMAL,
     847             :                                              NTCREATEX_SHARE_ACCESS_DELETE|
     848             :                                              NTCREATEX_SHARE_ACCESS_READ|
     849             :                                              NTCREATEX_SHARE_ACCESS_WRITE, 
     850             :                                              NTCREATEX_DISP_OVERWRITE_IF, 
     851             :                                              0, 0);
     852           2 :                 if (fnum == -1) {
     853           0 :                         printf("Unable to open by alt_name - %s\n", smbcli_errstr(tree));
     854           0 :                         ret = false;
     855             :                 }
     856             :                 
     857           2 :                 if (!skip_streams) {
     858           1 :                         correct_name = "::$DATA";
     859           1 :                         torture_comment(torture, "stream_name: %s\n", correct_name);
     860             :                         
     861           1 :                         NAME_CHECK("STREAM_INFO",        stream_info, streams[0].stream_name, STR_UNICODE);
     862           1 :                         NAME_CHECK("STREAM_INFORMATION", stream_info, streams[0].stream_name, STR_UNICODE);
     863             :                 }
     864             :         }
     865             :                 
     866             :         /* make sure the EAs look right */
     867           2 :         s1 = fnum_find("ALL_EAS");
     868           2 :         s2 = fnum_find("ALL_INFO");
     869           2 :         if (s1) {
     870           3 :                 for (i=0;i<s1->all_eas.out.num_eas;i++) {
     871           2 :                         printf("  flags=%d %s=%*.*s\n", 
     872           2 :                                s1->all_eas.out.eas[i].flags,
     873           2 :                                s1->all_eas.out.eas[i].name.s,
     874           2 :                                (int)s1->all_eas.out.eas[i].value.length,
     875           2 :                                (int)s1->all_eas.out.eas[i].value.length,
     876           2 :                                s1->all_eas.out.eas[i].value.data);
     877             :                 }
     878             :         }
     879           2 :         if (s1 && s2) {
     880           1 :                 if (s1->all_eas.out.num_eas == 0) {
     881           0 :                         if (s2->all_info.out.ea_size != 0) {
     882           0 :                                 printf("ERROR: num_eas==0 but fnum all_info.out.ea_size == %d\n",
     883             :                                        s2->all_info.out.ea_size);
     884             :                         }
     885             :                 } else {
     886           1 :                         if (s2->all_info.out.ea_size != 
     887           1 :                             ea_list_size(s1->all_eas.out.num_eas, s1->all_eas.out.eas)) {
     888           0 :                                 printf("ERROR: ea_list_size=%d != fnum all_info.out.ea_size=%d\n",
     889           0 :                                        (int)ea_list_size(s1->all_eas.out.num_eas, s1->all_eas.out.eas),
     890           0 :                                        (int)s2->all_info.out.ea_size);
     891             :                         }
     892             :                 }
     893             :         }
     894           2 :         s2 = fname_find(is_ipc, "ALL_EAS");
     895           2 :         if (s2) {
     896           1 :                 VAL_EQUAL(all_eas, num_eas, all_eas, num_eas);
     897           3 :                 for (i=0;i<s1->all_eas.out.num_eas;i++) {
     898           2 :                         VAL_EQUAL(all_eas, eas[i].flags, all_eas, eas[i].flags);
     899           2 :                         STR_EQUAL(all_eas, eas[i].name, all_eas, eas[i].name);
     900           2 :                         VAL_EQUAL(all_eas, eas[i].value.length, all_eas, eas[i].value.length);
     901             :                 }
     902             :         }
     903             : 
     904             : #define VAL_CHECK(sname1, stype1, tfield1, sname2, stype2, tfield2) do { \
     905             :         s1 = fnum_find(sname1); s2 = fnum_find(sname2); \
     906             :         if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
     907             :                 printf("(%d) handle %s/%s != %s/%s - 0x%x vs 0x%x\n", __LINE__, \
     908             :                        #stype1, #tfield1, #stype2, #tfield2,  \
     909             :                        s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
     910             :                 ret = false; \
     911             :         } \
     912             :         s1 = fname_find(is_ipc, sname1); s2 = fname_find(is_ipc, sname2); \
     913             :         if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
     914             :                 printf("(%d) path %s/%s != %s/%s - 0x%x vs 0x%x\n", __LINE__, \
     915             :                        #stype1, #tfield1, #stype2, #tfield2,  \
     916             :                        s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
     917             :                 ret = false; \
     918             :         } \
     919             :         s1 = fnum_find(sname1); s2 = fname_find(is_ipc, sname2); \
     920             :         if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
     921             :                 printf("(%d) handle %s/%s != path %s/%s - 0x%x vs 0x%x\n", __LINE__, \
     922             :                        #stype1, #tfield1, #stype2, #tfield2,  \
     923             :                        s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
     924             :                 ret = false; \
     925             :         } \
     926             :         s1 = fname_find(is_ipc, sname1); s2 = fnum_find(sname2); \
     927             :         if (s1 && s2 && s1->stype1.out.tfield1 != s2->stype2.out.tfield2) { \
     928             :                 printf("(%d) path %s/%s != handle %s/%s - 0x%x vs 0x%x\n", __LINE__, \
     929             :                        #stype1, #tfield1, #stype2, #tfield2,  \
     930             :                        s1->stype1.out.tfield1, s2->stype2.out.tfield2); \
     931             :                 ret = false; \
     932             :         }} while (0)
     933             : 
     934           2 :         VAL_CHECK("STANDARD_INFO", standard_info, delete_pending, 
     935             :                   "ALL_INFO",      all_info,      delete_pending);
     936           2 :         VAL_CHECK("STANDARD_INFO", standard_info, directory, 
     937             :                   "ALL_INFO",      all_info,      directory);
     938           2 :         VAL_CHECK("STANDARD_INFO", standard_info, nlink, 
     939             :                   "ALL_INFO",      all_info,      nlink);
     940           2 :         s1 = fnum_find("BASIC_INFO");
     941           2 :         if (s1 && is_ipc) {
     942           1 :                 if (s1->basic_info.out.attrib != FILE_ATTRIBUTE_NORMAL) {
     943           0 :                         printf("(%d) attrib basic_info/nlink incorrect - %d should be %d\n", __LINE__, s1->basic_info.out.attrib, (int)FILE_ATTRIBUTE_NORMAL);
     944           0 :                         ret = false;
     945             :                 }
     946             :         }
     947           2 :         s1 = fnum_find("STANDARD_INFO");
     948           2 :         if (s1 && is_ipc) {
     949           1 :                 if (s1->standard_info.out.nlink != 1) {
     950           0 :                         printf("(%d) nlinks standard_info/nlink incorrect - %d should be 1\n", __LINE__, s1->standard_info.out.nlink);
     951           0 :                         ret = false;
     952             :                 }
     953           1 :                 if (s1->standard_info.out.delete_pending != 1) {
     954           0 :                         printf("(%d) nlinks standard_info/delete_pending incorrect - %d should be 1\n", __LINE__, s1->standard_info.out.delete_pending);
     955           0 :                         ret = false;
     956             :                 }
     957             :         }
     958           2 :         VAL_CHECK("EA_INFO",       ea_info,       ea_size, 
     959             :                   "ALL_INFO",      all_info,      ea_size);
     960           2 :         if (!is_ipc) {
     961           1 :                 VAL_CHECK("EA_SIZE",       ea_size,       ea_size, 
     962             :                           "ALL_INFO",      all_info,      ea_size);
     963             :         }
     964             : 
     965             : #define NAME_PATH_CHECK(sname, stype, field) do { \
     966             :         s1 = fname_find(is_ipc, sname); s2 = fnum_find(sname); \
     967             :         if (s1 && s2) { \
     968             :                 VAL_EQUAL(stype, field, stype, field); \
     969             :         } \
     970             : } while (0)
     971             : 
     972             : 
     973           2 :         s1 = fnum_find("INTERNAL_INFORMATION");
     974           2 :         if (s1) {
     975           2 :                 torture_comment(torture, "file_id=%.0f\n", (double)s1->internal_information.out.file_id);
     976             :         }
     977             : 
     978           2 :         NAME_PATH_CHECK("INTERNAL_INFORMATION", internal_information, file_id);
     979           2 :         NAME_PATH_CHECK("POSITION_INFORMATION", position_information, position);
     980           2 :         if (s1 && s2) {
     981           1 :                 printf("fnum pos = %.0f, fname pos = %.0f\n",
     982           1 :                        (double)s2->position_information.out.position,
     983           1 :                        (double)s1->position_information.out.position );
     984             :         }
     985           2 :         NAME_PATH_CHECK("MODE_INFORMATION", mode_information, mode);
     986           2 :         NAME_PATH_CHECK("ALIGNMENT_INFORMATION", alignment_information, alignment_requirement);
     987           2 :         NAME_PATH_CHECK("ATTRIBUTE_TAG_INFORMATION", attribute_tag_information, attrib);
     988           2 :         NAME_PATH_CHECK("ATTRIBUTE_TAG_INFORMATION", attribute_tag_information, reparse_tag);
     989             : 
     990             : #if 0
     991             :         /* these are expected to differ */
     992             :         NAME_PATH_CHECK("ACCESS_INFORMATION", access_information, access_flags);
     993             : #endif
     994             : 
     995             : #if 0 /* unused */
     996             : #define UNKNOWN_CHECK(sname, stype, tfield) do { \
     997             :         s1 = fnum_find(sname); \
     998             :         if (s1 && s1->stype.out.tfield != 0) { \
     999             :                 printf("(%d) handle %s/%s unknown != 0 (0x%x)\n", __LINE__, \
    1000             :                        #stype, #tfield, \
    1001             :                        (unsigned int)s1->stype.out.tfield); \
    1002             :         } \
    1003             :         s1 = fname_find(is_ipc, sname); \
    1004             :         if (s1 && s1->stype.out.tfield != 0) { \
    1005             :                 printf("(%d) path %s/%s unknown != 0 (0x%x)\n", __LINE__, \
    1006             :                        #stype, #tfield, \
    1007             :                        (unsigned int)s1->stype.out.tfield); \
    1008             :         }} while (0)
    1009             : #endif
    1010             :         /* now get a bit fancier .... */
    1011             :         
    1012             :         /* when we set the delete disposition then the link count should drop
    1013             :            to 0 and delete_pending should be 1 */
    1014             :         
    1015           2 :         return ret;
    1016             : }
    1017             : 
    1018             : /* basic testing of all RAW_FILEINFO_* calls 
    1019             :    for each call we test that it succeeds, and where possible test 
    1020             :    for consistency between the calls. 
    1021             : */
    1022           1 : bool torture_raw_qfileinfo(struct torture_context *torture, 
    1023             :                                                    struct smbcli_state *cli)
    1024             : {
    1025           0 :         int fnum;
    1026           0 :         bool ret;
    1027           1 :         const char *fname = "\\torture_qfileinfo.txt";
    1028             : 
    1029           1 :         fnum = create_complex_file(cli, torture, fname);
    1030           1 :         if (fnum == -1) {
    1031           0 :                 printf("ERROR: open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
    1032           0 :                 return false;
    1033             :         }
    1034             : 
    1035           1 :         ret = torture_raw_qfileinfo_internals(torture, torture, cli->tree, fnum, fname, false /* is_ipc */);
    1036             :         
    1037           1 :         smbcli_close(cli->tree, fnum);
    1038           1 :         smbcli_unlink(cli->tree, fname);
    1039             : 
    1040           1 :         return ret;
    1041             : }
    1042             : 
    1043           1 : bool torture_raw_qfileinfo_pipe(struct torture_context *torture, 
    1044             :                                 struct smbcli_state *cli)
    1045             : {
    1046           1 :         bool ret = true;
    1047           0 :         int fnum;
    1048           1 :         const char *fname = "\\lsass";
    1049           0 :         union smb_open op;
    1050           0 :         NTSTATUS status;
    1051             : 
    1052           1 :         op.ntcreatex.level = RAW_OPEN_NTCREATEX;
    1053           1 :         op.ntcreatex.in.flags = 0;
    1054           1 :         op.ntcreatex.in.root_fid.fnum = 0;
    1055           1 :         op.ntcreatex.in.access_mask =
    1056             :                 SEC_STD_READ_CONTROL |
    1057             :                 SEC_FILE_WRITE_ATTRIBUTE |
    1058             :                 SEC_FILE_WRITE_EA |
    1059             :                 SEC_FILE_READ_DATA |
    1060             :                 SEC_FILE_WRITE_DATA;
    1061           1 :         op.ntcreatex.in.file_attr = 0;
    1062           1 :         op.ntcreatex.in.alloc_size = 0;
    1063           1 :         op.ntcreatex.in.share_access =
    1064             :                 NTCREATEX_SHARE_ACCESS_READ |
    1065             :                 NTCREATEX_SHARE_ACCESS_WRITE;
    1066           1 :         op.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
    1067           1 :         op.ntcreatex.in.create_options = 0;
    1068           1 :         op.ntcreatex.in.impersonation =
    1069             :                 NTCREATEX_IMPERSONATION_IMPERSONATION;
    1070           1 :         op.ntcreatex.in.security_flags = 0;
    1071           1 :         op.ntcreatex.in.fname = fname;
    1072             : 
    1073           1 :         status = smb_raw_open(cli->tree, torture, &op);
    1074           1 :         torture_assert_ntstatus_ok(torture, status, "smb_raw_open failed");
    1075             : 
    1076           1 :         fnum = op.ntcreatex.out.file.fnum;
    1077             : 
    1078           1 :         ret = torture_raw_qfileinfo_internals(torture, torture, cli->tree,
    1079             :                                               fnum, fname,
    1080             :                                               true /* is_ipc */);
    1081             : 
    1082           1 :         smbcli_close(cli->tree, fnum);
    1083           1 :         return ret;
    1084             : }

Generated by: LCOV version 1.14