LCOV - code coverage report
Current view: top level - source3/torture - test_posix.c (source / functions) Hit Total Coverage
Test: coverage report for recycleplus df22b230 Lines: 0 857 0.0 %
Date: 2024-02-14 10:14:15 Functions: 0 15 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Copyright (C) Ralph Boehme 2020
       4             : 
       5             :    This program is free software; you can redistribute it and/or modify
       6             :    it under the terms of the GNU General Public License as published by
       7             :    the Free Software Foundation; either version 3 of the License, or
       8             :    (at your option) any later version.
       9             : 
      10             :    This program is distributed in the hope that it will be useful,
      11             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             :    GNU General Public License for more details.
      14             : 
      15             :    You should have received a copy of the GNU General Public License
      16             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      17             : */
      18             : 
      19             : #include "includes.h"
      20             : #include "torture/proto.h"
      21             : #include "libcli/security/security.h"
      22             : #include "libsmb/libsmb.h"
      23             : #include "libsmb/clirap.h"
      24             : #include "libsmb/proto.h"
      25             : #include "../libcli/smb/smbXcli_base.h"
      26             : #include "util_sd.h"
      27             : #include "trans2.h"
      28             : 
      29             : extern struct cli_credentials *torture_creds;
      30             : extern fstring host, workgroup, share, password, username, myname;
      31             : 
      32             : struct posix_test_entry {
      33             :         const char *name;
      34             :         const char *target;
      35             :         const char *expected;
      36             :         uint32_t attr;
      37             :         uint64_t returned_size;
      38             :         bool ok;
      39             : };
      40             : 
      41           0 : static NTSTATUS posix_ls_fn(struct file_info *finfo,
      42             :                             const char *name,
      43             :                             void *_state)
      44             : {
      45           0 :         struct posix_test_entry *state =
      46             :                 (struct posix_test_entry *)_state;
      47             : 
      48           0 :         for (; state->name != NULL; state++) {
      49           0 :                 if (strequal(finfo->name, state->expected)) {
      50           0 :                         if (state->attr != finfo->attr) {
      51           0 :                                 break;
      52             :                         }
      53           0 :                         state->ok = true;
      54           0 :                         state->returned_size = finfo->size;
      55           0 :                         break;
      56             :                 }
      57             :         }
      58             : 
      59           0 :         return NT_STATUS_OK;
      60             : }
      61             : 
      62           0 : static void posix_test_entries_reset(struct posix_test_entry *state)
      63             : {
      64           0 :         for (; state->name != NULL; state++) {
      65           0 :                 state->ok = false;
      66           0 :                 state->returned_size = 0;
      67             :         }
      68           0 : }
      69             : 
      70           0 : static bool posix_test_entry_check(struct posix_test_entry *state,
      71             :                                    const char *name,
      72             :                                    bool expected,
      73             :                                    uint64_t expected_size)
      74             : {
      75           0 :         bool result = false;
      76             : 
      77           0 :         for (; state->name != NULL; state++) {
      78           0 :                 if (strequal(name, state->name)) {
      79           0 :                         result = state->ok;
      80           0 :                         break;
      81             :                 }
      82             :         }
      83           0 :         if (state->name == NULL) {
      84           0 :                 printf("test failed, unknown name: %s\n", name);
      85           0 :                 return false;
      86             :         }
      87             : 
      88           0 :         if (expected == result) {
      89           0 :                 return true;
      90             :         }
      91             : 
      92           0 :         printf("test failed, %s: %s\n",
      93             :                expected ? "missing" : "unexpected",
      94             :                name);
      95             : 
      96           0 :         return false;
      97             : }
      98             : 
      99             : /*
     100             :   Test non-POSIX vs POSIX ls * of symlinks
     101             :  */
     102           0 : bool run_posix_ls_wildcard_test(int dummy)
     103             : {
     104           0 :         TALLOC_CTX *frame = NULL;
     105           0 :         struct cli_state *cli_unix = NULL;
     106           0 :         struct cli_state *cli_win = NULL;
     107           0 :         uint16_t fnum = (uint16_t)-1;
     108             :         NTSTATUS status;
     109           0 :         const char *file = "file";
     110           0 :         const char *symlnk_dangling = "dangling";
     111           0 :         const char *symlnk_dst_dangling = "xxxxxxx";
     112           0 :         const char *symlnk_in_share = "symlnk_in_share";
     113           0 :         const char *symlnk_dst_in_share = file;
     114           0 :         const char *symlnk_outside_share = "symlnk_outside_share";
     115           0 :         const char *symlnk_dst_outside_share = "/etc/passwd";
     116           0 :         struct posix_test_entry state[] = {
     117             :                 {
     118             :                         .name = symlnk_dangling,
     119             :                         .target = symlnk_dst_dangling,
     120             :                         .expected = symlnk_dangling,
     121             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     122             :                 }, {
     123             :                         .name = symlnk_in_share,
     124             :                         .target = symlnk_dst_in_share,
     125             :                         .expected = symlnk_in_share,
     126             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     127             :                 }, {
     128             :                         .name = symlnk_outside_share,
     129             :                         .target = symlnk_dst_outside_share,
     130             :                         .expected = symlnk_outside_share,
     131             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     132             :                 }, {
     133             :                         .name = NULL,
     134             :                 }
     135             :         };
     136             :         int i;
     137           0 :         bool correct = false;
     138             : 
     139           0 :         frame = talloc_stackframe();
     140             : 
     141           0 :         printf("Starting POSIX-LS-WILDCARD test\n");
     142             : 
     143           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     144           0 :                 TALLOC_FREE(frame);
     145           0 :                 return false;
     146             :         }
     147             : 
     148           0 :         if (!torture_open_connection(&cli_win, 0)) {
     149           0 :                 TALLOC_FREE(frame);
     150           0 :                 return false;
     151             :         }
     152             : 
     153           0 :         torture_conn_set_sockopt(cli_unix);
     154           0 :         torture_conn_set_sockopt(cli_win);
     155             : 
     156           0 :         status = torture_setup_unix_extensions(cli_unix);
     157           0 :         if (!NT_STATUS_IS_OK(status)) {
     158           0 :                 TALLOC_FREE(frame);
     159           0 :                 return false;
     160             :         }
     161             : 
     162           0 :         cli_posix_unlink(cli_unix, file);
     163           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     164           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     165           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     166             : 
     167           0 :         status = cli_posix_open(cli_unix,
     168             :                                 file,
     169             :                                 O_RDWR|O_CREAT,
     170             :                                 0666,
     171             :                                 &fnum);
     172           0 :         if (!NT_STATUS_IS_OK(status)) {
     173           0 :                 printf("cli_posix_open of %s failed error %s\n",
     174             :                        file,
     175             :                        nt_errstr(status));
     176           0 :                 goto out;
     177             :         }
     178             : 
     179           0 :         status = cli_close(cli_unix, fnum);
     180           0 :         if (!NT_STATUS_IS_OK(status)) {
     181           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     182           0 :                 goto out;
     183             :         }
     184           0 :         fnum = (uint16_t)-1;
     185             : 
     186           0 :         for (i = 0; state[i].name != NULL; i++) {
     187           0 :                 status = cli_posix_symlink(cli_unix,
     188             :                                            state[i].target,
     189             :                                            state[i].name);
     190           0 :                 if (!NT_STATUS_IS_OK(status)) {
     191           0 :                         printf("POSIX symlink of %s failed (%s)\n",
     192             :                                symlnk_dangling, nt_errstr(status));
     193           0 :                         goto out;
     194             :                 }
     195             :         }
     196             : 
     197           0 :         printf("Doing Windows ls *\n");
     198             : 
     199           0 :         status = cli_list(cli_win, "*", 0, posix_ls_fn, state);
     200           0 :         if (!NT_STATUS_IS_OK(status)) {
     201           0 :                 printf("cli_list failed %s\n", nt_errstr(status));
     202           0 :                 goto out;
     203             :         }
     204             : 
     205           0 :         if (!posix_test_entry_check(state, symlnk_dangling, false, 0)) {
     206           0 :                 goto out;
     207             :         }
     208           0 :         if (!posix_test_entry_check(state, symlnk_outside_share, false, 0)) {
     209           0 :                 goto out;
     210             :         }
     211           0 :         if (!posix_test_entry_check(state, symlnk_in_share, true, 0)) {
     212           0 :                 goto out;
     213             :         }
     214             : 
     215           0 :         posix_test_entries_reset(state);
     216             : 
     217           0 :         printf("Doing POSIX ls *\n");
     218             : 
     219           0 :         status = cli_list(cli_unix, "*", 0, posix_ls_fn, state);
     220           0 :         if (!NT_STATUS_IS_OK(status)) {
     221           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     222           0 :                 goto out;
     223             :         }
     224             : 
     225           0 :         if (!posix_test_entry_check(state,
     226             :                                     symlnk_dangling,
     227             :                                     true,
     228             :                                     strlen(symlnk_dst_dangling)))
     229             :         {
     230           0 :                 goto out;
     231             :         }
     232           0 :         if (!posix_test_entry_check(state,
     233             :                                     symlnk_outside_share,
     234             :                                     true,
     235             :                                     strlen(symlnk_dst_outside_share)))
     236             :         {
     237           0 :                 goto out;
     238             :         }
     239           0 :         if (!posix_test_entry_check(state,
     240             :                                     symlnk_in_share,
     241             :                                     true,
     242             :                                     strlen(symlnk_dst_in_share))) {
     243           0 :                 goto out;
     244             :         }
     245             : 
     246           0 :         printf("POSIX-LS-WILDCARD test passed\n");
     247           0 :         correct = true;
     248             : 
     249           0 : out:
     250           0 :         cli_posix_unlink(cli_unix, file);
     251           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     252           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     253           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     254             : 
     255           0 :         if (!torture_close_connection(cli_unix)) {
     256           0 :                 correct = false;
     257             :         }
     258           0 :         if (!torture_close_connection(cli_win)) {
     259           0 :                 correct = false;
     260             :         }
     261             : 
     262           0 :         TALLOC_FREE(frame);
     263           0 :         return correct;
     264             : }
     265             : 
     266             : /*
     267             :   Test non-POSIX vs POSIX ls single of symlinks
     268             :  */
     269           0 : bool run_posix_ls_single_test(int dummy)
     270             : {
     271           0 :         TALLOC_CTX *frame = NULL;
     272           0 :         struct cli_state *cli_unix = NULL;
     273           0 :         struct cli_state *cli_win = NULL;
     274           0 :         uint16_t fnum = (uint16_t)-1;
     275             :         NTSTATUS status;
     276           0 :         const char *file = "file";
     277           0 :         const char *symlnk_dangling = "dangling";
     278           0 :         const char *symlnk_dst_dangling = "xxxxxxx";
     279           0 :         const char *symlnk_in_share = "symlnk_in_share";
     280           0 :         const char *symlnk_dst_in_share = file;
     281           0 :         const char *symlnk_outside_share = "symlnk_outside_share";
     282           0 :         const char *symlnk_dst_outside_share = "/etc/passwd";
     283           0 :         struct posix_test_entry state[] = {
     284             :                 {
     285             :                         .name = symlnk_dangling,
     286             :                         .target = symlnk_dst_dangling,
     287             :                         .expected = symlnk_dangling,
     288             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     289             :                 }, {
     290             :                         .name = symlnk_in_share,
     291             :                         .target = symlnk_dst_in_share,
     292             :                         .expected = symlnk_in_share,
     293             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     294             :                 }, {
     295             :                         .name = symlnk_outside_share,
     296             :                         .target = symlnk_dst_outside_share,
     297             :                         .expected = symlnk_outside_share,
     298             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     299             :                 }, {
     300             :                         .name = NULL,
     301             :                 }
     302             :         };
     303             :         int i;
     304           0 :         bool correct = false;
     305             : 
     306           0 :         frame = talloc_stackframe();
     307             : 
     308           0 :         printf("Starting POSIX-LS-SINGLE test\n");
     309             : 
     310           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     311           0 :                 TALLOC_FREE(frame);
     312           0 :                 return false;
     313             :         }
     314             : 
     315           0 :         if (!torture_init_connection(&cli_win)) {
     316           0 :                 TALLOC_FREE(frame);
     317           0 :                 return false;
     318             :         }
     319             : 
     320           0 :         status = smbXcli_negprot(cli_win->conn,
     321           0 :                                  cli_win->timeout,
     322           0 :                                  lp_client_min_protocol(),
     323           0 :                                  lp_client_max_protocol());
     324           0 :         if (!NT_STATUS_IS_OK(status)) {
     325           0 :                 printf("smbXcli_negprot returned %s\n", nt_errstr(status));
     326           0 :                 TALLOC_FREE(frame);
     327           0 :                 return false;
     328             :         }
     329             : 
     330           0 :         status = cli_session_setup_creds(cli_win, torture_creds);
     331           0 :         if (!NT_STATUS_IS_OK(status)) {
     332           0 :                 printf("smb2cli_sesssetup returned %s\n", nt_errstr(status));
     333           0 :                 TALLOC_FREE(frame);
     334           0 :                 return false;
     335             :         }
     336             : 
     337           0 :         status = cli_tree_connect(cli_win, share, "?????", NULL);
     338           0 :         if (!NT_STATUS_IS_OK(status)) {
     339           0 :                 printf("cli_tree_connect returned %s\n", nt_errstr(status));
     340           0 :                 TALLOC_FREE(frame);
     341           0 :                 return false;
     342             :         }
     343           0 :         torture_conn_set_sockopt(cli_unix);
     344           0 :         torture_conn_set_sockopt(cli_win);
     345             : 
     346           0 :         status = torture_setup_unix_extensions(cli_unix);
     347           0 :         if (!NT_STATUS_IS_OK(status)) {
     348           0 :                 TALLOC_FREE(frame);
     349           0 :                 return false;
     350             :         }
     351             : 
     352           0 :         cli_posix_unlink(cli_unix, file);
     353           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     354           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     355           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     356             : 
     357           0 :         status = cli_posix_open(cli_unix,
     358             :                                 file,
     359             :                                 O_RDWR|O_CREAT,
     360             :                                 0666,
     361             :                                 &fnum);
     362           0 :         if (!NT_STATUS_IS_OK(status)) {
     363           0 :                 printf("cli_posix_open of %s failed error %s\n",
     364             :                        file,
     365             :                        nt_errstr(status));
     366           0 :                 goto out;
     367             :         }
     368             : 
     369           0 :         status = cli_close(cli_unix, fnum);
     370           0 :         if (!NT_STATUS_IS_OK(status)) {
     371           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     372           0 :                 goto out;
     373             :         }
     374           0 :         fnum = (uint16_t)-1;
     375             : 
     376           0 :         for (i = 0; state[i].name != NULL; i++) {
     377           0 :                 status = cli_posix_symlink(cli_unix,
     378             :                                            state[i].target,
     379             :                                            state[i].name);
     380           0 :                 if (!NT_STATUS_IS_OK(status)) {
     381           0 :                         printf("POSIX symlink of %s failed (%s)\n",
     382             :                                symlnk_dangling, nt_errstr(status));
     383           0 :                         goto out;
     384             :                 }
     385             :         }
     386             : 
     387           0 :         printf("Doing Windows ls single\n");
     388             : 
     389           0 :         cli_list(cli_win, symlnk_dangling, 0, posix_ls_fn, state);
     390           0 :         cli_list(cli_win, symlnk_outside_share, 0, posix_ls_fn, state);
     391           0 :         cli_list(cli_win, symlnk_in_share, 0, posix_ls_fn, state);
     392             : 
     393           0 :         if (!posix_test_entry_check(state, symlnk_dangling, false, 0)) {
     394           0 :                 goto out;
     395             :         }
     396           0 :         if (!posix_test_entry_check(state, symlnk_outside_share, false, 0)) {
     397           0 :                 goto out;
     398             :         }
     399           0 :         if (!posix_test_entry_check(state, symlnk_in_share, true, 0)) {
     400           0 :                 goto out;
     401             :         }
     402             : 
     403           0 :         posix_test_entries_reset(state);
     404             : 
     405           0 :         printf("Doing POSIX ls single\n");
     406             : 
     407           0 :         cli_list(cli_unix, symlnk_dangling, 0, posix_ls_fn, state);
     408           0 :         cli_list(cli_unix, symlnk_outside_share, 0, posix_ls_fn, state);
     409           0 :         cli_list(cli_unix, symlnk_in_share, 0, posix_ls_fn, state);
     410             : 
     411           0 :         if (!posix_test_entry_check(state,
     412             :                                     symlnk_dangling,
     413             :                                     true,
     414             :                                     strlen(symlnk_dst_dangling)))
     415             :         {
     416           0 :                 goto out;
     417             :         }
     418           0 :         if (!posix_test_entry_check(state,
     419             :                                     symlnk_outside_share,
     420             :                                     true,
     421             :                                     strlen(symlnk_dst_outside_share)))
     422             :         {
     423           0 :                 goto out;
     424             :         }
     425           0 :         if (!posix_test_entry_check(state,
     426             :                                     symlnk_in_share,
     427             :                                     true,
     428             :                                     strlen(symlnk_dst_in_share))) {
     429           0 :                 goto out;
     430             :         }
     431             : 
     432           0 :         printf("POSIX-LS-SINGLE test passed\n");
     433           0 :         correct = true;
     434             : 
     435           0 : out:
     436           0 :         cli_posix_unlink(cli_unix, file);
     437           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     438           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     439           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     440             : 
     441           0 :         if (!torture_close_connection(cli_unix)) {
     442           0 :                 correct = false;
     443             :         }
     444           0 :         if (!torture_close_connection(cli_win)) {
     445           0 :                 correct = false;
     446             :         }
     447             : 
     448           0 :         TALLOC_FREE(frame);
     449           0 :         return correct;
     450             : }
     451             : 
     452             : /*
     453             :   Test POSIX readlink of symlinks
     454             :  */
     455           0 : bool run_posix_readlink_test(int dummy)
     456             : {
     457           0 :         TALLOC_CTX *frame = NULL;
     458           0 :         struct cli_state *cli_unix = NULL;
     459           0 :         uint16_t fnum = (uint16_t)-1;
     460             :         NTSTATUS status;
     461           0 :         const char *file = "file";
     462           0 :         const char *symlnk_dangling = "dangling";
     463           0 :         const char *symlnk_dst_dangling = "xxxxxxx";
     464           0 :         const char *symlnk_in_share = "symlnk_in_share";
     465           0 :         const char *symlnk_dst_in_share = file;
     466           0 :         const char *symlnk_outside_share = "symlnk_outside_share";
     467           0 :         const char *symlnk_dst_outside_share = "/etc/passwd";
     468           0 :         struct posix_test_entry state[] = {
     469             :                 {
     470             :                         .name = symlnk_dangling,
     471             :                         .target = symlnk_dst_dangling,
     472             :                         .expected = symlnk_dangling,
     473             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     474             :                 }, {
     475             :                         .name = symlnk_in_share,
     476             :                         .target = symlnk_dst_in_share,
     477             :                         .expected = symlnk_in_share,
     478             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     479             :                 }, {
     480             :                         .name = symlnk_outside_share,
     481             :                         .target = symlnk_dst_outside_share,
     482             :                         .expected = symlnk_outside_share,
     483             :                         .attr = FILE_ATTRIBUTE_NORMAL,
     484             :                 }, {
     485             :                         .name = NULL,
     486             :                 }
     487             :         };
     488             :         int i;
     489           0 :         bool correct = false;
     490             : 
     491           0 :         frame = talloc_stackframe();
     492             : 
     493           0 :         printf("Starting POSIX-READLINK test\n");
     494             : 
     495           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     496           0 :                 TALLOC_FREE(frame);
     497           0 :                 return false;
     498             :         }
     499             : 
     500           0 :         torture_conn_set_sockopt(cli_unix);
     501             : 
     502           0 :         status = torture_setup_unix_extensions(cli_unix);
     503           0 :         if (!NT_STATUS_IS_OK(status)) {
     504           0 :                 TALLOC_FREE(frame);
     505           0 :                 return false;
     506             :         }
     507             : 
     508           0 :         cli_posix_unlink(cli_unix, file);
     509           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     510           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     511           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     512             : 
     513           0 :         status = cli_posix_open(cli_unix,
     514             :                                 file,
     515             :                                 O_RDWR|O_CREAT,
     516             :                                 0666,
     517             :                                 &fnum);
     518           0 :         if (!NT_STATUS_IS_OK(status)) {
     519           0 :                 printf("cli_posix_open of %s failed error %s\n",
     520             :                        file,
     521             :                        nt_errstr(status));
     522           0 :                 goto out;
     523             :         }
     524             : 
     525           0 :         status = cli_close(cli_unix, fnum);
     526           0 :         if (!NT_STATUS_IS_OK(status)) {
     527           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     528           0 :                 goto out;
     529             :         }
     530           0 :         fnum = (uint16_t)-1;
     531             : 
     532           0 :         for (i = 0; state[i].name != NULL; i++) {
     533           0 :                 status = cli_posix_symlink(cli_unix,
     534             :                                            state[i].target,
     535             :                                            state[i].name);
     536           0 :                 if (!NT_STATUS_IS_OK(status)) {
     537           0 :                         printf("POSIX symlink of %s failed (%s)\n",
     538             :                                symlnk_dangling, nt_errstr(status));
     539           0 :                         goto out;
     540             :                 }
     541             :         }
     542             : 
     543           0 :         for (i = 0; state[i].name != NULL; i++) {
     544           0 :                 char *target = NULL;
     545             : 
     546           0 :                 status = cli_readlink(
     547             :                         cli_unix,
     548             :                         state[i].name,
     549             :                         talloc_tos(),
     550             :                         &target,
     551             :                         NULL,
     552             :                         NULL);
     553           0 :                 if (!NT_STATUS_IS_OK(status)) {
     554           0 :                         printf("POSIX readlink on %s failed (%s)\n",
     555             :                                state[i].name, nt_errstr(status));
     556           0 :                         goto out;
     557             :                 }
     558           0 :                 if (strequal(target, state[i].target)) {
     559           0 :                         state[i].ok = true;
     560           0 :                         state[i].returned_size = strlen(target);
     561             :                 }
     562             :         }
     563             : 
     564           0 :         if (!posix_test_entry_check(state,
     565             :                                     symlnk_dangling,
     566             :                                     true,
     567             :                                     strlen(symlnk_dst_dangling)))
     568             :         {
     569           0 :                 goto out;
     570             :         }
     571           0 :         if (!posix_test_entry_check(state,
     572             :                                     symlnk_outside_share,
     573             :                                     true,
     574             :                                     strlen(symlnk_dst_outside_share)))
     575             :         {
     576           0 :                 goto out;
     577             :         }
     578           0 :         if (!posix_test_entry_check(state,
     579             :                                     symlnk_in_share,
     580             :                                     true,
     581             :                                     strlen(symlnk_dst_in_share))) {
     582           0 :                 goto out;
     583             :         }
     584             : 
     585           0 :         printf("POSIX-READLINK test passed\n");
     586           0 :         correct = true;
     587             : 
     588           0 : out:
     589           0 :         cli_posix_unlink(cli_unix, file);
     590           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     591           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     592           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     593             : 
     594           0 :         if (!torture_close_connection(cli_unix)) {
     595           0 :                 correct = false;
     596             :         }
     597             : 
     598           0 :         TALLOC_FREE(frame);
     599           0 :         return correct;
     600             : }
     601             : 
     602             : /*
     603             :   Test POSIX stat of symlinks
     604             :  */
     605           0 : bool run_posix_stat_test(int dummy)
     606             : {
     607           0 :         TALLOC_CTX *frame = NULL;
     608           0 :         struct cli_state *cli_unix = NULL;
     609           0 :         uint16_t fnum = (uint16_t)-1;
     610             :         NTSTATUS status;
     611           0 :         const char *file = "file";
     612           0 :         const char *symlnk_dangling = "dangling";
     613           0 :         const char *symlnk_dst_dangling = "xxxxxxx";
     614           0 :         const char *symlnk_in_share = "symlnk_in_share";
     615           0 :         const char *symlnk_dst_in_share = file;
     616           0 :         const char *symlnk_outside_share = "symlnk_outside_share";
     617           0 :         const char *symlnk_dst_outside_share = "/etc/passwd";
     618           0 :         struct posix_test_entry state[] = {
     619             :                 {
     620             :                         .name = symlnk_dangling,
     621             :                         .target = symlnk_dst_dangling,
     622             :                         .expected = symlnk_dangling,
     623             :                 }, {
     624             :                         .name = symlnk_in_share,
     625             :                         .target = symlnk_dst_in_share,
     626             :                         .expected = symlnk_in_share,
     627             :                 }, {
     628             :                         .name = symlnk_outside_share,
     629             :                         .target = symlnk_dst_outside_share,
     630             :                         .expected = symlnk_outside_share,
     631             :                 }, {
     632             :                         .name = NULL,
     633             :                 }
     634             :         };
     635             :         int i;
     636           0 :         bool correct = false;
     637             : 
     638           0 :         frame = talloc_stackframe();
     639             : 
     640           0 :         printf("Starting POSIX-STAT test\n");
     641             : 
     642           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     643           0 :                 TALLOC_FREE(frame);
     644           0 :                 return false;
     645             :         }
     646             : 
     647           0 :         torture_conn_set_sockopt(cli_unix);
     648             : 
     649           0 :         status = torture_setup_unix_extensions(cli_unix);
     650           0 :         if (!NT_STATUS_IS_OK(status)) {
     651           0 :                 TALLOC_FREE(frame);
     652           0 :                 return false;
     653             :         }
     654             : 
     655           0 :         cli_posix_unlink(cli_unix, file);
     656           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     657           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     658           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     659             : 
     660           0 :         status = cli_posix_open(cli_unix,
     661             :                                 file,
     662             :                                 O_RDWR|O_CREAT,
     663             :                                 0666,
     664             :                                 &fnum);
     665           0 :         if (!NT_STATUS_IS_OK(status)) {
     666           0 :                 printf("cli_posix_open of %s failed error %s\n",
     667             :                        file,
     668             :                        nt_errstr(status));
     669           0 :                 goto out;
     670             :         }
     671             : 
     672           0 :         status = cli_close(cli_unix, fnum);
     673           0 :         if (!NT_STATUS_IS_OK(status)) {
     674           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     675           0 :                 goto out;
     676             :         }
     677           0 :         fnum = (uint16_t)-1;
     678             : 
     679           0 :         for (i = 0; state[i].name != NULL; i++) {
     680           0 :                 status = cli_posix_symlink(cli_unix,
     681             :                                            state[i].target,
     682             :                                            state[i].name);
     683           0 :                 if (!NT_STATUS_IS_OK(status)) {
     684           0 :                         printf("POSIX symlink of %s failed (%s)\n",
     685             :                                symlnk_dangling, nt_errstr(status));
     686           0 :                         goto out;
     687             :                 }
     688             :         }
     689             : 
     690           0 :         for (i = 0; state[i].name != NULL; i++) {
     691             :                 SMB_STRUCT_STAT sbuf;
     692             : 
     693           0 :                 status = cli_posix_stat(cli_unix,
     694             :                                         state[i].name,
     695             :                                         &sbuf);
     696           0 :                 if (!NT_STATUS_IS_OK(status)) {
     697           0 :                         printf("POSIX stat on %s failed (%s)\n",
     698             :                                state[i].name, nt_errstr(status));
     699           0 :                         continue;
     700             :                 }
     701           0 :                 state[i].ok = true;
     702           0 :                 state[i].returned_size = sbuf.st_ex_size;
     703             :         }
     704             : 
     705           0 :         if (!posix_test_entry_check(state,
     706             :                                     symlnk_dangling,
     707             :                                     true,
     708             :                                     strlen(symlnk_dst_dangling)))
     709             :         {
     710           0 :                 goto out;
     711             :         }
     712           0 :         if (!posix_test_entry_check(state,
     713             :                                     symlnk_outside_share,
     714             :                                     true,
     715             :                                     strlen(symlnk_dst_outside_share)))
     716             :         {
     717           0 :                 goto out;
     718             :         }
     719           0 :         if (!posix_test_entry_check(state,
     720             :                                     symlnk_in_share,
     721             :                                     true,
     722             :                                     strlen(symlnk_dst_in_share))) {
     723           0 :                 goto out;
     724             :         }
     725             : 
     726           0 :         printf("POSIX-STAT test passed\n");
     727           0 :         correct = true;
     728             : 
     729           0 : out:
     730           0 :         cli_posix_unlink(cli_unix, file);
     731           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     732           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     733           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     734             : 
     735           0 :         if (!torture_close_connection(cli_unix)) {
     736           0 :                 correct = false;
     737             :         }
     738             : 
     739           0 :         TALLOC_FREE(frame);
     740           0 :         return correct;
     741             : }
     742             : 
     743             : /*
     744             :   Test Creating files and directories directly
     745             :   under a symlink.
     746             :  */
     747           0 : bool run_posix_symlink_parent_test(int dummy)
     748             : {
     749           0 :         TALLOC_CTX *frame = NULL;
     750           0 :         struct cli_state *cli_unix = NULL;
     751           0 :         uint16_t fnum = (uint16_t)-1;
     752             :         NTSTATUS status;
     753           0 :         const char *parent_dir = "target_dir";
     754           0 :         const char *parent_symlink = "symlink_to_target_dir";
     755           0 :         const char *fname_real = "target_dir/file";
     756           0 :         const char *dname_real = "target_dir/dir";
     757           0 :         const char *fname_link = "symlink_to_target_dir/file";
     758           0 :         const char *dname_link = "symlink_to_target_dir/dir";
     759           0 :         const char *sname_link = "symlink_to_target_dir/symlink";
     760           0 :         const char *hname_link = "symlink_to_target_dir/hardlink";
     761           0 :         bool correct = false;
     762             : 
     763           0 :         frame = talloc_stackframe();
     764             : 
     765           0 :         printf("Starting POSIX-SYMLINK-PARENT test\n");
     766             : 
     767           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     768           0 :                 TALLOC_FREE(frame);
     769           0 :                 return false;
     770             :         }
     771             : 
     772           0 :         torture_conn_set_sockopt(cli_unix);
     773             : 
     774           0 :         status = torture_setup_unix_extensions(cli_unix);
     775           0 :         if (!NT_STATUS_IS_OK(status)) {
     776           0 :                 TALLOC_FREE(frame);
     777           0 :                 return false;
     778             :         }
     779             : 
     780             :         /* Start with a clean slate. */
     781           0 :         cli_posix_unlink(cli_unix, fname_real);
     782           0 :         cli_posix_rmdir(cli_unix, dname_real);
     783           0 :         cli_posix_unlink(cli_unix, fname_link);
     784           0 :         cli_posix_rmdir(cli_unix, dname_link);
     785           0 :         cli_posix_unlink(cli_unix, sname_link);
     786           0 :         cli_posix_unlink(cli_unix, hname_link);
     787           0 :         cli_posix_unlink(cli_unix, parent_symlink);
     788           0 :         cli_posix_rmdir(cli_unix, parent_dir);
     789             : 
     790             :         /* Create parent_dir. */
     791           0 :         status = cli_posix_mkdir(cli_unix, parent_dir, 0777);
     792           0 :         if (!NT_STATUS_IS_OK(status)) {
     793           0 :                 printf("cli_posix_mkdir of %s failed error %s\n",
     794             :                        parent_dir,
     795             :                        nt_errstr(status));
     796           0 :                 goto out;
     797             :         }
     798             :         /* Create symlink to parent_dir. */
     799           0 :         status = cli_posix_symlink(cli_unix,
     800             :                                    parent_dir,
     801             :                                    parent_symlink);
     802           0 :         if (!NT_STATUS_IS_OK(status)) {
     803           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
     804             :                        parent_symlink,
     805             :                        parent_dir,
     806             :                        nt_errstr(status));
     807           0 :                 goto out;
     808             :         }
     809             :         /* Try and create a directory under the symlink. */
     810           0 :         status = cli_posix_mkdir(cli_unix, dname_link, 0777);
     811           0 :         if (!NT_STATUS_IS_OK(status)) {
     812           0 :                 printf("cli_posix_mkdir of %s failed error %s\n",
     813             :                        dname_link,
     814             :                        nt_errstr(status));
     815           0 :                 goto out;
     816             :         }
     817             :         /* Try and create a file under the symlink. */
     818           0 :         status = cli_posix_open(cli_unix,
     819             :                                 fname_link,
     820             :                                 O_RDWR|O_CREAT,
     821             :                                 0666,
     822             :                                 &fnum);
     823           0 :         if (!NT_STATUS_IS_OK(status)) {
     824           0 :                 printf("cli_posix_open of %s failed error %s\n",
     825             :                        fname_link,
     826             :                        nt_errstr(status));
     827           0 :                 goto out;
     828             :         }
     829           0 :         status = cli_close(cli_unix, fnum);
     830           0 :         if (!NT_STATUS_IS_OK(status)) {
     831           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     832           0 :                 goto out;
     833             :         }
     834           0 :         fnum = (uint16_t)-1;
     835             : 
     836             :         /* Try and create a symlink to the file under the symlink. */
     837           0 :         status = cli_posix_symlink(cli_unix,
     838             :                                    fname_link,
     839             :                                    sname_link);
     840           0 :         if (!NT_STATUS_IS_OK(status)) {
     841           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
     842             :                         sname_link,
     843             :                         fname_link,
     844             :                         nt_errstr(status));
     845           0 :                 goto out;
     846             :         }
     847             : 
     848             :         /* Try and create a hardlink to the file under the symlink. */
     849           0 :         status = cli_posix_hardlink(cli_unix,
     850             :                                    fname_link,
     851             :                                    hname_link);
     852           0 :         if (!NT_STATUS_IS_OK(status)) {
     853           0 :                 printf("cli_posix_hardlink of %s -> %s failed error %s\n",
     854             :                         hname_link,
     855             :                         fname_link,
     856             :                         nt_errstr(status));
     857           0 :                 goto out;
     858             :         }
     859             : 
     860             :         /* Ensure we can delete the symlink via the parent symlink */
     861           0 :         status = cli_posix_unlink(cli_unix, sname_link);
     862           0 :         if (!NT_STATUS_IS_OK(status)) {
     863           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
     864             :                        sname_link,
     865             :                        nt_errstr(status));
     866           0 :                 goto out;
     867             :         }
     868             : 
     869             :         /* Ensure we can delete the hardlink via the parent symlink */
     870           0 :         status = cli_posix_unlink(cli_unix, hname_link);
     871           0 :         if (!NT_STATUS_IS_OK(status)) {
     872           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
     873             :                        hname_link,
     874             :                        nt_errstr(status));
     875           0 :                 goto out;
     876             :         }
     877             : 
     878             :         /* Ensure we can delete the directory via the parent symlink */
     879           0 :         status = cli_posix_rmdir(cli_unix, dname_link);
     880           0 :         if (!NT_STATUS_IS_OK(status)) {
     881           0 :                 printf("cli_posix_rmdir of %s failed error %s\n",
     882             :                        dname_link,
     883             :                        nt_errstr(status));
     884           0 :                 goto out;
     885             :         }
     886             :         /* Ensure we can delete the file via the parent symlink */
     887           0 :         status = cli_posix_unlink(cli_unix, fname_link);
     888           0 :         if (!NT_STATUS_IS_OK(status)) {
     889           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
     890             :                        fname_link,
     891             :                        nt_errstr(status));
     892           0 :                 goto out;
     893             :         }
     894             : 
     895           0 :         printf("POSIX-SYMLINK-PARENT test passed\n");
     896           0 :         correct = true;
     897             : 
     898           0 : out:
     899           0 :         if (fnum != (uint16_t)-1) {
     900           0 :                 cli_close(cli_unix, fnum);
     901             :         }
     902           0 :         cli_posix_unlink(cli_unix, fname_real);
     903           0 :         cli_posix_rmdir(cli_unix, dname_real);
     904           0 :         cli_posix_unlink(cli_unix, fname_link);
     905           0 :         cli_posix_rmdir(cli_unix, dname_link);
     906           0 :         cli_posix_unlink(cli_unix, sname_link);
     907           0 :         cli_posix_unlink(cli_unix, hname_link);
     908           0 :         cli_posix_unlink(cli_unix, parent_symlink);
     909           0 :         cli_posix_rmdir(cli_unix, parent_dir);
     910             : 
     911           0 :         if (!torture_close_connection(cli_unix)) {
     912           0 :                 correct = false;
     913             :         }
     914             : 
     915           0 :         TALLOC_FREE(frame);
     916           0 :         return correct;
     917             : }
     918             : 
     919             : /*
     920             :   Ensure we get an error when doing chmod on a symlink,
     921             :   whether it is pointing to a real object or dangling.
     922             :  */
     923           0 : bool run_posix_symlink_chmod_test(int dummy)
     924             : {
     925           0 :         TALLOC_CTX *frame = NULL;
     926           0 :         struct cli_state *cli_unix = NULL;
     927             :         NTSTATUS status;
     928           0 :         uint16_t fnum = (uint16_t)-1;
     929           0 :         const char *fname_real = "file_real";
     930           0 :         const char *fname_real_symlink = "file_real_symlink";
     931           0 :         const char *nonexist = "nonexist";
     932           0 :         const char *nonexist_symlink = "dangling_symlink";
     933           0 :         bool correct = false;
     934             : 
     935           0 :         frame = talloc_stackframe();
     936             : 
     937           0 :         printf("Starting POSIX-SYMLINK-CHMOD test\n");
     938             : 
     939           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     940           0 :                 TALLOC_FREE(frame);
     941           0 :                 return false;
     942             :         }
     943             : 
     944           0 :         torture_conn_set_sockopt(cli_unix);
     945             : 
     946           0 :         status = torture_setup_unix_extensions(cli_unix);
     947           0 :         if (!NT_STATUS_IS_OK(status)) {
     948           0 :                 TALLOC_FREE(frame);
     949           0 :                 return false;
     950             :         }
     951             : 
     952             :         /* Start with a clean slate. */
     953           0 :         cli_posix_unlink(cli_unix, fname_real);
     954           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
     955           0 :         cli_posix_unlink(cli_unix, nonexist);
     956           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
     957             : 
     958             :         /* Create a real file. */
     959           0 :         status = cli_posix_open(cli_unix,
     960             :                                 fname_real,
     961             :                                 O_RDWR|O_CREAT,
     962             :                                 0644,
     963             :                                 &fnum);
     964           0 :         if (!NT_STATUS_IS_OK(status)) {
     965           0 :                 printf("cli_posix_open of %s failed error %s\n",
     966             :                        fname_real,
     967             :                        nt_errstr(status));
     968           0 :                 goto out;
     969             :         }
     970           0 :         status = cli_close(cli_unix, fnum);
     971           0 :         if (!NT_STATUS_IS_OK(status)) {
     972           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     973           0 :                 goto out;
     974             :         }
     975           0 :         fnum = (uint16_t)-1;
     976             : 
     977             :         /* Create symlink to real target. */
     978           0 :         status = cli_posix_symlink(cli_unix,
     979             :                                    fname_real,
     980             :                                    fname_real_symlink);
     981           0 :         if (!NT_STATUS_IS_OK(status)) {
     982           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
     983             :                        fname_real_symlink,
     984             :                        fname_real,
     985             :                        nt_errstr(status));
     986           0 :                 goto out;
     987             :         }
     988             : 
     989             :         /* We should not be able to chmod symlinks that point to something. */
     990           0 :         status = cli_posix_chmod(cli_unix, fname_real_symlink, 0777);
     991             : 
     992             :         /* This should fail with something other than server crashed. */
     993           0 :         if (NT_STATUS_IS_OK(status)) {
     994           0 :                 printf("cli_posix_chmod of %s succeeded (should have failed)\n",
     995             :                         fname_real_symlink);
     996           0 :                 goto out;
     997             :         }
     998           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
     999             :                 /* Oops. Server crashed. */
    1000           0 :                 printf("cli_posix_chmod of %s failed error %s\n",
    1001             :                         fname_real_symlink,
    1002             :                         nt_errstr(status));
    1003           0 :                 goto out;
    1004             :         }
    1005             :         /* Any other failure is ok. */
    1006             : 
    1007             :         /* Now create symlink to non-existing target. */
    1008           0 :         status = cli_posix_symlink(cli_unix,
    1009             :                                    nonexist,
    1010             :                                    nonexist_symlink);
    1011           0 :         if (!NT_STATUS_IS_OK(status)) {
    1012           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1013             :                        nonexist_symlink,
    1014             :                        nonexist,
    1015             :                        nt_errstr(status));
    1016           0 :                 goto out;
    1017             :         }
    1018             : 
    1019             :         /* We should not be able to chmod symlinks that point to nothing. */
    1020           0 :         status = cli_posix_chmod(cli_unix, nonexist_symlink, 0777);
    1021             : 
    1022             :         /* This should fail with something other than server crashed. */
    1023           0 :         if (NT_STATUS_IS_OK(status)) {
    1024           0 :                 printf("cli_posix_chmod of %s succeeded (should have failed)\n",
    1025             :                         nonexist_symlink);
    1026           0 :                 goto out;
    1027             :         }
    1028           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
    1029             :                 /* Oops. Server crashed. */
    1030           0 :                 printf("cli_posix_chmod of %s failed error %s\n",
    1031             :                         nonexist_symlink,
    1032             :                         nt_errstr(status));
    1033           0 :                 goto out;
    1034             :         }
    1035             : 
    1036             :         /* Any other failure is ok. */
    1037           0 :         printf("POSIX-SYMLINK-CHMOD test passed (expected failure was %s)\n",
    1038             :                         nt_errstr(status));
    1039           0 :         correct = true;
    1040             : 
    1041           0 : out:
    1042           0 :         if (fnum != (uint16_t)-1) {
    1043           0 :                 cli_close(cli_unix, fnum);
    1044             :         }
    1045           0 :         cli_posix_unlink(cli_unix, fname_real);
    1046           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1047           0 :         cli_posix_unlink(cli_unix, nonexist);
    1048           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1049             : 
    1050           0 :         if (!torture_close_connection(cli_unix)) {
    1051           0 :                 correct = false;
    1052             :         }
    1053             : 
    1054           0 :         TALLOC_FREE(frame);
    1055           0 :         return correct;
    1056             : }
    1057             : 
    1058             : /*
    1059             :   Ensure we get an ACL containing OI|IO ACE entries
    1060             :   after we add a default POSIX ACL to a directory.
    1061             :   This will only ever be an SMB1 test as it depends
    1062             :   on POSIX ACL semantics.
    1063             :  */
    1064           0 : bool run_posix_dir_default_acl_test(int dummy)
    1065             : {
    1066           0 :         TALLOC_CTX *frame = NULL;
    1067           0 :         struct cli_state *cli_unix = NULL;
    1068             :         NTSTATUS status;
    1069           0 :         uint16_t fnum = (uint16_t)-1;
    1070           0 :         const char *dname = "dir_with_default_acl";
    1071           0 :         bool correct = false;
    1072             :         SMB_STRUCT_STAT sbuf;
    1073           0 :         size_t acl_size = 0;
    1074           0 :         char *aclbuf = NULL;
    1075           0 :         size_t num_file_acls = 0;
    1076           0 :         size_t num_dir_acls = 0;
    1077             :         size_t expected_buflen;
    1078           0 :         uint8_t def_acl[SMB_POSIX_ACL_HEADER_SIZE +
    1079             :                         5*SMB_POSIX_ACL_ENTRY_SIZE] = {0};
    1080           0 :         uint8_t *p = NULL;
    1081           0 :         uint32_t i = 0;
    1082           0 :         struct security_descriptor *sd = NULL;
    1083           0 :         bool got_inherit = false;
    1084             : 
    1085           0 :         frame = talloc_stackframe();
    1086             : 
    1087           0 :         printf("Starting POSIX-DIR-DEFAULT-ACL test\n");
    1088             : 
    1089           0 :         if (!torture_open_connection(&cli_unix, 0)) {
    1090           0 :                 TALLOC_FREE(frame);
    1091           0 :                 return false;
    1092             :         }
    1093             : 
    1094           0 :         torture_conn_set_sockopt(cli_unix);
    1095             : 
    1096           0 :         status = torture_setup_unix_extensions(cli_unix);
    1097           0 :         if (!NT_STATUS_IS_OK(status)) {
    1098           0 :                 TALLOC_FREE(frame);
    1099           0 :                 return false;
    1100             :         }
    1101             : 
    1102             :         /* Start with a clean slate. */
    1103           0 :         cli_posix_unlink(cli_unix, dname);
    1104           0 :         cli_posix_rmdir(cli_unix, dname);
    1105             : 
    1106           0 :         status = cli_posix_mkdir(cli_unix, dname, 0777);
    1107           0 :         if (!NT_STATUS_IS_OK(status)) {
    1108           0 :                 printf("cli_posix_mkdir of %s failed error %s\n",
    1109             :                        dname,
    1110             :                        nt_errstr(status));
    1111           0 :                 goto out;
    1112             :         }
    1113             : 
    1114             :         /* Do a posix stat to get the owner. */
    1115           0 :         status = cli_posix_stat(cli_unix, dname, &sbuf);
    1116           0 :         if (!NT_STATUS_IS_OK(status)) {
    1117           0 :                 printf("cli_posix_stat of %s failed %s\n",
    1118             :                         dname,
    1119             :                         nt_errstr(status));
    1120           0 :                 goto out;
    1121             :         }
    1122             : 
    1123             :         /* Get the ACL on the directory. */
    1124           0 :         status = cli_posix_getacl(cli_unix, dname, frame, &acl_size, &aclbuf);
    1125           0 :         if (!NT_STATUS_IS_OK(status)) {
    1126           0 :                 printf("cli_posix_getacl on %s failed %s\n",
    1127             :                         dname,
    1128             :                         nt_errstr(status));
    1129           0 :                 goto out;
    1130             :         }
    1131             : 
    1132           0 :         if (acl_size < 6 || SVAL(aclbuf,0) != SMB_POSIX_ACL_VERSION) {
    1133           0 :                 printf("%s, unknown POSIX acl version %u.\n",
    1134             :                         dname,
    1135           0 :                         (unsigned int)CVAL(aclbuf,0) );
    1136           0 :                 goto out;
    1137             :         }
    1138             : 
    1139           0 :         num_file_acls = SVAL(aclbuf,2);
    1140           0 :         num_dir_acls = SVAL(aclbuf,4);
    1141             : 
    1142             :         /*
    1143             :          * No overflow check, num_*_acls comes from a 16-bit value,
    1144             :          * and we expect expected_buflen (size_t) to be of at least 32
    1145             :          * bit.
    1146             :          */
    1147           0 :         expected_buflen = SMB_POSIX_ACL_HEADER_SIZE +
    1148           0 :                           SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls);
    1149             : 
    1150           0 :         if (acl_size != expected_buflen) {
    1151           0 :                 printf("%s, incorrect POSIX acl buffer size "
    1152             :                         "(should be %zu, was %zu).\n",
    1153             :                         dname,
    1154             :                         expected_buflen,
    1155             :                         acl_size);
    1156           0 :                 goto out;
    1157             :         }
    1158             : 
    1159           0 :         if (num_dir_acls != 0) {
    1160           0 :                 printf("%s, POSIX default acl already exists"
    1161             :                         "(should be 0, was %zu).\n",
    1162             :                         dname,
    1163             :                         num_dir_acls);
    1164           0 :                 goto out;
    1165             :         }
    1166             : 
    1167             :         /*
    1168             :          * Get the Windows ACL on the directory.
    1169             :          * Make sure there are no inheritable entries.
    1170             :          */
    1171           0 :         status = cli_ntcreate(cli_unix,
    1172             :                                 dname,
    1173             :                                 0,
    1174             :                                 SEC_STD_READ_CONTROL,
    1175             :                                 0,
    1176             :                                 FILE_SHARE_READ|
    1177             :                                         FILE_SHARE_WRITE|
    1178             :                                         FILE_SHARE_DELETE,
    1179             :                                 FILE_OPEN,
    1180             :                                 FILE_DIRECTORY_FILE,
    1181             :                                 0x0,
    1182             :                                 &fnum,
    1183             :                                 NULL);
    1184           0 :         if (!NT_STATUS_IS_OK(status)) {
    1185           0 :                 printf("Failed to open directory %s: %s\n",
    1186             :                         dname,
    1187             :                         nt_errstr(status));
    1188           0 :                 goto out;
    1189             :         }
    1190             : 
    1191           0 :         status = cli_query_security_descriptor(cli_unix,
    1192             :                                                 fnum,
    1193             :                                                 SECINFO_DACL,
    1194             :                                                 frame,
    1195             :                                                 &sd);
    1196           0 :         if (!NT_STATUS_IS_OK(status)) {
    1197           0 :                 printf("Failed to get security descriptor on directory %s: %s\n",
    1198             :                         dname,
    1199             :                         nt_errstr(status));
    1200           0 :                 goto out;
    1201             :         }
    1202             : 
    1203           0 :         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
    1204           0 :                 struct security_ace *ace = &sd->dacl->aces[i];
    1205           0 :                 if (ace->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
    1206             :                                   SEC_ACE_FLAG_CONTAINER_INHERIT)) {
    1207           0 :                         printf("security descritor on directory %s already "
    1208             :                                 "contains inheritance flags\n",
    1209             :                                 dname);
    1210           0 :                         sec_desc_print(NULL, stdout, sd, true);
    1211           0 :                         goto out;
    1212             :                 }
    1213             :         }
    1214             : 
    1215           0 :         TALLOC_FREE(sd);
    1216             : 
    1217             :         /* Construct a new default ACL. */
    1218           0 :         SSVAL(def_acl,0,SMB_POSIX_ACL_VERSION);
    1219           0 :         SSVAL(def_acl,2,SMB_POSIX_IGNORE_ACE_ENTRIES);
    1220           0 :         SSVAL(def_acl,4,5); /* num_dir_acls. */
    1221             : 
    1222           0 :         p = def_acl + SMB_POSIX_ACL_HEADER_SIZE;
    1223             : 
    1224             :         /* USER_OBJ. */
    1225           0 :         SCVAL(p,0,SMB_POSIX_ACL_USER_OBJ); /* tagtype. */
    1226           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1227           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1228             : 
    1229             :         /* GROUP_OBJ. */
    1230           0 :         SCVAL(p,0,SMB_POSIX_ACL_GROUP_OBJ); /* tagtype. */
    1231           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1232           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1233             : 
    1234             :         /* OTHER. */
    1235           0 :         SCVAL(p,0,SMB_POSIX_ACL_OTHER); /* tagtype. */
    1236           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1237           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1238             : 
    1239             :         /* Explicit user. */
    1240           0 :         SCVAL(p,0,SMB_POSIX_ACL_USER); /* tagtype. */
    1241           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1242           0 :         SIVAL(p,2,sbuf.st_ex_uid);
    1243           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1244             : 
    1245             :         /* MASK. */
    1246           0 :         SCVAL(p,0,SMB_POSIX_ACL_MASK); /* tagtype. */
    1247           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1248           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1249             : 
    1250             :         /* Set the POSIX default ACL. */
    1251           0 :         status = cli_posix_setacl(cli_unix, dname, def_acl, sizeof(def_acl));
    1252           0 :         if (!NT_STATUS_IS_OK(status)) {
    1253           0 :                 printf("cli_posix_setacl on %s failed %s\n",
    1254             :                         dname,
    1255             :                         nt_errstr(status));
    1256           0 :                 goto out;
    1257             :         }
    1258             : 
    1259             :         /*
    1260             :          * Get the Windows ACL on the directory again.
    1261             :          * Now there should be inheritable entries.
    1262             :          */
    1263             : 
    1264           0 :         status = cli_query_security_descriptor(cli_unix,
    1265             :                                                 fnum,
    1266             :                                                 SECINFO_DACL,
    1267             :                                                 frame,
    1268             :                                                 &sd);
    1269           0 :         if (!NT_STATUS_IS_OK(status)) {
    1270           0 :                 printf("Failed (2) to get security descriptor "
    1271             :                         "on directory %s: %s\n",
    1272             :                         dname,
    1273             :                         nt_errstr(status));
    1274           0 :                 goto out;
    1275             :         }
    1276             : 
    1277           0 :         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
    1278           0 :                 struct security_ace *ace = &sd->dacl->aces[i];
    1279           0 :                 if (ace->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
    1280             :                                   SEC_ACE_FLAG_CONTAINER_INHERIT)) {
    1281           0 :                         got_inherit = true;
    1282           0 :                         break;
    1283             :                 }
    1284             :         }
    1285             : 
    1286           0 :         if (!got_inherit) {
    1287           0 :                 printf("security descritor on directory %s does not "
    1288             :                         "contain inheritance flags\n",
    1289             :                         dname);
    1290           0 :                 sec_desc_print(NULL, stdout, sd, true);
    1291           0 :                 goto out;
    1292             :         }
    1293             : 
    1294           0 :         cli_close(cli_unix, fnum);
    1295           0 :         fnum = (uint16_t)-1;
    1296           0 :         printf("POSIX-DIR-DEFAULT-ACL test passed\n");
    1297           0 :         correct = true;
    1298             : 
    1299           0 : out:
    1300             : 
    1301           0 :         TALLOC_FREE(sd);
    1302             : 
    1303           0 :         if (fnum != (uint16_t)-1) {
    1304           0 :                 cli_close(cli_unix, fnum);
    1305             :         }
    1306           0 :         cli_posix_unlink(cli_unix, dname);
    1307           0 :         cli_posix_rmdir(cli_unix, dname);
    1308             : 
    1309           0 :         if (!torture_close_connection(cli_unix)) {
    1310           0 :                 correct = false;
    1311             :         }
    1312             : 
    1313           0 :         TALLOC_FREE(frame);
    1314           0 :         return correct;
    1315             : }
    1316             : 
    1317             : /*
    1318             :   Ensure we can rename a symlink whether it is
    1319             :   pointing to a real object or dangling.
    1320             :  */
    1321           0 : bool run_posix_symlink_rename_test(int dummy)
    1322             : {
    1323           0 :         TALLOC_CTX *frame = NULL;
    1324           0 :         struct cli_state *cli_unix = NULL;
    1325             :         NTSTATUS status;
    1326           0 :         uint16_t fnum = (uint16_t)-1;
    1327           0 :         const char *fname_real = "file_real";
    1328           0 :         const char *fname_real_symlink = "file_real_symlink";
    1329           0 :         const char *fname_real_symlink_newname = "rename_file_real_symlink";
    1330           0 :         const char *nonexist = "nonexist";
    1331           0 :         const char *nonexist_symlink = "dangling_symlink";
    1332           0 :         const char *nonexist_symlink_newname = "dangling_symlink_rename";
    1333           0 :         bool correct = false;
    1334             : 
    1335           0 :         frame = talloc_stackframe();
    1336             : 
    1337           0 :         printf("Starting POSIX-SYMLINK-RENAME test\n");
    1338             : 
    1339           0 :         if (!torture_open_connection(&cli_unix, 0)) {
    1340           0 :                 TALLOC_FREE(frame);
    1341           0 :                 return false;
    1342             :         }
    1343             : 
    1344           0 :         torture_conn_set_sockopt(cli_unix);
    1345             : 
    1346           0 :         status = torture_setup_unix_extensions(cli_unix);
    1347           0 :         if (!NT_STATUS_IS_OK(status)) {
    1348           0 :                 TALLOC_FREE(frame);
    1349           0 :                 return false;
    1350             :         }
    1351             : 
    1352             :         /* Start with a clean slate. */
    1353           0 :         cli_posix_unlink(cli_unix, fname_real);
    1354           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1355           0 :         cli_posix_unlink(cli_unix, fname_real_symlink_newname);
    1356           0 :         cli_posix_unlink(cli_unix, nonexist);
    1357           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1358           0 :         cli_posix_unlink(cli_unix, nonexist_symlink_newname);
    1359             : 
    1360             :         /* Create a real file. */
    1361           0 :         status = cli_posix_open(cli_unix,
    1362             :                                 fname_real,
    1363             :                                 O_RDWR|O_CREAT,
    1364             :                                 0644,
    1365             :                                 &fnum);
    1366           0 :         if (!NT_STATUS_IS_OK(status)) {
    1367           0 :                 printf("cli_posix_open of %s failed error %s\n",
    1368             :                        fname_real,
    1369             :                        nt_errstr(status));
    1370           0 :                 goto out;
    1371             :         }
    1372           0 :         status = cli_close(cli_unix, fnum);
    1373           0 :         if (!NT_STATUS_IS_OK(status)) {
    1374           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    1375           0 :                 goto out;
    1376             :         }
    1377           0 :         fnum = (uint16_t)-1;
    1378             : 
    1379             :         /* Create symlink to real target. */
    1380           0 :         status = cli_posix_symlink(cli_unix,
    1381             :                                    fname_real,
    1382             :                                    fname_real_symlink);
    1383           0 :         if (!NT_STATUS_IS_OK(status)) {
    1384           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1385             :                        fname_real_symlink,
    1386             :                        fname_real,
    1387             :                        nt_errstr(status));
    1388           0 :                 goto out;
    1389             :         }
    1390             : 
    1391             :         /* Ensure we can rename the symlink to the real file. */
    1392           0 :         status = cli_rename(cli_unix,
    1393             :                                 fname_real_symlink,
    1394             :                                 fname_real_symlink_newname,
    1395             :                                 false);
    1396           0 :         if (!NT_STATUS_IS_OK(status)) {
    1397           0 :                 printf("cli_rename of %s -> %s failed %s\n",
    1398             :                         fname_real_symlink,
    1399             :                         fname_real_symlink_newname,
    1400             :                         nt_errstr(status));
    1401           0 :                 goto out;
    1402             :         }
    1403             : 
    1404             :         /* Now create symlink to non-existing target. */
    1405           0 :         status = cli_posix_symlink(cli_unix,
    1406             :                                    nonexist,
    1407             :                                    nonexist_symlink);
    1408           0 :         if (!NT_STATUS_IS_OK(status)) {
    1409           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1410             :                        nonexist_symlink,
    1411             :                        nonexist,
    1412             :                        nt_errstr(status));
    1413           0 :                 goto out;
    1414             :         }
    1415             : 
    1416             :         /* Ensure we can rename the dangling symlink. */
    1417           0 :         status = cli_rename(cli_unix,
    1418             :                                 nonexist_symlink,
    1419             :                                 nonexist_symlink_newname,
    1420             :                                 false);
    1421           0 :         if (!NT_STATUS_IS_OK(status)) {
    1422           0 :                 printf("cli_rename of %s -> %s failed %s\n",
    1423             :                         nonexist_symlink,
    1424             :                         nonexist_symlink_newname,
    1425             :                         nt_errstr(status));
    1426           0 :                 goto out;
    1427             :         }
    1428             : 
    1429           0 :         printf("POSIX-SYMLINK-RENAME test passed\n");
    1430           0 :         correct = true;
    1431             : 
    1432           0 : out:
    1433           0 :         if (fnum != (uint16_t)-1) {
    1434           0 :                 cli_close(cli_unix, fnum);
    1435             :         }
    1436           0 :         cli_posix_unlink(cli_unix, fname_real);
    1437           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1438           0 :         cli_posix_unlink(cli_unix, fname_real_symlink_newname);
    1439           0 :         cli_posix_unlink(cli_unix, nonexist);
    1440           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1441           0 :         cli_posix_unlink(cli_unix, nonexist_symlink_newname);
    1442             : 
    1443           0 :         if (!torture_close_connection(cli_unix)) {
    1444           0 :                 correct = false;
    1445             :         }
    1446             : 
    1447           0 :         TALLOC_FREE(frame);
    1448           0 :         return correct;
    1449             : }
    1450             : 
    1451             : /* List of info levels to try with a POSIX symlink path. */
    1452             : 
    1453             : static struct {
    1454             :         uint32_t level;
    1455             :         const char *name;
    1456             : } posix_smb1_qpath_array[] = {
    1457             :   { SMB_INFO_STANDARD,                  "SMB_INFO_STANDARD"},
    1458             :   { SMB_INFO_QUERY_EA_SIZE,             "SMB_INFO_QUERY_EA_SIZE"},
    1459             :   { SMB_INFO_IS_NAME_VALID,             "SMB_INFO_IS_NAME_VALID"},
    1460             :   { SMB_INFO_QUERY_EAS_FROM_LIST,       "SMB_INFO_QUERY_EAS_FROM_LIST"},
    1461             :   { SMB_INFO_QUERY_ALL_EAS,             "SMB_INFO_QUERY_ALL_EAS"},
    1462             :   { SMB_FILE_BASIC_INFORMATION,         "SMB_FILE_BASIC_INFORMATION"},
    1463             :   { SMB_FILE_STANDARD_INFORMATION,      "SMB_FILE_STANDARD_INFORMATION"},
    1464             :   { SMB_FILE_EA_INFORMATION,            "SMB_FILE_EA_INFORMATION"},
    1465             :   { SMB_FILE_ALTERNATE_NAME_INFORMATION,"SMB_FILE_ALTERNATE_NAME_INFORMATION"},
    1466             :   { SMB_QUERY_FILE_NAME_INFO,           "SMB_QUERY_FILE_NAME_INFO"},
    1467             :   { SMB_FILE_NORMALIZED_NAME_INFORMATION,"SMB_FILE_NORMALIZED_NAME_INFORMATION"},
    1468             :   { SMB_FILE_ALLOCATION_INFORMATION,    "SMB_FILE_ALLOCATION_INFORMATION"},
    1469             :   { SMB_FILE_END_OF_FILE_INFORMATION,   "SMB_FILE_END_OF_FILE_INFORMATION"},
    1470             :   { SMB_FILE_ALL_INFORMATION,           "SMB_FILE_ALL_INFORMATION"},
    1471             :   { SMB_FILE_INTERNAL_INFORMATION,      "SMB_FILE_INTERNAL_INFORMATION"},
    1472             :   { SMB_FILE_ACCESS_INFORMATION,        "SMB_FILE_ACCESS_INFORMATION"},
    1473             :   { SMB_FILE_NAME_INFORMATION,          "SMB_FILE_NAME_INFORMATION"},
    1474             :   { SMB_FILE_DISPOSITION_INFORMATION,   "SMB_FILE_DISPOSITION_INFORMATION"},
    1475             :   { SMB_FILE_POSITION_INFORMATION,      "SMB_FILE_POSITION_INFORMATION"},
    1476             :   { SMB_FILE_MODE_INFORMATION,          "SMB_FILE_MODE_INFORMATION"},
    1477             :   { SMB_FILE_ALIGNMENT_INFORMATION,     "SMB_FILE_ALIGNMENT_INFORMATION"},
    1478             :   { SMB_FILE_STREAM_INFORMATION,        "SMB_FILE_STREAM_INFORMATION"},
    1479             :   { SMB_FILE_COMPRESSION_INFORMATION,   "SMB_FILE_COMPRESSION_INFORMATION"},
    1480             :   { SMB_FILE_NETWORK_OPEN_INFORMATION,  "SMB_FILE_NETWORK_OPEN_INFORMATION"},
    1481             :   { SMB_FILE_ATTRIBUTE_TAG_INFORMATION, "SMB_FILE_ATTRIBUTE_TAG_INFORMATION"},
    1482             :   { SMB_QUERY_FILE_UNIX_BASIC,          "SMB_QUERY_FILE_UNIX_BASIC"},
    1483             :   { SMB_QUERY_FILE_UNIX_INFO2,          "SMB_QUERY_FILE_UNIX_INFO2"},
    1484             :   { SMB_QUERY_FILE_UNIX_LINK,           "SMB_QUERY_FILE_UNIX_LINK"},
    1485             :   { SMB_QUERY_POSIX_ACL,                "SMB_QUERY_POSIX_ACL"},
    1486             :   { SMB_QUERY_POSIX_LOCK,               "SMB_QUERY_POSIX_LOCK"},
    1487             : };
    1488             : 
    1489           0 : static NTSTATUS do_qpath(TALLOC_CTX *ctx,
    1490             :                          struct cli_state *cli_unix,
    1491             :                          const char *fname,
    1492             :                          size_t i)
    1493             : {
    1494             :         NTSTATUS status;
    1495             : 
    1496           0 :         if (posix_smb1_qpath_array[i].level ==
    1497             :                         SMB_INFO_QUERY_EAS_FROM_LIST) {
    1498             :                 uint16_t setup;
    1499             :                 uint8_t *param;
    1500             :                 uint8_t data[8];
    1501           0 :                 uint8_t *rparam = NULL;
    1502           0 :                 uint8_t *rdata = NULL;
    1503           0 :                 uint32_t rbytes = 0;
    1504             : 
    1505             :                 /* Set up an EA list with 'a' as the single name. */
    1506           0 :                 SIVAL(data,0, 8);
    1507           0 :                 SCVAL(data,4, 2); /* namelen. */
    1508           0 :                 SCVAL(data,5, 'a');
    1509           0 :                 SCVAL(data,6, '\0'); /* name. */
    1510           0 :                 SCVAL(data,7, '\0'); /* padding. */
    1511             : 
    1512           0 :                 SSVAL(&setup, 0, TRANSACT2_QPATHINFO);
    1513             : 
    1514           0 :                 param = talloc_zero_array(ctx, uint8_t, 6);
    1515           0 :                 if (param == NULL) {
    1516           0 :                         return NT_STATUS_NO_MEMORY;
    1517             :                 }
    1518           0 :                 SSVAL(param, 0, SMB_INFO_QUERY_EAS_FROM_LIST);
    1519           0 :                 param = trans2_bytes_push_str(param,
    1520           0 :                                 smbXcli_conn_use_unicode(cli_unix->conn),
    1521             :                                 fname,
    1522           0 :                                 strlen(fname)+1,
    1523             :                                 NULL);
    1524           0 :                 if (param == NULL) {
    1525           0 :                         return NT_STATUS_NO_MEMORY;
    1526             :                 }
    1527             : 
    1528           0 :                 status = cli_trans(ctx,
    1529             :                                 cli_unix,
    1530             :                                 SMBtrans2,
    1531             :                                 NULL,
    1532             :                                 -1,
    1533             :                                 0,
    1534             :                                 0,
    1535             :                                 &setup, 1, 0,
    1536           0 :                                 param, talloc_get_size(param), talloc_get_size(param),
    1537             :                                 data, 8, 0,
    1538             :                                 NULL,
    1539             :                                 NULL, 0, NULL,
    1540             :                                 &rparam, 0, &rbytes,
    1541             :                                 &rdata, 0, &rbytes);
    1542           0 :                 TALLOC_FREE(rparam);
    1543           0 :                 TALLOC_FREE(rdata);
    1544             :         } else {
    1545           0 :                 uint8_t *rdata = NULL;
    1546           0 :                 uint32_t num_rdata = 0;
    1547             : 
    1548           0 :                 status = cli_qpathinfo(ctx,
    1549             :                                 cli_unix,
    1550             :                                 fname,
    1551           0 :                                 posix_smb1_qpath_array[i].level,
    1552             :                                 0, /* min_rdata */
    1553             :                                 65534, /* max_rdata */
    1554             :                                 &rdata,
    1555             :                                 &num_rdata);
    1556           0 :                 TALLOC_FREE(rdata);
    1557             :         }
    1558             :         /*
    1559             :          * We don't care what came back, so long as the
    1560             :          * server didn't crash.
    1561             :          */
    1562           0 :         if (NT_STATUS_EQUAL(status,
    1563             :                         NT_STATUS_CONNECTION_DISCONNECTED)) {
    1564           0 :                 printf("cli_qpathinfo of %s failed error "
    1565             :                         "NT_STATUS_CONNECTION_DISCONNECTED\n",
    1566             :                         fname);
    1567           0 :                 return status;
    1568             :         }
    1569             : 
    1570           0 :         printf("cli_qpathinfo info %x (%s) of %s got %s "
    1571             :                 "(this is not an error)\n",
    1572           0 :                 (unsigned int)posix_smb1_qpath_array[i].level,
    1573             :                 posix_smb1_qpath_array[i].name,
    1574             :                 fname,
    1575             :                 nt_errstr(status));
    1576             : 
    1577           0 :         return NT_STATUS_OK;
    1578             : }
    1579             : 
    1580             : /*
    1581             :   Ensure we can call SMB1 getpathinfo in a symlink,
    1582             :   pointing to a real object or dangling. We mostly
    1583             :   expect errors, but the server must not crash.
    1584             :  */
    1585           0 : bool run_posix_symlink_getpathinfo_test(int dummy)
    1586             : {
    1587           0 :         TALLOC_CTX *frame = NULL;
    1588           0 :         struct cli_state *cli_unix = NULL;
    1589             :         NTSTATUS status;
    1590           0 :         uint16_t fnum = (uint16_t)-1;
    1591           0 :         const char *fname_real = "file_getpath_real";
    1592           0 :         const char *fname_real_symlink = "file_real_getpath_symlink";
    1593           0 :         const char *nonexist = "nonexist_getpath";
    1594           0 :         const char *nonexist_symlink = "dangling_getpath_symlink";
    1595           0 :         bool correct = false;
    1596             :         size_t i;
    1597             : 
    1598           0 :         frame = talloc_stackframe();
    1599             : 
    1600           0 :         printf("Starting POSIX-SYMLINK-GETPATHINFO test\n");
    1601             : 
    1602           0 :         if (!torture_open_connection(&cli_unix, 0)) {
    1603           0 :                 TALLOC_FREE(frame);
    1604           0 :                 return false;
    1605             :         }
    1606             : 
    1607           0 :         torture_conn_set_sockopt(cli_unix);
    1608             : 
    1609           0 :         status = torture_setup_unix_extensions(cli_unix);
    1610           0 :         if (!NT_STATUS_IS_OK(status)) {
    1611           0 :                 TALLOC_FREE(frame);
    1612           0 :                 return false;
    1613             :         }
    1614             : 
    1615             :         /* Start with a clean slate. */
    1616           0 :         cli_posix_unlink(cli_unix, fname_real);
    1617           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1618           0 :         cli_posix_unlink(cli_unix, nonexist);
    1619           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1620             : 
    1621             :         /* Create a real file. */
    1622           0 :         status = cli_posix_open(cli_unix,
    1623             :                                 fname_real,
    1624             :                                 O_RDWR|O_CREAT,
    1625             :                                 0644,
    1626             :                                 &fnum);
    1627           0 :         if (!NT_STATUS_IS_OK(status)) {
    1628           0 :                 printf("cli_posix_open of %s failed error %s\n",
    1629             :                        fname_real,
    1630             :                        nt_errstr(status));
    1631           0 :                 goto out;
    1632             :         }
    1633           0 :         status = cli_close(cli_unix, fnum);
    1634           0 :         if (!NT_STATUS_IS_OK(status)) {
    1635           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    1636           0 :                 goto out;
    1637             :         }
    1638           0 :         fnum = (uint16_t)-1;
    1639             : 
    1640             :         /* Create symlink to real target. */
    1641           0 :         status = cli_posix_symlink(cli_unix,
    1642             :                                    fname_real,
    1643             :                                    fname_real_symlink);
    1644           0 :         if (!NT_STATUS_IS_OK(status)) {
    1645           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1646             :                        fname_real_symlink,
    1647             :                        fname_real,
    1648             :                        nt_errstr(status));
    1649           0 :                 goto out;
    1650             :         }
    1651             : 
    1652             :         /* Now create symlink to non-existing target. */
    1653           0 :         status = cli_posix_symlink(cli_unix,
    1654             :                                    nonexist,
    1655             :                                    nonexist_symlink);
    1656           0 :         if (!NT_STATUS_IS_OK(status)) {
    1657           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1658             :                        nonexist_symlink,
    1659             :                        nonexist,
    1660             :                        nt_errstr(status));
    1661           0 :                 goto out;
    1662             :         }
    1663             : 
    1664           0 :         for (i = 0; i < ARRAY_SIZE(posix_smb1_qpath_array); i++) {
    1665           0 :                 status = do_qpath(frame,
    1666             :                                   cli_unix,
    1667             :                                   fname_real_symlink,
    1668             :                                   i);
    1669           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1670           0 :                         goto out;
    1671             :                 }
    1672           0 :                 status = do_qpath(frame,
    1673             :                                   cli_unix,
    1674             :                                   nonexist_symlink,
    1675             :                                   i);
    1676           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1677           0 :                         goto out;
    1678             :                 }
    1679             :         }
    1680             : 
    1681           0 :         printf("POSIX-SYMLINK-GETPATHINFO test passed\n");
    1682           0 :         correct = true;
    1683             : 
    1684           0 : out:
    1685           0 :         if (fnum != (uint16_t)-1) {
    1686           0 :                 cli_close(cli_unix, fnum);
    1687             :         }
    1688           0 :         cli_posix_unlink(cli_unix, fname_real);
    1689           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1690           0 :         cli_posix_unlink(cli_unix, nonexist);
    1691           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1692             : 
    1693           0 :         if (!torture_close_connection(cli_unix)) {
    1694           0 :                 correct = false;
    1695             :         }
    1696             : 
    1697           0 :         TALLOC_FREE(frame);
    1698           0 :         return correct;
    1699             : }
    1700             : 
    1701             : /* List of info levels to try with a POSIX symlink path. */
    1702             : 
    1703             : static struct {
    1704             :         uint32_t level;
    1705             :         const char *name;
    1706             :         uint32_t data_len;
    1707             : } posix_smb1_setpath_array[] = {
    1708             :   { SMB_SET_FILE_UNIX_BASIC,    "SMB_SET_FILE_UNIX_BASIC",    100},
    1709             :   { SMB_SET_FILE_UNIX_INFO2,    "SMB_SET_FILE_UNIX_INFO2",    116},
    1710             :   { SMB_SET_FILE_UNIX_LINK,     "SMB_SET_FILE_UNIX_LINK",     8},
    1711             :   { SMB_SET_FILE_UNIX_HLINK,    "SMB_SET_FILE_UNIX_HLINK",    8},
    1712             :   { SMB_SET_POSIX_ACL,          "SMB_SET_POSIX_ACL",          6},
    1713             :   { SMB_SET_POSIX_LOCK,         "SMB_SET_POSIX_LOCK",         24},
    1714             :   { SMB_INFO_STANDARD,          "SMB_INFO_STANDARD",          12},
    1715             :   { SMB_INFO_SET_EA,            "SMB_INFO_SET_EA",            10},
    1716             :   { SMB_FILE_BASIC_INFORMATION, "SMB_FILE_BASIC_INFORMATION", 36},
    1717             :   { SMB_SET_FILE_ALLOCATION_INFO, "SMB_SET_FILE_ALLOCATION_INFO", 8},
    1718             :   { SMB_SET_FILE_END_OF_FILE_INFO,"SMB_SET_FILE_END_OF_FILE_INFO",8},
    1719             :   { SMB_SET_FILE_DISPOSITION_INFO,"SMB_SET_FILE_DISPOSITION_INFO",1},
    1720             :   { SMB_FILE_POSITION_INFORMATION,"SMB_FILE_POSITION_INFORMATION",8},
    1721             :   { SMB_FILE_FULL_EA_INFORMATION, "SMB_FILE_FULL_EA_INFORMATION",10},
    1722             :   { SMB_FILE_MODE_INFORMATION,  "SMB_FILE_MODE_INFORMATION",  4},
    1723             :   { SMB_FILE_SHORT_NAME_INFORMATION,"SMB_FILE_SHORT_NAME_INFORMATION",12},
    1724             :   { SMB_FILE_RENAME_INFORMATION,"SMB_FILE_RENAME_INFORMATION",        20},
    1725             :   { SMB_FILE_LINK_INFORMATION,  "SMB_FILE_LINK_INFORMATION",  20},
    1726             : };
    1727             : 
    1728           0 : static NTSTATUS do_setpath(TALLOC_CTX *ctx,
    1729             :                            struct cli_state *cli_unix,
    1730             :                            const char *fname,
    1731             :                            size_t i)
    1732             : {
    1733             :         NTSTATUS status;
    1734           0 :         uint8_t *data = NULL;
    1735             : 
    1736           0 :         data = talloc_zero_array(ctx,
    1737             :                                  uint8_t,
    1738             :                                  posix_smb1_setpath_array[i].data_len);
    1739           0 :         if (data == NULL) {
    1740           0 :                 return NT_STATUS_NO_MEMORY;
    1741             :         }
    1742             : 
    1743           0 :         status = cli_setpathinfo(cli_unix,
    1744           0 :                         posix_smb1_setpath_array[i].level,
    1745             :                         fname,
    1746             :                         data,
    1747           0 :                         posix_smb1_setpath_array[i].data_len);
    1748           0 :         TALLOC_FREE(data);
    1749             : 
    1750             :         /*
    1751             :          * We don't care what came back, so long as the
    1752             :          * server didn't crash.
    1753             :          */
    1754           0 :         if (NT_STATUS_EQUAL(status,
    1755             :                         NT_STATUS_CONNECTION_DISCONNECTED)) {
    1756           0 :                 printf("cli_setpathinfo info %x (%s) of %s failed"
    1757             :                         "error NT_STATUS_CONNECTION_DISCONNECTED\n",
    1758           0 :                         (unsigned int)posix_smb1_setpath_array[i].level,
    1759             :                         posix_smb1_setpath_array[i].name,
    1760             :                         fname);
    1761           0 :                 return status;
    1762             :         }
    1763             : 
    1764           0 :         printf("cli_setpathinfo info %x (%s) of %s got %s "
    1765             :                 "(this is not an error)\n",
    1766           0 :                 (unsigned int)posix_smb1_setpath_array[i].level,
    1767             :                 posix_smb1_setpath_array[i].name,
    1768             :                 fname,
    1769             :                 nt_errstr(status));
    1770             : 
    1771           0 :         return NT_STATUS_OK;
    1772             : }
    1773             : 
    1774             : /*
    1775             :   Ensure we can call SMB1 setpathinfo in a symlink,
    1776             :   pointing to a real object or dangling. We mostly
    1777             :   expect errors, but the server must not crash.
    1778             :  */
    1779           0 : bool run_posix_symlink_setpathinfo_test(int dummy)
    1780             : {
    1781           0 :         TALLOC_CTX *frame = NULL;
    1782           0 :         struct cli_state *cli_unix = NULL;
    1783             :         NTSTATUS status;
    1784           0 :         uint16_t fnum = (uint16_t)-1;
    1785           0 :         const char *fname_real = "file_setpath_real";
    1786           0 :         const char *fname_real_symlink = "file_real_setpath_symlink";
    1787           0 :         const char *nonexist = "nonexist_setpath";
    1788           0 :         const char *nonexist_symlink = "dangling_setpath_symlink";
    1789           0 :         bool correct = false;
    1790             :         size_t i;
    1791             : 
    1792           0 :         frame = talloc_stackframe();
    1793             : 
    1794           0 :         printf("Starting POSIX-SYMLINK-SETPATHINFO test\n");
    1795             : 
    1796           0 :         if (!torture_open_connection(&cli_unix, 0)) {
    1797           0 :                 TALLOC_FREE(frame);
    1798           0 :                 return false;
    1799             :         }
    1800             : 
    1801           0 :         torture_conn_set_sockopt(cli_unix);
    1802             : 
    1803           0 :         status = torture_setup_unix_extensions(cli_unix);
    1804           0 :         if (!NT_STATUS_IS_OK(status)) {
    1805           0 :                 TALLOC_FREE(frame);
    1806           0 :                 return false;
    1807             :         }
    1808             : 
    1809             :         /* Start with a clean slate. */
    1810           0 :         cli_posix_unlink(cli_unix, fname_real);
    1811           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1812           0 :         cli_posix_unlink(cli_unix, nonexist);
    1813           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1814             : 
    1815             :         /* Create a real file. */
    1816           0 :         status = cli_posix_open(cli_unix,
    1817             :                                 fname_real,
    1818             :                                 O_RDWR|O_CREAT,
    1819             :                                 0644,
    1820             :                                 &fnum);
    1821           0 :         if (!NT_STATUS_IS_OK(status)) {
    1822           0 :                 printf("cli_posix_open of %s failed error %s\n",
    1823             :                        fname_real,
    1824             :                        nt_errstr(status));
    1825           0 :                 goto out;
    1826             :         }
    1827           0 :         status = cli_close(cli_unix, fnum);
    1828           0 :         if (!NT_STATUS_IS_OK(status)) {
    1829           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    1830           0 :                 goto out;
    1831             :         }
    1832           0 :         fnum = (uint16_t)-1;
    1833             : 
    1834             :         /* Create symlink to real target. */
    1835           0 :         status = cli_posix_symlink(cli_unix,
    1836             :                                    fname_real,
    1837             :                                    fname_real_symlink);
    1838           0 :         if (!NT_STATUS_IS_OK(status)) {
    1839           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1840             :                        fname_real_symlink,
    1841             :                        fname_real,
    1842             :                        nt_errstr(status));
    1843           0 :                 goto out;
    1844             :         }
    1845             : 
    1846             :         /* Now create symlink to non-existing target. */
    1847           0 :         status = cli_posix_symlink(cli_unix,
    1848             :                                    nonexist,
    1849             :                                    nonexist_symlink);
    1850           0 :         if (!NT_STATUS_IS_OK(status)) {
    1851           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1852             :                        nonexist_symlink,
    1853             :                        nonexist,
    1854             :                        nt_errstr(status));
    1855           0 :                 goto out;
    1856             :         }
    1857             : 
    1858           0 :         for (i = 0; i < ARRAY_SIZE(posix_smb1_setpath_array); i++) {
    1859           0 :                 status = do_setpath(frame,
    1860             :                                   cli_unix,
    1861             :                                   fname_real_symlink,
    1862             :                                   i);
    1863           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1864           0 :                         goto out;
    1865             :                 }
    1866           0 :                 status = do_setpath(frame,
    1867             :                                   cli_unix,
    1868             :                                   nonexist_symlink,
    1869             :                                   i);
    1870           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1871           0 :                         goto out;
    1872             :                 }
    1873             :         }
    1874             : 
    1875           0 :         printf("POSIX-SYMLINK-SETPATHINFO test passed\n");
    1876           0 :         correct = true;
    1877             : 
    1878           0 : out:
    1879           0 :         if (fnum != (uint16_t)-1) {
    1880           0 :                 cli_close(cli_unix, fnum);
    1881             :         }
    1882           0 :         cli_posix_unlink(cli_unix, fname_real);
    1883           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1884           0 :         cli_posix_unlink(cli_unix, nonexist);
    1885           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1886             : 
    1887           0 :         if (!torture_close_connection(cli_unix)) {
    1888           0 :                 correct = false;
    1889             :         }
    1890             : 
    1891           0 :         TALLOC_FREE(frame);
    1892           0 :         return correct;
    1893             : }

Generated by: LCOV version 1.14