LCOV - code coverage report
Current view: top level - source3/torture - test_posix.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 857 0.0 %
Date: 2024-06-13 04:01:37 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_close 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_posix_readlink(cli_unix,
     547             :                                             state[i].name,
     548             :                                             talloc_tos(),
     549             :                                             &target);
     550           0 :                 if (!NT_STATUS_IS_OK(status)) {
     551           0 :                         printf("POSIX readlink on %s failed (%s)\n",
     552             :                                state[i].name, nt_errstr(status));
     553           0 :                         goto out;
     554             :                 }
     555           0 :                 if (strequal(target, state[i].target)) {
     556           0 :                         state[i].ok = true;
     557           0 :                         state[i].returned_size = strlen(target);
     558             :                 }
     559             :         }
     560             : 
     561           0 :         if (!posix_test_entry_check(state,
     562             :                                     symlnk_dangling,
     563             :                                     true,
     564             :                                     strlen(symlnk_dst_dangling)))
     565             :         {
     566           0 :                 goto out;
     567             :         }
     568           0 :         if (!posix_test_entry_check(state,
     569             :                                     symlnk_outside_share,
     570             :                                     true,
     571             :                                     strlen(symlnk_dst_outside_share)))
     572             :         {
     573           0 :                 goto out;
     574             :         }
     575           0 :         if (!posix_test_entry_check(state,
     576             :                                     symlnk_in_share,
     577             :                                     true,
     578             :                                     strlen(symlnk_dst_in_share))) {
     579           0 :                 goto out;
     580             :         }
     581             : 
     582           0 :         printf("POSIX-READLINK test passed\n");
     583           0 :         correct = true;
     584             : 
     585           0 : out:
     586           0 :         cli_posix_unlink(cli_unix, file);
     587           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     588           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     589           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     590             : 
     591           0 :         if (!torture_close_connection(cli_unix)) {
     592           0 :                 correct = false;
     593             :         }
     594             : 
     595           0 :         TALLOC_FREE(frame);
     596           0 :         return correct;
     597             : }
     598             : 
     599             : /*
     600             :   Test POSIX stat of symlinks
     601             :  */
     602           0 : bool run_posix_stat_test(int dummy)
     603             : {
     604           0 :         TALLOC_CTX *frame = NULL;
     605           0 :         struct cli_state *cli_unix = NULL;
     606           0 :         uint16_t fnum = (uint16_t)-1;
     607             :         NTSTATUS status;
     608           0 :         const char *file = "file";
     609           0 :         const char *symlnk_dangling = "dangling";
     610           0 :         const char *symlnk_dst_dangling = "xxxxxxx";
     611           0 :         const char *symlnk_in_share = "symlnk_in_share";
     612           0 :         const char *symlnk_dst_in_share = file;
     613           0 :         const char *symlnk_outside_share = "symlnk_outside_share";
     614           0 :         const char *symlnk_dst_outside_share = "/etc/passwd";
     615           0 :         struct posix_test_entry state[] = {
     616             :                 {
     617             :                         .name = symlnk_dangling,
     618             :                         .target = symlnk_dst_dangling,
     619             :                         .expected = symlnk_dangling,
     620             :                 }, {
     621             :                         .name = symlnk_in_share,
     622             :                         .target = symlnk_dst_in_share,
     623             :                         .expected = symlnk_in_share,
     624             :                 }, {
     625             :                         .name = symlnk_outside_share,
     626             :                         .target = symlnk_dst_outside_share,
     627             :                         .expected = symlnk_outside_share,
     628             :                 }, {
     629             :                         .name = NULL,
     630             :                 }
     631             :         };
     632             :         int i;
     633           0 :         bool correct = false;
     634             : 
     635           0 :         frame = talloc_stackframe();
     636             : 
     637           0 :         printf("Starting POSIX-STAT test\n");
     638             : 
     639           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     640           0 :                 TALLOC_FREE(frame);
     641           0 :                 return false;
     642             :         }
     643             : 
     644           0 :         torture_conn_set_sockopt(cli_unix);
     645             : 
     646           0 :         status = torture_setup_unix_extensions(cli_unix);
     647           0 :         if (!NT_STATUS_IS_OK(status)) {
     648           0 :                 TALLOC_FREE(frame);
     649           0 :                 return false;
     650             :         }
     651             : 
     652           0 :         cli_posix_unlink(cli_unix, file);
     653           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     654           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     655           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     656             : 
     657           0 :         status = cli_posix_open(cli_unix,
     658             :                                 file,
     659             :                                 O_RDWR|O_CREAT,
     660             :                                 0666,
     661             :                                 &fnum);
     662           0 :         if (!NT_STATUS_IS_OK(status)) {
     663           0 :                 printf("cli_posix_open of %s failed error %s\n",
     664             :                        file,
     665             :                        nt_errstr(status));
     666           0 :                 goto out;
     667             :         }
     668             : 
     669           0 :         status = cli_close(cli_unix, fnum);
     670           0 :         if (!NT_STATUS_IS_OK(status)) {
     671           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     672           0 :                 goto out;
     673             :         }
     674           0 :         fnum = (uint16_t)-1;
     675             : 
     676           0 :         for (i = 0; state[i].name != NULL; i++) {
     677           0 :                 status = cli_posix_symlink(cli_unix,
     678             :                                            state[i].target,
     679             :                                            state[i].name);
     680           0 :                 if (!NT_STATUS_IS_OK(status)) {
     681           0 :                         printf("POSIX symlink of %s failed (%s)\n",
     682             :                                symlnk_dangling, nt_errstr(status));
     683           0 :                         goto out;
     684             :                 }
     685             :         }
     686             : 
     687           0 :         for (i = 0; state[i].name != NULL; i++) {
     688             :                 SMB_STRUCT_STAT sbuf;
     689             : 
     690           0 :                 status = cli_posix_stat(cli_unix,
     691             :                                         state[i].name,
     692             :                                         &sbuf);
     693           0 :                 if (!NT_STATUS_IS_OK(status)) {
     694           0 :                         printf("POSIX stat on %s failed (%s)\n",
     695             :                                state[i].name, nt_errstr(status));
     696           0 :                         continue;
     697             :                 }
     698           0 :                 state[i].ok = true;
     699           0 :                 state[i].returned_size = sbuf.st_ex_size;
     700             :         }
     701             : 
     702           0 :         if (!posix_test_entry_check(state,
     703             :                                     symlnk_dangling,
     704             :                                     true,
     705             :                                     strlen(symlnk_dst_dangling)))
     706             :         {
     707           0 :                 goto out;
     708             :         }
     709           0 :         if (!posix_test_entry_check(state,
     710             :                                     symlnk_outside_share,
     711             :                                     true,
     712             :                                     strlen(symlnk_dst_outside_share)))
     713             :         {
     714           0 :                 goto out;
     715             :         }
     716           0 :         if (!posix_test_entry_check(state,
     717             :                                     symlnk_in_share,
     718             :                                     true,
     719             :                                     strlen(symlnk_dst_in_share))) {
     720           0 :                 goto out;
     721             :         }
     722             : 
     723           0 :         printf("POSIX-STAT test passed\n");
     724           0 :         correct = true;
     725             : 
     726           0 : out:
     727           0 :         cli_posix_unlink(cli_unix, file);
     728           0 :         cli_posix_unlink(cli_unix, symlnk_dangling);
     729           0 :         cli_posix_unlink(cli_unix, symlnk_in_share);
     730           0 :         cli_posix_unlink(cli_unix, symlnk_outside_share);
     731             : 
     732           0 :         if (!torture_close_connection(cli_unix)) {
     733           0 :                 correct = false;
     734             :         }
     735             : 
     736           0 :         TALLOC_FREE(frame);
     737           0 :         return correct;
     738             : }
     739             : 
     740             : /*
     741             :   Test Creating files and directories directly
     742             :   under a symlink.
     743             :  */
     744           0 : bool run_posix_symlink_parent_test(int dummy)
     745             : {
     746           0 :         TALLOC_CTX *frame = NULL;
     747           0 :         struct cli_state *cli_unix = NULL;
     748           0 :         uint16_t fnum = (uint16_t)-1;
     749             :         NTSTATUS status;
     750           0 :         const char *parent_dir = "target_dir";
     751           0 :         const char *parent_symlink = "symlink_to_target_dir";
     752           0 :         const char *fname_real = "target_dir/file";
     753           0 :         const char *dname_real = "target_dir/dir";
     754           0 :         const char *fname_link = "symlink_to_target_dir/file";
     755           0 :         const char *dname_link = "symlink_to_target_dir/dir";
     756           0 :         const char *sname_link = "symlink_to_target_dir/symlink";
     757           0 :         const char *hname_link = "symlink_to_target_dir/hardlink";
     758           0 :         bool correct = false;
     759             : 
     760           0 :         frame = talloc_stackframe();
     761             : 
     762           0 :         printf("Starting POSIX-SYMLINK-PARENT test\n");
     763             : 
     764           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     765           0 :                 TALLOC_FREE(frame);
     766           0 :                 return false;
     767             :         }
     768             : 
     769           0 :         torture_conn_set_sockopt(cli_unix);
     770             : 
     771           0 :         status = torture_setup_unix_extensions(cli_unix);
     772           0 :         if (!NT_STATUS_IS_OK(status)) {
     773           0 :                 TALLOC_FREE(frame);
     774           0 :                 return false;
     775             :         }
     776             : 
     777             :         /* Start with a clean slate. */
     778           0 :         cli_posix_unlink(cli_unix, fname_real);
     779           0 :         cli_posix_rmdir(cli_unix, dname_real);
     780           0 :         cli_posix_unlink(cli_unix, fname_link);
     781           0 :         cli_posix_rmdir(cli_unix, dname_link);
     782           0 :         cli_posix_unlink(cli_unix, sname_link);
     783           0 :         cli_posix_unlink(cli_unix, hname_link);
     784           0 :         cli_posix_unlink(cli_unix, parent_symlink);
     785           0 :         cli_posix_rmdir(cli_unix, parent_dir);
     786             : 
     787             :         /* Create parent_dir. */
     788           0 :         status = cli_posix_mkdir(cli_unix, parent_dir, 0777);
     789           0 :         if (!NT_STATUS_IS_OK(status)) {
     790           0 :                 printf("cli_posix_mkdir of %s failed error %s\n",
     791             :                        parent_dir,
     792             :                        nt_errstr(status));
     793           0 :                 goto out;
     794             :         }
     795             :         /* Create symlink to parent_dir. */
     796           0 :         status = cli_posix_symlink(cli_unix,
     797             :                                    parent_dir,
     798             :                                    parent_symlink);
     799           0 :         if (!NT_STATUS_IS_OK(status)) {
     800           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
     801             :                        parent_symlink,
     802             :                        parent_dir,
     803             :                        nt_errstr(status));
     804           0 :                 goto out;
     805             :         }
     806             :         /* Try and create a directory under the symlink. */
     807           0 :         status = cli_posix_mkdir(cli_unix, dname_link, 0777);
     808           0 :         if (!NT_STATUS_IS_OK(status)) {
     809           0 :                 printf("cli_posix_mkdir of %s failed error %s\n",
     810             :                        dname_link,
     811             :                        nt_errstr(status));
     812           0 :                 goto out;
     813             :         }
     814             :         /* Try and create a file under the symlink. */
     815           0 :         status = cli_posix_open(cli_unix,
     816             :                                 fname_link,
     817             :                                 O_RDWR|O_CREAT,
     818             :                                 0666,
     819             :                                 &fnum);
     820           0 :         if (!NT_STATUS_IS_OK(status)) {
     821           0 :                 printf("cli_posix_open of %s failed error %s\n",
     822             :                        fname_link,
     823             :                        nt_errstr(status));
     824           0 :                 goto out;
     825             :         }
     826           0 :         status = cli_close(cli_unix, fnum);
     827           0 :         if (!NT_STATUS_IS_OK(status)) {
     828           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     829           0 :                 goto out;
     830             :         }
     831           0 :         fnum = (uint16_t)-1;
     832             : 
     833             :         /* Try and create a symlink to the file under the symlink. */
     834           0 :         status = cli_posix_symlink(cli_unix,
     835             :                                    fname_link,
     836             :                                    sname_link);
     837           0 :         if (!NT_STATUS_IS_OK(status)) {
     838           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
     839             :                         sname_link,
     840             :                         fname_link,
     841             :                         nt_errstr(status));
     842           0 :                 goto out;
     843             :         }
     844             : 
     845             :         /* Try and create a hardlink to the file under the symlink. */
     846           0 :         status = cli_posix_hardlink(cli_unix,
     847             :                                    fname_link,
     848             :                                    hname_link);
     849           0 :         if (!NT_STATUS_IS_OK(status)) {
     850           0 :                 printf("cli_posix_hardlink of %s -> %s failed error %s\n",
     851             :                         hname_link,
     852             :                         fname_link,
     853             :                         nt_errstr(status));
     854           0 :                 goto out;
     855             :         }
     856             : 
     857             :         /* Ensure we can delete the symlink via the parent symlink */
     858           0 :         status = cli_posix_unlink(cli_unix, sname_link);
     859           0 :         if (!NT_STATUS_IS_OK(status)) {
     860           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
     861             :                        sname_link,
     862             :                        nt_errstr(status));
     863           0 :                 goto out;
     864             :         }
     865             : 
     866             :         /* Ensure we can delete the hardlink via the parent symlink */
     867           0 :         status = cli_posix_unlink(cli_unix, hname_link);
     868           0 :         if (!NT_STATUS_IS_OK(status)) {
     869           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
     870             :                        hname_link,
     871             :                        nt_errstr(status));
     872           0 :                 goto out;
     873             :         }
     874             : 
     875             :         /* Ensure we can delete the directory via the parent symlink */
     876           0 :         status = cli_posix_rmdir(cli_unix, dname_link);
     877           0 :         if (!NT_STATUS_IS_OK(status)) {
     878           0 :                 printf("cli_posix_rmdir of %s failed error %s\n",
     879             :                        dname_link,
     880             :                        nt_errstr(status));
     881           0 :                 goto out;
     882             :         }
     883             :         /* Ensure we can delete the file via the parent symlink */
     884           0 :         status = cli_posix_unlink(cli_unix, fname_link);
     885           0 :         if (!NT_STATUS_IS_OK(status)) {
     886           0 :                 printf("cli_posix_unlink of %s failed error %s\n",
     887             :                        fname_link,
     888             :                        nt_errstr(status));
     889           0 :                 goto out;
     890             :         }
     891             : 
     892           0 :         printf("POSIX-SYMLINK-PARENT test passed\n");
     893           0 :         correct = true;
     894             : 
     895           0 : out:
     896           0 :         if (fnum != (uint16_t)-1) {
     897           0 :                 cli_close(cli_unix, fnum);
     898             :         }
     899           0 :         cli_posix_unlink(cli_unix, fname_real);
     900           0 :         cli_posix_rmdir(cli_unix, dname_real);
     901           0 :         cli_posix_unlink(cli_unix, fname_link);
     902           0 :         cli_posix_rmdir(cli_unix, dname_link);
     903           0 :         cli_posix_unlink(cli_unix, sname_link);
     904           0 :         cli_posix_unlink(cli_unix, hname_link);
     905           0 :         cli_posix_unlink(cli_unix, parent_symlink);
     906           0 :         cli_posix_rmdir(cli_unix, parent_dir);
     907             : 
     908           0 :         if (!torture_close_connection(cli_unix)) {
     909           0 :                 correct = false;
     910             :         }
     911             : 
     912           0 :         TALLOC_FREE(frame);
     913           0 :         return correct;
     914             : }
     915             : 
     916             : /*
     917             :   Ensure we get an error when doing chmod on a symlink,
     918             :   whether it is pointing to a real object or dangling.
     919             :  */
     920           0 : bool run_posix_symlink_chmod_test(int dummy)
     921             : {
     922           0 :         TALLOC_CTX *frame = NULL;
     923           0 :         struct cli_state *cli_unix = NULL;
     924             :         NTSTATUS status;
     925           0 :         uint16_t fnum = (uint16_t)-1;
     926           0 :         const char *fname_real = "file_real";
     927           0 :         const char *fname_real_symlink = "file_real_symlink";
     928           0 :         const char *nonexist = "nonexist";
     929           0 :         const char *nonexist_symlink = "dangling_symlink";
     930           0 :         bool correct = false;
     931             : 
     932           0 :         frame = talloc_stackframe();
     933             : 
     934           0 :         printf("Starting POSIX-SYMLINK-CHMOD test\n");
     935             : 
     936           0 :         if (!torture_open_connection(&cli_unix, 0)) {
     937           0 :                 TALLOC_FREE(frame);
     938           0 :                 return false;
     939             :         }
     940             : 
     941           0 :         torture_conn_set_sockopt(cli_unix);
     942             : 
     943           0 :         status = torture_setup_unix_extensions(cli_unix);
     944           0 :         if (!NT_STATUS_IS_OK(status)) {
     945           0 :                 TALLOC_FREE(frame);
     946           0 :                 return false;
     947             :         }
     948             : 
     949             :         /* Start with a clean slate. */
     950           0 :         cli_posix_unlink(cli_unix, fname_real);
     951           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
     952           0 :         cli_posix_unlink(cli_unix, nonexist);
     953           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
     954             : 
     955             :         /* Create a real file. */
     956           0 :         status = cli_posix_open(cli_unix,
     957             :                                 fname_real,
     958             :                                 O_RDWR|O_CREAT,
     959             :                                 0644,
     960             :                                 &fnum);
     961           0 :         if (!NT_STATUS_IS_OK(status)) {
     962           0 :                 printf("cli_posix_open of %s failed error %s\n",
     963             :                        fname_real,
     964             :                        nt_errstr(status));
     965           0 :                 goto out;
     966             :         }
     967           0 :         status = cli_close(cli_unix, fnum);
     968           0 :         if (!NT_STATUS_IS_OK(status)) {
     969           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
     970           0 :                 goto out;
     971             :         }
     972           0 :         fnum = (uint16_t)-1;
     973             : 
     974             :         /* Create symlink to real target. */
     975           0 :         status = cli_posix_symlink(cli_unix,
     976             :                                    fname_real,
     977             :                                    fname_real_symlink);
     978           0 :         if (!NT_STATUS_IS_OK(status)) {
     979           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
     980             :                        fname_real_symlink,
     981             :                        fname_real,
     982             :                        nt_errstr(status));
     983           0 :                 goto out;
     984             :         }
     985             : 
     986             :         /* We should not be able to chmod symlinks that point to something. */
     987           0 :         status = cli_posix_chmod(cli_unix, fname_real_symlink, 0777);
     988             : 
     989             :         /* This should fail with something other than server crashed. */
     990           0 :         if (NT_STATUS_IS_OK(status)) {
     991           0 :                 printf("cli_posix_chmod of %s succeeded (should have failed)\n",
     992             :                         fname_real_symlink);
     993           0 :                 goto out;
     994             :         }
     995           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
     996             :                 /* Oops. Server crashed. */
     997           0 :                 printf("cli_posix_chmod of %s failed error %s\n",
     998             :                         fname_real_symlink,
     999             :                         nt_errstr(status));
    1000           0 :                 goto out;
    1001             :         }
    1002             :         /* Any other failure is ok. */
    1003             : 
    1004             :         /* Now create symlink to non-existing target. */
    1005           0 :         status = cli_posix_symlink(cli_unix,
    1006             :                                    nonexist,
    1007             :                                    nonexist_symlink);
    1008           0 :         if (!NT_STATUS_IS_OK(status)) {
    1009           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1010             :                        nonexist_symlink,
    1011             :                        nonexist,
    1012             :                        nt_errstr(status));
    1013           0 :                 goto out;
    1014             :         }
    1015             : 
    1016             :         /* We should not be able to chmod symlinks that point to nothing. */
    1017           0 :         status = cli_posix_chmod(cli_unix, nonexist_symlink, 0777);
    1018             : 
    1019             :         /* This should fail with something other than server crashed. */
    1020           0 :         if (NT_STATUS_IS_OK(status)) {
    1021           0 :                 printf("cli_posix_chmod of %s succeeded (should have failed)\n",
    1022             :                         nonexist_symlink);
    1023           0 :                 goto out;
    1024             :         }
    1025           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) {
    1026             :                 /* Oops. Server crashed. */
    1027           0 :                 printf("cli_posix_chmod of %s failed error %s\n",
    1028             :                         nonexist_symlink,
    1029             :                         nt_errstr(status));
    1030           0 :                 goto out;
    1031             :         }
    1032             : 
    1033             :         /* Any other failure is ok. */
    1034           0 :         printf("POSIX-SYMLINK-CHMOD test passed (expected failure was %s)\n",
    1035             :                         nt_errstr(status));
    1036           0 :         correct = true;
    1037             : 
    1038           0 : out:
    1039           0 :         if (fnum != (uint16_t)-1) {
    1040           0 :                 cli_close(cli_unix, fnum);
    1041             :         }
    1042           0 :         cli_posix_unlink(cli_unix, fname_real);
    1043           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1044           0 :         cli_posix_unlink(cli_unix, nonexist);
    1045           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1046             : 
    1047           0 :         if (!torture_close_connection(cli_unix)) {
    1048           0 :                 correct = false;
    1049             :         }
    1050             : 
    1051           0 :         TALLOC_FREE(frame);
    1052           0 :         return correct;
    1053             : }
    1054             : 
    1055             : /*
    1056             :   Ensure we get an ACL containing OI|IO ACE entries
    1057             :   after we add a default POSIX ACL to a directory.
    1058             :   This will only ever be an SMB1 test as it depends
    1059             :   on POSIX ACL semantics.
    1060             :  */
    1061           0 : bool run_posix_dir_default_acl_test(int dummy)
    1062             : {
    1063           0 :         TALLOC_CTX *frame = NULL;
    1064           0 :         struct cli_state *cli_unix = NULL;
    1065             :         NTSTATUS status;
    1066           0 :         uint16_t fnum = (uint16_t)-1;
    1067           0 :         const char *dname = "dir_with_default_acl";
    1068           0 :         bool correct = false;
    1069             :         SMB_STRUCT_STAT sbuf;
    1070           0 :         size_t acl_size = 0;
    1071           0 :         char *aclbuf = NULL;
    1072           0 :         size_t num_file_acls = 0;
    1073           0 :         size_t num_dir_acls = 0;
    1074             :         size_t expected_buflen;
    1075           0 :         uint8_t def_acl[SMB_POSIX_ACL_HEADER_SIZE +
    1076             :                         5*SMB_POSIX_ACL_ENTRY_SIZE] = {0};
    1077           0 :         uint8_t *p = NULL;
    1078           0 :         uint32_t i = 0;
    1079           0 :         struct security_descriptor *sd = NULL;
    1080           0 :         bool got_inherit = false;
    1081             : 
    1082           0 :         frame = talloc_stackframe();
    1083             : 
    1084           0 :         printf("Starting POSIX-DIR-DEFAULT-ACL test\n");
    1085             : 
    1086           0 :         if (!torture_open_connection(&cli_unix, 0)) {
    1087           0 :                 TALLOC_FREE(frame);
    1088           0 :                 return false;
    1089             :         }
    1090             : 
    1091           0 :         torture_conn_set_sockopt(cli_unix);
    1092             : 
    1093           0 :         status = torture_setup_unix_extensions(cli_unix);
    1094           0 :         if (!NT_STATUS_IS_OK(status)) {
    1095           0 :                 TALLOC_FREE(frame);
    1096           0 :                 return false;
    1097             :         }
    1098             : 
    1099             :         /* Start with a clean slate. */
    1100           0 :         cli_posix_unlink(cli_unix, dname);
    1101           0 :         cli_posix_rmdir(cli_unix, dname);
    1102             : 
    1103           0 :         status = cli_posix_mkdir(cli_unix, dname, 0777);
    1104           0 :         if (!NT_STATUS_IS_OK(status)) {
    1105           0 :                 printf("cli_posix_mkdir of %s failed error %s\n",
    1106             :                        dname,
    1107             :                        nt_errstr(status));
    1108           0 :                 goto out;
    1109             :         }
    1110             : 
    1111             :         /* Do a posix stat to get the owner. */
    1112           0 :         status = cli_posix_stat(cli_unix, dname, &sbuf);
    1113           0 :         if (!NT_STATUS_IS_OK(status)) {
    1114           0 :                 printf("cli_posix_stat of %s failed %s\n",
    1115             :                         dname,
    1116             :                         nt_errstr(status));
    1117           0 :                 goto out;
    1118             :         }
    1119             : 
    1120             :         /* Get the ACL on the directory. */
    1121           0 :         status = cli_posix_getacl(cli_unix, dname, frame, &acl_size, &aclbuf);
    1122           0 :         if (!NT_STATUS_IS_OK(status)) {
    1123           0 :                 printf("cli_posix_getacl on %s failed %s\n",
    1124             :                         dname,
    1125             :                         nt_errstr(status));
    1126           0 :                 goto out;
    1127             :         }
    1128             : 
    1129           0 :         if (acl_size < 6 || SVAL(aclbuf,0) != SMB_POSIX_ACL_VERSION) {
    1130           0 :                 printf("%s, unknown POSIX acl version %u.\n",
    1131             :                         dname,
    1132           0 :                         (unsigned int)CVAL(aclbuf,0) );
    1133           0 :                 goto out;
    1134             :         }
    1135             : 
    1136           0 :         num_file_acls = SVAL(aclbuf,2);
    1137           0 :         num_dir_acls = SVAL(aclbuf,4);
    1138             : 
    1139             :         /*
    1140             :          * No overflow check, num_*_acls comes from a 16-bit value,
    1141             :          * and we expect expected_buflen (size_t) to be of at least 32
    1142             :          * bit.
    1143             :          */
    1144           0 :         expected_buflen = SMB_POSIX_ACL_HEADER_SIZE +
    1145           0 :                           SMB_POSIX_ACL_ENTRY_SIZE*(num_file_acls+num_dir_acls);
    1146             : 
    1147           0 :         if (acl_size != expected_buflen) {
    1148           0 :                 printf("%s, incorrect POSIX acl buffer size "
    1149             :                         "(should be %zu, was %zu).\n",
    1150             :                         dname,
    1151             :                         expected_buflen,
    1152             :                         acl_size);
    1153           0 :                 goto out;
    1154             :         }
    1155             : 
    1156           0 :         if (num_dir_acls != 0) {
    1157           0 :                 printf("%s, POSIX default acl already exists"
    1158             :                         "(should be 0, was %zu).\n",
    1159             :                         dname,
    1160             :                         num_dir_acls);
    1161           0 :                 goto out;
    1162             :         }
    1163             : 
    1164             :         /*
    1165             :          * Get the Windows ACL on the directory.
    1166             :          * Make sure there are no inheritable entries.
    1167             :          */
    1168           0 :         status = cli_ntcreate(cli_unix,
    1169             :                                 dname,
    1170             :                                 0,
    1171             :                                 SEC_STD_READ_CONTROL,
    1172             :                                 0,
    1173             :                                 FILE_SHARE_READ|
    1174             :                                         FILE_SHARE_WRITE|
    1175             :                                         FILE_SHARE_DELETE,
    1176             :                                 FILE_OPEN,
    1177             :                                 FILE_DIRECTORY_FILE,
    1178             :                                 0x0,
    1179             :                                 &fnum,
    1180             :                                 NULL);
    1181           0 :         if (!NT_STATUS_IS_OK(status)) {
    1182           0 :                 printf("Failed to open directory %s: %s\n",
    1183             :                         dname,
    1184             :                         nt_errstr(status));
    1185           0 :                 goto out;
    1186             :         }
    1187             : 
    1188           0 :         status = cli_query_security_descriptor(cli_unix,
    1189             :                                                 fnum,
    1190             :                                                 SECINFO_DACL,
    1191             :                                                 frame,
    1192             :                                                 &sd);
    1193           0 :         if (!NT_STATUS_IS_OK(status)) {
    1194           0 :                 printf("Failed to get security descriptor on directory %s: %s\n",
    1195             :                         dname,
    1196             :                         nt_errstr(status));
    1197           0 :                 goto out;
    1198             :         }
    1199             : 
    1200           0 :         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
    1201           0 :                 struct security_ace *ace = &sd->dacl->aces[i];
    1202           0 :                 if (ace->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
    1203             :                                   SEC_ACE_FLAG_CONTAINER_INHERIT)) {
    1204           0 :                         printf("security descritor on directory %s already "
    1205             :                                 "contains inheritance flags\n",
    1206             :                                 dname);
    1207           0 :                         sec_desc_print(NULL, stdout, sd, true);
    1208           0 :                         goto out;
    1209             :                 }
    1210             :         }
    1211             : 
    1212           0 :         TALLOC_FREE(sd);
    1213             : 
    1214             :         /* Construct a new default ACL. */
    1215           0 :         SSVAL(def_acl,0,SMB_POSIX_ACL_VERSION);
    1216           0 :         SSVAL(def_acl,2,SMB_POSIX_IGNORE_ACE_ENTRIES);
    1217           0 :         SSVAL(def_acl,4,5); /* num_dir_acls. */
    1218             : 
    1219           0 :         p = def_acl + SMB_POSIX_ACL_HEADER_SIZE;
    1220             : 
    1221             :         /* USER_OBJ. */
    1222           0 :         SCVAL(p,0,SMB_POSIX_ACL_USER_OBJ); /* tagtype. */
    1223           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1224           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1225             : 
    1226             :         /* GROUP_OBJ. */
    1227           0 :         SCVAL(p,0,SMB_POSIX_ACL_GROUP_OBJ); /* tagtype. */
    1228           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1229           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1230             : 
    1231             :         /* OTHER. */
    1232           0 :         SCVAL(p,0,SMB_POSIX_ACL_OTHER); /* tagtype. */
    1233           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1234           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1235             : 
    1236             :         /* Explicit user. */
    1237           0 :         SCVAL(p,0,SMB_POSIX_ACL_USER); /* tagtype. */
    1238           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1239           0 :         SIVAL(p,2,sbuf.st_ex_uid);
    1240           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1241             : 
    1242             :         /* MASK. */
    1243           0 :         SCVAL(p,0,SMB_POSIX_ACL_MASK); /* tagtype. */
    1244           0 :         SCVAL(p,1,SMB_POSIX_ACL_READ|SMB_POSIX_ACL_WRITE|SMB_POSIX_ACL_EXECUTE);
    1245           0 :         p += SMB_POSIX_ACL_ENTRY_SIZE;
    1246             : 
    1247             :         /* Set the POSIX default ACL. */
    1248           0 :         status = cli_posix_setacl(cli_unix, dname, def_acl, sizeof(def_acl));
    1249           0 :         if (!NT_STATUS_IS_OK(status)) {
    1250           0 :                 printf("cli_posix_setacl on %s failed %s\n",
    1251             :                         dname,
    1252             :                         nt_errstr(status));
    1253           0 :                 goto out;
    1254             :         }
    1255             : 
    1256             :         /*
    1257             :          * Get the Windows ACL on the directory again.
    1258             :          * Now there should be inheritable entries.
    1259             :          */
    1260             : 
    1261           0 :         status = cli_query_security_descriptor(cli_unix,
    1262             :                                                 fnum,
    1263             :                                                 SECINFO_DACL,
    1264             :                                                 frame,
    1265             :                                                 &sd);
    1266           0 :         if (!NT_STATUS_IS_OK(status)) {
    1267           0 :                 printf("Failed (2) to get security descriptor "
    1268             :                         "on directory %s: %s\n",
    1269             :                         dname,
    1270             :                         nt_errstr(status));
    1271           0 :                 goto out;
    1272             :         }
    1273             : 
    1274           0 :         for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
    1275           0 :                 struct security_ace *ace = &sd->dacl->aces[i];
    1276           0 :                 if (ace->flags & (SEC_ACE_FLAG_OBJECT_INHERIT|
    1277             :                                   SEC_ACE_FLAG_CONTAINER_INHERIT)) {
    1278           0 :                         got_inherit = true;
    1279           0 :                         break;
    1280             :                 }
    1281             :         }
    1282             : 
    1283           0 :         if (!got_inherit) {
    1284           0 :                 printf("security descritor on directory %s does not "
    1285             :                         "contain inheritance flags\n",
    1286             :                         dname);
    1287           0 :                 sec_desc_print(NULL, stdout, sd, true);
    1288           0 :                 goto out;
    1289             :         }
    1290             : 
    1291           0 :         cli_close(cli_unix, fnum);
    1292           0 :         fnum = (uint16_t)-1;
    1293           0 :         printf("POSIX-DIR-DEFAULT-ACL test passed\n");
    1294           0 :         correct = true;
    1295             : 
    1296           0 : out:
    1297             : 
    1298           0 :         TALLOC_FREE(sd);
    1299             : 
    1300           0 :         if (fnum != (uint16_t)-1) {
    1301           0 :                 cli_close(cli_unix, fnum);
    1302             :         }
    1303           0 :         cli_posix_unlink(cli_unix, dname);
    1304           0 :         cli_posix_rmdir(cli_unix, dname);
    1305             : 
    1306           0 :         if (!torture_close_connection(cli_unix)) {
    1307           0 :                 correct = false;
    1308             :         }
    1309             : 
    1310           0 :         TALLOC_FREE(frame);
    1311           0 :         return correct;
    1312             : }
    1313             : 
    1314             : /*
    1315             :   Ensure we can rename a symlink whether it is
    1316             :   pointing to a real object or dangling.
    1317             :  */
    1318           0 : bool run_posix_symlink_rename_test(int dummy)
    1319             : {
    1320           0 :         TALLOC_CTX *frame = NULL;
    1321           0 :         struct cli_state *cli_unix = NULL;
    1322             :         NTSTATUS status;
    1323           0 :         uint16_t fnum = (uint16_t)-1;
    1324           0 :         const char *fname_real = "file_real";
    1325           0 :         const char *fname_real_symlink = "file_real_symlink";
    1326           0 :         const char *fname_real_symlink_newname = "rename_file_real_symlink";
    1327           0 :         const char *nonexist = "nonexist";
    1328           0 :         const char *nonexist_symlink = "dangling_symlink";
    1329           0 :         const char *nonexist_symlink_newname = "dangling_symlink_rename";
    1330           0 :         bool correct = false;
    1331             : 
    1332           0 :         frame = talloc_stackframe();
    1333             : 
    1334           0 :         printf("Starting POSIX-SYMLINK-RENAME test\n");
    1335             : 
    1336           0 :         if (!torture_open_connection(&cli_unix, 0)) {
    1337           0 :                 TALLOC_FREE(frame);
    1338           0 :                 return false;
    1339             :         }
    1340             : 
    1341           0 :         torture_conn_set_sockopt(cli_unix);
    1342             : 
    1343           0 :         status = torture_setup_unix_extensions(cli_unix);
    1344           0 :         if (!NT_STATUS_IS_OK(status)) {
    1345           0 :                 TALLOC_FREE(frame);
    1346           0 :                 return false;
    1347             :         }
    1348             : 
    1349             :         /* Start with a clean slate. */
    1350           0 :         cli_posix_unlink(cli_unix, fname_real);
    1351           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1352           0 :         cli_posix_unlink(cli_unix, fname_real_symlink_newname);
    1353           0 :         cli_posix_unlink(cli_unix, nonexist);
    1354           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1355           0 :         cli_posix_unlink(cli_unix, nonexist_symlink_newname);
    1356             : 
    1357             :         /* Create a real file. */
    1358           0 :         status = cli_posix_open(cli_unix,
    1359             :                                 fname_real,
    1360             :                                 O_RDWR|O_CREAT,
    1361             :                                 0644,
    1362             :                                 &fnum);
    1363           0 :         if (!NT_STATUS_IS_OK(status)) {
    1364           0 :                 printf("cli_posix_open of %s failed error %s\n",
    1365             :                        fname_real,
    1366             :                        nt_errstr(status));
    1367           0 :                 goto out;
    1368             :         }
    1369           0 :         status = cli_close(cli_unix, fnum);
    1370           0 :         if (!NT_STATUS_IS_OK(status)) {
    1371           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    1372           0 :                 goto out;
    1373             :         }
    1374           0 :         fnum = (uint16_t)-1;
    1375             : 
    1376             :         /* Create symlink to real target. */
    1377           0 :         status = cli_posix_symlink(cli_unix,
    1378             :                                    fname_real,
    1379             :                                    fname_real_symlink);
    1380           0 :         if (!NT_STATUS_IS_OK(status)) {
    1381           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1382             :                        fname_real_symlink,
    1383             :                        fname_real,
    1384             :                        nt_errstr(status));
    1385           0 :                 goto out;
    1386             :         }
    1387             : 
    1388             :         /* Ensure we can rename the symlink to the real file. */
    1389           0 :         status = cli_rename(cli_unix,
    1390             :                                 fname_real_symlink,
    1391             :                                 fname_real_symlink_newname,
    1392             :                                 false);
    1393           0 :         if (!NT_STATUS_IS_OK(status)) {
    1394           0 :                 printf("cli_rename of %s -> %s failed %s\n",
    1395             :                         fname_real_symlink,
    1396             :                         fname_real_symlink_newname,
    1397             :                         nt_errstr(status));
    1398           0 :                 goto out;
    1399             :         }
    1400             : 
    1401             :         /* Now create symlink to non-existing target. */
    1402           0 :         status = cli_posix_symlink(cli_unix,
    1403             :                                    nonexist,
    1404             :                                    nonexist_symlink);
    1405           0 :         if (!NT_STATUS_IS_OK(status)) {
    1406           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1407             :                        nonexist_symlink,
    1408             :                        nonexist,
    1409             :                        nt_errstr(status));
    1410           0 :                 goto out;
    1411             :         }
    1412             : 
    1413             :         /* Ensure we can rename the dangling symlink. */
    1414           0 :         status = cli_rename(cli_unix,
    1415             :                                 nonexist_symlink,
    1416             :                                 nonexist_symlink_newname,
    1417             :                                 false);
    1418           0 :         if (!NT_STATUS_IS_OK(status)) {
    1419           0 :                 printf("cli_rename of %s -> %s failed %s\n",
    1420             :                         nonexist_symlink,
    1421             :                         nonexist_symlink_newname,
    1422             :                         nt_errstr(status));
    1423           0 :                 goto out;
    1424             :         }
    1425             : 
    1426           0 :         printf("POSIX-SYMLINK-RENAME test passed\n");
    1427           0 :         correct = true;
    1428             : 
    1429           0 : out:
    1430           0 :         if (fnum != (uint16_t)-1) {
    1431           0 :                 cli_close(cli_unix, fnum);
    1432             :         }
    1433           0 :         cli_posix_unlink(cli_unix, fname_real);
    1434           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1435           0 :         cli_posix_unlink(cli_unix, fname_real_symlink_newname);
    1436           0 :         cli_posix_unlink(cli_unix, nonexist);
    1437           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1438           0 :         cli_posix_unlink(cli_unix, nonexist_symlink_newname);
    1439             : 
    1440           0 :         if (!torture_close_connection(cli_unix)) {
    1441           0 :                 correct = false;
    1442             :         }
    1443             : 
    1444           0 :         TALLOC_FREE(frame);
    1445           0 :         return correct;
    1446             : }
    1447             : 
    1448             : /* List of info levels to try with a POSIX symlink path. */
    1449             : 
    1450             : static struct {
    1451             :         uint32_t level;
    1452             :         const char *name;
    1453             : } posix_smb1_qpath_array[] = {
    1454             :   { SMB_INFO_STANDARD,                  "SMB_INFO_STANDARD"},
    1455             :   { SMB_INFO_QUERY_EA_SIZE,             "SMB_INFO_QUERY_EA_SIZE"},
    1456             :   { SMB_INFO_IS_NAME_VALID,             "SMB_INFO_IS_NAME_VALID"},
    1457             :   { SMB_INFO_QUERY_EAS_FROM_LIST,       "SMB_INFO_QUERY_EAS_FROM_LIST"},
    1458             :   { SMB_INFO_QUERY_ALL_EAS,             "SMB_INFO_QUERY_ALL_EAS"},
    1459             :   { SMB_FILE_BASIC_INFORMATION,         "SMB_FILE_BASIC_INFORMATION"},
    1460             :   { SMB_FILE_STANDARD_INFORMATION,      "SMB_FILE_STANDARD_INFORMATION"},
    1461             :   { SMB_FILE_EA_INFORMATION,            "SMB_FILE_EA_INFORMATION"},
    1462             :   { SMB_FILE_ALTERNATE_NAME_INFORMATION,"SMB_FILE_ALTERNATE_NAME_INFORMATION"},
    1463             :   { SMB_QUERY_FILE_NAME_INFO,           "SMB_QUERY_FILE_NAME_INFO"},
    1464             :   { SMB_FILE_NORMALIZED_NAME_INFORMATION,"SMB_FILE_NORMALIZED_NAME_INFORMATION"},
    1465             :   { SMB_FILE_ALLOCATION_INFORMATION,    "SMB_FILE_ALLOCATION_INFORMATION"},
    1466             :   { SMB_FILE_END_OF_FILE_INFORMATION,   "SMB_FILE_END_OF_FILE_INFORMATION"},
    1467             :   { SMB_FILE_ALL_INFORMATION,           "SMB_FILE_ALL_INFORMATION"},
    1468             :   { SMB_FILE_INTERNAL_INFORMATION,      "SMB_FILE_INTERNAL_INFORMATION"},
    1469             :   { SMB_FILE_ACCESS_INFORMATION,        "SMB_FILE_ACCESS_INFORMATION"},
    1470             :   { SMB_FILE_NAME_INFORMATION,          "SMB_FILE_NAME_INFORMATION"},
    1471             :   { SMB_FILE_DISPOSITION_INFORMATION,   "SMB_FILE_DISPOSITION_INFORMATION"},
    1472             :   { SMB_FILE_POSITION_INFORMATION,      "SMB_FILE_POSITION_INFORMATION"},
    1473             :   { SMB_FILE_MODE_INFORMATION,          "SMB_FILE_MODE_INFORMATION"},
    1474             :   { SMB_FILE_ALIGNMENT_INFORMATION,     "SMB_FILE_ALIGNMENT_INFORMATION"},
    1475             :   { SMB_FILE_STREAM_INFORMATION,        "SMB_FILE_STREAM_INFORMATION"},
    1476             :   { SMB_FILE_COMPRESSION_INFORMATION,   "SMB_FILE_COMPRESSION_INFORMATION"},
    1477             :   { SMB_FILE_NETWORK_OPEN_INFORMATION,  "SMB_FILE_NETWORK_OPEN_INFORMATION"},
    1478             :   { SMB_FILE_ATTRIBUTE_TAG_INFORMATION, "SMB_FILE_ATTRIBUTE_TAG_INFORMATION"},
    1479             :   { SMB_QUERY_FILE_UNIX_BASIC,          "SMB_QUERY_FILE_UNIX_BASIC"},
    1480             :   { SMB_QUERY_FILE_UNIX_INFO2,          "SMB_QUERY_FILE_UNIX_INFO2"},
    1481             :   { SMB_QUERY_FILE_UNIX_LINK,           "SMB_QUERY_FILE_UNIX_LINK"},
    1482             :   { SMB_QUERY_POSIX_ACL,                "SMB_QUERY_POSIX_ACL"},
    1483             :   { SMB_QUERY_POSIX_LOCK,               "SMB_QUERY_POSIX_LOCK"},
    1484             : };
    1485             : 
    1486           0 : static NTSTATUS do_qpath(TALLOC_CTX *ctx,
    1487             :                          struct cli_state *cli_unix,
    1488             :                          const char *fname,
    1489             :                          size_t i)
    1490             : {
    1491             :         NTSTATUS status;
    1492             : 
    1493           0 :         if (posix_smb1_qpath_array[i].level ==
    1494             :                         SMB_INFO_QUERY_EAS_FROM_LIST) {
    1495             :                 uint16_t setup;
    1496             :                 uint8_t *param;
    1497             :                 uint8_t data[8];
    1498           0 :                 uint8_t *rparam = NULL;
    1499           0 :                 uint8_t *rdata = NULL;
    1500           0 :                 uint32_t rbytes = 0;
    1501             : 
    1502             :                 /* Set up an EA list with 'a' as the single name. */
    1503           0 :                 SIVAL(data,0, 8);
    1504           0 :                 SCVAL(data,4, 2); /* namelen. */
    1505           0 :                 SCVAL(data,5, 'a');
    1506           0 :                 SCVAL(data,6, '\0'); /* name. */
    1507           0 :                 SCVAL(data,7, '\0'); /* padding. */
    1508             : 
    1509           0 :                 SSVAL(&setup, 0, TRANSACT2_QPATHINFO);
    1510             : 
    1511           0 :                 param = talloc_zero_array(ctx, uint8_t, 6);
    1512           0 :                 if (param == NULL) {
    1513           0 :                         return NT_STATUS_NO_MEMORY;
    1514             :                 }
    1515           0 :                 SSVAL(param, 0, SMB_INFO_QUERY_EAS_FROM_LIST);
    1516           0 :                 param = trans2_bytes_push_str(param,
    1517           0 :                                 smbXcli_conn_use_unicode(cli_unix->conn),
    1518             :                                 fname,
    1519           0 :                                 strlen(fname)+1,
    1520             :                                 NULL);
    1521           0 :                 if (param == NULL) {
    1522           0 :                         return NT_STATUS_NO_MEMORY;
    1523             :                 }
    1524             : 
    1525           0 :                 status = cli_trans(ctx,
    1526             :                                 cli_unix,
    1527             :                                 SMBtrans2,
    1528             :                                 NULL,
    1529             :                                 -1,
    1530             :                                 0,
    1531             :                                 0,
    1532             :                                 &setup, 1, 0,
    1533           0 :                                 param, talloc_get_size(param), talloc_get_size(param),
    1534             :                                 data, 8, 0,
    1535             :                                 NULL,
    1536             :                                 NULL, 0, NULL,
    1537             :                                 &rparam, 0, &rbytes,
    1538             :                                 &rdata, 0, &rbytes);
    1539           0 :                 TALLOC_FREE(rparam);
    1540           0 :                 TALLOC_FREE(rdata);
    1541             :         } else {
    1542           0 :                 uint8_t *rdata = NULL;
    1543           0 :                 uint32_t num_rdata = 0;
    1544             : 
    1545           0 :                 status = cli_qpathinfo(ctx,
    1546             :                                 cli_unix,
    1547             :                                 fname,
    1548           0 :                                 posix_smb1_qpath_array[i].level,
    1549             :                                 0, /* min_rdata */
    1550             :                                 65534, /* max_rdata */
    1551             :                                 &rdata,
    1552             :                                 &num_rdata);
    1553           0 :                 TALLOC_FREE(rdata);
    1554             :         }
    1555             :         /*
    1556             :          * We don't care what came back, so long as the
    1557             :          * server didn't crash.
    1558             :          */
    1559           0 :         if (NT_STATUS_EQUAL(status,
    1560             :                         NT_STATUS_CONNECTION_DISCONNECTED)) {
    1561           0 :                 printf("cli_qpathinfo of %s failed error "
    1562             :                         "NT_STATUS_CONNECTION_DISCONNECTED\n",
    1563             :                         fname);
    1564           0 :                 return status;
    1565             :         }
    1566             : 
    1567           0 :         printf("cli_qpathinfo info %x (%s) of %s got %s "
    1568             :                 "(this is not an error)\n",
    1569           0 :                 (unsigned int)posix_smb1_qpath_array[i].level,
    1570             :                 posix_smb1_qpath_array[i].name,
    1571             :                 fname,
    1572             :                 nt_errstr(status));
    1573             : 
    1574           0 :         return NT_STATUS_OK;
    1575             : }
    1576             : 
    1577             : /*
    1578             :   Ensure we can call SMB1 getpathinfo in a symlink,
    1579             :   pointing to a real object or dangling. We mostly
    1580             :   expect errors, but the server must not crash.
    1581             :  */
    1582           0 : bool run_posix_symlink_getpathinfo_test(int dummy)
    1583             : {
    1584           0 :         TALLOC_CTX *frame = NULL;
    1585           0 :         struct cli_state *cli_unix = NULL;
    1586             :         NTSTATUS status;
    1587           0 :         uint16_t fnum = (uint16_t)-1;
    1588           0 :         const char *fname_real = "file_getpath_real";
    1589           0 :         const char *fname_real_symlink = "file_real_getpath_symlink";
    1590           0 :         const char *nonexist = "nonexist_getpath";
    1591           0 :         const char *nonexist_symlink = "dangling_getpath_symlink";
    1592           0 :         bool correct = false;
    1593             :         size_t i;
    1594             : 
    1595           0 :         frame = talloc_stackframe();
    1596             : 
    1597           0 :         printf("Starting POSIX-SYMLINK-GETPATHINFO test\n");
    1598             : 
    1599           0 :         if (!torture_open_connection(&cli_unix, 0)) {
    1600           0 :                 TALLOC_FREE(frame);
    1601           0 :                 return false;
    1602             :         }
    1603             : 
    1604           0 :         torture_conn_set_sockopt(cli_unix);
    1605             : 
    1606           0 :         status = torture_setup_unix_extensions(cli_unix);
    1607           0 :         if (!NT_STATUS_IS_OK(status)) {
    1608           0 :                 TALLOC_FREE(frame);
    1609           0 :                 return false;
    1610             :         }
    1611             : 
    1612             :         /* Start with a clean slate. */
    1613           0 :         cli_posix_unlink(cli_unix, fname_real);
    1614           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1615           0 :         cli_posix_unlink(cli_unix, nonexist);
    1616           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1617             : 
    1618             :         /* Create a real file. */
    1619           0 :         status = cli_posix_open(cli_unix,
    1620             :                                 fname_real,
    1621             :                                 O_RDWR|O_CREAT,
    1622             :                                 0644,
    1623             :                                 &fnum);
    1624           0 :         if (!NT_STATUS_IS_OK(status)) {
    1625           0 :                 printf("cli_posix_open of %s failed error %s\n",
    1626             :                        fname_real,
    1627             :                        nt_errstr(status));
    1628           0 :                 goto out;
    1629             :         }
    1630           0 :         status = cli_close(cli_unix, fnum);
    1631           0 :         if (!NT_STATUS_IS_OK(status)) {
    1632           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    1633           0 :                 goto out;
    1634             :         }
    1635           0 :         fnum = (uint16_t)-1;
    1636             : 
    1637             :         /* Create symlink to real target. */
    1638           0 :         status = cli_posix_symlink(cli_unix,
    1639             :                                    fname_real,
    1640             :                                    fname_real_symlink);
    1641           0 :         if (!NT_STATUS_IS_OK(status)) {
    1642           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1643             :                        fname_real_symlink,
    1644             :                        fname_real,
    1645             :                        nt_errstr(status));
    1646           0 :                 goto out;
    1647             :         }
    1648             : 
    1649             :         /* Now create symlink to non-existing target. */
    1650           0 :         status = cli_posix_symlink(cli_unix,
    1651             :                                    nonexist,
    1652             :                                    nonexist_symlink);
    1653           0 :         if (!NT_STATUS_IS_OK(status)) {
    1654           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1655             :                        nonexist_symlink,
    1656             :                        nonexist,
    1657             :                        nt_errstr(status));
    1658           0 :                 goto out;
    1659             :         }
    1660             : 
    1661           0 :         for (i = 0; i < ARRAY_SIZE(posix_smb1_qpath_array); i++) {
    1662           0 :                 status = do_qpath(frame,
    1663             :                                   cli_unix,
    1664             :                                   fname_real_symlink,
    1665             :                                   i);
    1666           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1667           0 :                         goto out;
    1668             :                 }
    1669           0 :                 status = do_qpath(frame,
    1670             :                                   cli_unix,
    1671             :                                   nonexist_symlink,
    1672             :                                   i);
    1673           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1674           0 :                         goto out;
    1675             :                 }
    1676             :         }
    1677             : 
    1678           0 :         printf("POSIX-SYMLINK-GETPATHINFO test passed\n");
    1679           0 :         correct = true;
    1680             : 
    1681           0 : out:
    1682           0 :         if (fnum != (uint16_t)-1) {
    1683           0 :                 cli_close(cli_unix, fnum);
    1684             :         }
    1685           0 :         cli_posix_unlink(cli_unix, fname_real);
    1686           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1687           0 :         cli_posix_unlink(cli_unix, nonexist);
    1688           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1689             : 
    1690           0 :         if (!torture_close_connection(cli_unix)) {
    1691           0 :                 correct = false;
    1692             :         }
    1693             : 
    1694           0 :         TALLOC_FREE(frame);
    1695           0 :         return correct;
    1696             : }
    1697             : 
    1698             : /* List of info levels to try with a POSIX symlink path. */
    1699             : 
    1700             : static struct {
    1701             :         uint32_t level;
    1702             :         const char *name;
    1703             :         uint32_t data_len;
    1704             : } posix_smb1_setpath_array[] = {
    1705             :   { SMB_SET_FILE_UNIX_BASIC,    "SMB_SET_FILE_UNIX_BASIC",    100},
    1706             :   { SMB_SET_FILE_UNIX_INFO2,    "SMB_SET_FILE_UNIX_INFO2",    116},
    1707             :   { SMB_SET_FILE_UNIX_LINK,     "SMB_SET_FILE_UNIX_LINK",     8},
    1708             :   { SMB_SET_FILE_UNIX_HLINK,    "SMB_SET_FILE_UNIX_HLINK",    8},
    1709             :   { SMB_SET_POSIX_ACL,          "SMB_SET_POSIX_ACL",          6},
    1710             :   { SMB_SET_POSIX_LOCK,         "SMB_SET_POSIX_LOCK",         24},
    1711             :   { SMB_INFO_STANDARD,          "SMB_INFO_STANDARD",          12},
    1712             :   { SMB_INFO_SET_EA,            "SMB_INFO_SET_EA",            10},
    1713             :   { SMB_FILE_BASIC_INFORMATION, "SMB_FILE_BASIC_INFORMATION", 36},
    1714             :   { SMB_SET_FILE_ALLOCATION_INFO, "SMB_SET_FILE_ALLOCATION_INFO", 8},
    1715             :   { SMB_SET_FILE_END_OF_FILE_INFO,"SMB_SET_FILE_END_OF_FILE_INFO",8},
    1716             :   { SMB_SET_FILE_DISPOSITION_INFO,"SMB_SET_FILE_DISPOSITION_INFO",1},
    1717             :   { SMB_FILE_POSITION_INFORMATION,"SMB_FILE_POSITION_INFORMATION",8},
    1718             :   { SMB_FILE_FULL_EA_INFORMATION, "SMB_FILE_FULL_EA_INFORMATION",10},
    1719             :   { SMB_FILE_MODE_INFORMATION,  "SMB_FILE_MODE_INFORMATION",  4},
    1720             :   { SMB_FILE_SHORT_NAME_INFORMATION,"SMB_FILE_SHORT_NAME_INFORMATION",12},
    1721             :   { SMB_FILE_RENAME_INFORMATION,"SMB_FILE_RENAME_INFORMATION",        20},
    1722             :   { SMB_FILE_LINK_INFORMATION,  "SMB_FILE_LINK_INFORMATION",  20},
    1723             : };
    1724             : 
    1725           0 : static NTSTATUS do_setpath(TALLOC_CTX *ctx,
    1726             :                            struct cli_state *cli_unix,
    1727             :                            const char *fname,
    1728             :                            size_t i)
    1729             : {
    1730             :         NTSTATUS status;
    1731           0 :         uint8_t *data = NULL;
    1732             : 
    1733           0 :         data = talloc_zero_array(ctx,
    1734             :                                  uint8_t,
    1735             :                                  posix_smb1_setpath_array[i].data_len);
    1736           0 :         if (data == NULL) {
    1737           0 :                 return NT_STATUS_NO_MEMORY;
    1738             :         }
    1739             : 
    1740           0 :         status = cli_setpathinfo(cli_unix,
    1741           0 :                         posix_smb1_setpath_array[i].level,
    1742             :                         fname,
    1743             :                         data,
    1744           0 :                         posix_smb1_setpath_array[i].data_len);
    1745           0 :         TALLOC_FREE(data);
    1746             : 
    1747             :         /*
    1748             :          * We don't care what came back, so long as the
    1749             :          * server didn't crash.
    1750             :          */
    1751           0 :         if (NT_STATUS_EQUAL(status,
    1752             :                         NT_STATUS_CONNECTION_DISCONNECTED)) {
    1753           0 :                 printf("cli_setpathinfo info %x (%s) of %s failed"
    1754             :                         "error NT_STATUS_CONNECTION_DISCONNECTED\n",
    1755           0 :                         (unsigned int)posix_smb1_setpath_array[i].level,
    1756             :                         posix_smb1_setpath_array[i].name,
    1757             :                         fname);
    1758           0 :                 return status;
    1759             :         }
    1760             : 
    1761           0 :         printf("cli_setpathinfo info %x (%s) of %s got %s "
    1762             :                 "(this is not an error)\n",
    1763           0 :                 (unsigned int)posix_smb1_setpath_array[i].level,
    1764             :                 posix_smb1_setpath_array[i].name,
    1765             :                 fname,
    1766             :                 nt_errstr(status));
    1767             : 
    1768           0 :         return NT_STATUS_OK;
    1769             : }
    1770             : 
    1771             : /*
    1772             :   Ensure we can call SMB1 setpathinfo in a symlink,
    1773             :   pointing to a real object or dangling. We mostly
    1774             :   expect errors, but the server must not crash.
    1775             :  */
    1776           0 : bool run_posix_symlink_setpathinfo_test(int dummy)
    1777             : {
    1778           0 :         TALLOC_CTX *frame = NULL;
    1779           0 :         struct cli_state *cli_unix = NULL;
    1780             :         NTSTATUS status;
    1781           0 :         uint16_t fnum = (uint16_t)-1;
    1782           0 :         const char *fname_real = "file_setpath_real";
    1783           0 :         const char *fname_real_symlink = "file_real_setpath_symlink";
    1784           0 :         const char *nonexist = "nonexist_setpath";
    1785           0 :         const char *nonexist_symlink = "dangling_setpath_symlink";
    1786           0 :         bool correct = false;
    1787             :         size_t i;
    1788             : 
    1789           0 :         frame = talloc_stackframe();
    1790             : 
    1791           0 :         printf("Starting POSIX-SYMLINK-SETPATHINFO test\n");
    1792             : 
    1793           0 :         if (!torture_open_connection(&cli_unix, 0)) {
    1794           0 :                 TALLOC_FREE(frame);
    1795           0 :                 return false;
    1796             :         }
    1797             : 
    1798           0 :         torture_conn_set_sockopt(cli_unix);
    1799             : 
    1800           0 :         status = torture_setup_unix_extensions(cli_unix);
    1801           0 :         if (!NT_STATUS_IS_OK(status)) {
    1802           0 :                 TALLOC_FREE(frame);
    1803           0 :                 return false;
    1804             :         }
    1805             : 
    1806             :         /* Start with a clean slate. */
    1807           0 :         cli_posix_unlink(cli_unix, fname_real);
    1808           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1809           0 :         cli_posix_unlink(cli_unix, nonexist);
    1810           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1811             : 
    1812             :         /* Create a real file. */
    1813           0 :         status = cli_posix_open(cli_unix,
    1814             :                                 fname_real,
    1815             :                                 O_RDWR|O_CREAT,
    1816             :                                 0644,
    1817             :                                 &fnum);
    1818           0 :         if (!NT_STATUS_IS_OK(status)) {
    1819           0 :                 printf("cli_posix_open of %s failed error %s\n",
    1820             :                        fname_real,
    1821             :                        nt_errstr(status));
    1822           0 :                 goto out;
    1823             :         }
    1824           0 :         status = cli_close(cli_unix, fnum);
    1825           0 :         if (!NT_STATUS_IS_OK(status)) {
    1826           0 :                 printf("cli_close failed %s\n", nt_errstr(status));
    1827           0 :                 goto out;
    1828             :         }
    1829           0 :         fnum = (uint16_t)-1;
    1830             : 
    1831             :         /* Create symlink to real target. */
    1832           0 :         status = cli_posix_symlink(cli_unix,
    1833             :                                    fname_real,
    1834             :                                    fname_real_symlink);
    1835           0 :         if (!NT_STATUS_IS_OK(status)) {
    1836           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1837             :                        fname_real_symlink,
    1838             :                        fname_real,
    1839             :                        nt_errstr(status));
    1840           0 :                 goto out;
    1841             :         }
    1842             : 
    1843             :         /* Now create symlink to non-existing target. */
    1844           0 :         status = cli_posix_symlink(cli_unix,
    1845             :                                    nonexist,
    1846             :                                    nonexist_symlink);
    1847           0 :         if (!NT_STATUS_IS_OK(status)) {
    1848           0 :                 printf("cli_posix_symlink of %s -> %s failed error %s\n",
    1849             :                        nonexist_symlink,
    1850             :                        nonexist,
    1851             :                        nt_errstr(status));
    1852           0 :                 goto out;
    1853             :         }
    1854             : 
    1855           0 :         for (i = 0; i < ARRAY_SIZE(posix_smb1_setpath_array); i++) {
    1856           0 :                 status = do_setpath(frame,
    1857             :                                   cli_unix,
    1858             :                                   fname_real_symlink,
    1859             :                                   i);
    1860           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1861           0 :                         goto out;
    1862             :                 }
    1863           0 :                 status = do_setpath(frame,
    1864             :                                   cli_unix,
    1865             :                                   nonexist_symlink,
    1866             :                                   i);
    1867           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1868           0 :                         goto out;
    1869             :                 }
    1870             :         }
    1871             : 
    1872           0 :         printf("POSIX-SYMLINK-SETPATHINFO test passed\n");
    1873           0 :         correct = true;
    1874             : 
    1875           0 : out:
    1876           0 :         if (fnum != (uint16_t)-1) {
    1877           0 :                 cli_close(cli_unix, fnum);
    1878             :         }
    1879           0 :         cli_posix_unlink(cli_unix, fname_real);
    1880           0 :         cli_posix_unlink(cli_unix, fname_real_symlink);
    1881           0 :         cli_posix_unlink(cli_unix, nonexist);
    1882           0 :         cli_posix_unlink(cli_unix, nonexist_symlink);
    1883             : 
    1884           0 :         if (!torture_close_connection(cli_unix)) {
    1885           0 :                 correct = false;
    1886             :         }
    1887             : 
    1888           0 :         TALLOC_FREE(frame);
    1889           0 :         return correct;
    1890             : }

Generated by: LCOV version 1.13