| 1 | /* 
 | 
|---|
| 2 |    Unix SMB/CIFS implementation.
 | 
|---|
| 3 |    test suite for session setup operations
 | 
|---|
| 4 |    Copyright (C) Andrew Tridgell 2003
 | 
|---|
| 5 |    
 | 
|---|
| 6 |    This program is free software; you can redistribute it and/or modify
 | 
|---|
| 7 |    it under the terms of the GNU General Public License as published by
 | 
|---|
| 8 |    the Free Software Foundation; either version 3 of the License, or
 | 
|---|
| 9 |    (at your option) any later version.
 | 
|---|
| 10 |    
 | 
|---|
| 11 |    This program is distributed in the hope that it will be useful,
 | 
|---|
| 12 |    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
| 13 |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
| 14 |    GNU General Public License for more details.
 | 
|---|
| 15 |    
 | 
|---|
| 16 |    You should have received a copy of the GNU General Public License
 | 
|---|
| 17 |    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
|---|
| 18 | */
 | 
|---|
| 19 | 
 | 
|---|
| 20 | #include "includes.h"
 | 
|---|
| 21 | #include "torture/torture.h"
 | 
|---|
| 22 | #include "libcli/raw/libcliraw.h"
 | 
|---|
| 23 | #include "libcli/raw/raw_proto.h"
 | 
|---|
| 24 | #include "libcli/composite/composite.h"
 | 
|---|
| 25 | #include "libcli/smb_composite/smb_composite.h"
 | 
|---|
| 26 | #include "lib/cmdline/popt_common.h"
 | 
|---|
| 27 | #include "lib/events/events.h"
 | 
|---|
| 28 | #include "libcli/libcli.h"
 | 
|---|
| 29 | #include "torture/util.h"
 | 
|---|
| 30 | #include "auth/credentials/credentials.h"
 | 
|---|
| 31 | #include "param/param.h"
 | 
|---|
| 32 | 
 | 
|---|
| 33 | #define BASEDIR "\\rawcontext"
 | 
|---|
| 34 | 
 | 
|---|
| 35 | #define CHECK_STATUS(status, correct) do { \
 | 
|---|
| 36 |         if (!NT_STATUS_EQUAL(status, correct)) { \
 | 
|---|
| 37 |                 printf("(%s) Incorrect status %s - should be %s\n", \
 | 
|---|
| 38 |                        __location__, nt_errstr(status), nt_errstr(correct)); \
 | 
|---|
| 39 |                 ret = false; \
 | 
|---|
| 40 |                 goto done; \
 | 
|---|
| 41 |         }} while (0)
 | 
|---|
| 42 | 
 | 
|---|
| 43 | #define CHECK_VALUE(v, correct) do { \
 | 
|---|
| 44 |         if ((v) != (correct)) { \
 | 
|---|
| 45 |                 printf("(%s) Incorrect value %s=%d - should be %d\n", \
 | 
|---|
| 46 |                        __location__, #v, v, correct); \
 | 
|---|
| 47 |                 ret = false; \
 | 
|---|
| 48 |                 goto done; \
 | 
|---|
| 49 |         }} while (0)
 | 
|---|
| 50 | 
 | 
|---|
| 51 | #define CHECK_NOT_VALUE(v, correct) do { \
 | 
|---|
| 52 |         if ((v) == (correct)) { \
 | 
|---|
| 53 |                 printf("(%s) Incorrect value %s=%d - should not be %d\n", \
 | 
|---|
| 54 |                        __location__, #v, v, correct); \
 | 
|---|
| 55 |                 ret = false; \
 | 
|---|
| 56 |                 goto done; \
 | 
|---|
| 57 |         }} while (0)
 | 
|---|
| 58 | 
 | 
|---|
| 59 | 
 | 
|---|
| 60 | /*
 | 
|---|
| 61 |   test session ops
 | 
|---|
| 62 | */
 | 
|---|
| 63 | static bool test_session(struct smbcli_state *cli, struct torture_context *tctx)
 | 
|---|
| 64 | {
 | 
|---|
| 65 |         NTSTATUS status;
 | 
|---|
| 66 |         bool ret = true;
 | 
|---|
| 67 |         struct smbcli_session *session;
 | 
|---|
| 68 |         struct smbcli_session *session2;
 | 
|---|
| 69 |         struct smbcli_session *session3;
 | 
|---|
| 70 |         struct smbcli_session *session4;
 | 
|---|
| 71 |         struct cli_credentials *anon_creds;
 | 
|---|
| 72 |         struct smbcli_session *sessions[15];
 | 
|---|
| 73 |         struct composite_context *composite_contexts[15];
 | 
|---|
| 74 |         struct smbcli_tree *tree;
 | 
|---|
| 75 |         struct smb_composite_sesssetup setup;
 | 
|---|
| 76 |         struct smb_composite_sesssetup setups[15];
 | 
|---|
| 77 |         struct gensec_settings *gensec_settings;
 | 
|---|
| 78 |         union smb_open io;
 | 
|---|
| 79 |         union smb_write wr;
 | 
|---|
| 80 |         union smb_close cl;
 | 
|---|
| 81 |         int fnum;
 | 
|---|
| 82 |         const char *fname = BASEDIR "\\test.txt";
 | 
|---|
| 83 |         uint8_t c = 1;
 | 
|---|
| 84 |         int i;
 | 
|---|
| 85 |         struct smbcli_session_options options;
 | 
|---|
| 86 | 
 | 
|---|
| 87 |         printf("TESTING SESSION HANDLING\n");
 | 
|---|
| 88 | 
 | 
|---|
| 89 |         if (!torture_setup_dir(cli, BASEDIR)) {
 | 
|---|
| 90 |                 return false;
 | 
|---|
| 91 |         }
 | 
|---|
| 92 | 
 | 
|---|
| 93 |         printf("create a second security context on the same transport\n");
 | 
|---|
| 94 | 
 | 
|---|
| 95 |         lp_smbcli_session_options(tctx->lp_ctx, &options);
 | 
|---|
| 96 |         gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 | 
|---|
| 97 | 
 | 
|---|
| 98 |         session = smbcli_session_init(cli->transport, tctx, false, options);
 | 
|---|
| 99 | 
 | 
|---|
| 100 |         setup.in.sesskey = cli->transport->negotiate.sesskey;
 | 
|---|
| 101 |         setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
 | 
|---|
| 102 |         setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 | 
|---|
| 103 | 
 | 
|---|
| 104 |         setup.in.credentials = cmdline_credentials;
 | 
|---|
| 105 |         setup.in.gensec_settings = gensec_settings;
 | 
|---|
| 106 | 
 | 
|---|
| 107 |         status = smb_composite_sesssetup(session, &setup);
 | 
|---|
| 108 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 109 |         
 | 
|---|
| 110 |         session->vuid = setup.out.vuid;
 | 
|---|
| 111 | 
 | 
|---|
| 112 |         printf("create a third security context on the same transport, with vuid set\n");
 | 
|---|
| 113 |         session2 = smbcli_session_init(cli->transport, tctx, false, options);
 | 
|---|
| 114 | 
 | 
|---|
| 115 |         session2->vuid = session->vuid;
 | 
|---|
| 116 |         setup.in.sesskey = cli->transport->negotiate.sesskey;
 | 
|---|
| 117 |         setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
 | 
|---|
| 118 |         setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 | 
|---|
| 119 | 
 | 
|---|
| 120 |         setup.in.credentials = cmdline_credentials;
 | 
|---|
| 121 | 
 | 
|---|
| 122 |         status = smb_composite_sesssetup(session2, &setup);
 | 
|---|
| 123 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 124 | 
 | 
|---|
| 125 |         session2->vuid = setup.out.vuid;
 | 
|---|
| 126 |         printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
 | 
|---|
| 127 |         
 | 
|---|
| 128 |         if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
 | 
|---|
| 129 |                 /* Samba4 currently fails this - we need to determine if this insane behaviour is important */
 | 
|---|
| 130 |                 if (session2->vuid == session->vuid) {
 | 
|---|
| 131 |                         printf("server allows the user to re-use an existing vuid in session setup \n");
 | 
|---|
| 132 |                 }
 | 
|---|
| 133 |         } else {
 | 
|---|
| 134 |                 CHECK_NOT_VALUE(session2->vuid, session->vuid);
 | 
|---|
| 135 |         }
 | 
|---|
| 136 |         talloc_free(session2);
 | 
|---|
| 137 | 
 | 
|---|
| 138 |         if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
 | 
|---|
| 139 |                 printf("create a fourth security context on the same transport, without extended security\n");
 | 
|---|
| 140 |                 session3 = smbcli_session_init(cli->transport, tctx, false, options);
 | 
|---|
| 141 | 
 | 
|---|
| 142 |                 session3->vuid = session->vuid;
 | 
|---|
| 143 |                 setup.in.sesskey = cli->transport->negotiate.sesskey;
 | 
|---|
| 144 |                 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
 | 
|---|
| 145 |                 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 | 
|---|
| 146 |         
 | 
|---|
| 147 |                 setup.in.credentials = cmdline_credentials;
 | 
|---|
| 148 | 
 | 
|---|
| 149 |                 status = smb_composite_sesssetup(session3, &setup);
 | 
|---|
| 150 |                 CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE);
 | 
|---|
| 151 | 
 | 
|---|
| 152 |                 printf("create a fouth anonymous security context on the same transport, without extended security\n");
 | 
|---|
| 153 |                 session4 = smbcli_session_init(cli->transport, tctx, false, options);
 | 
|---|
| 154 | 
 | 
|---|
| 155 |                 session4->vuid = session->vuid;
 | 
|---|
| 156 |                 setup.in.sesskey = cli->transport->negotiate.sesskey;
 | 
|---|
| 157 |                 setup.in.capabilities &= ~CAP_EXTENDED_SECURITY; /* force a non extended security login (should fail) */
 | 
|---|
| 158 |                 setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 | 
|---|
| 159 |                 
 | 
|---|
| 160 |                 anon_creds = cli_credentials_init(tctx);
 | 
|---|
| 161 |                 cli_credentials_set_conf(anon_creds, tctx->lp_ctx);
 | 
|---|
| 162 |                 cli_credentials_set_anonymous(anon_creds);
 | 
|---|
| 163 | 
 | 
|---|
| 164 |                 setup.in.credentials = anon_creds;
 | 
|---|
| 165 |         
 | 
|---|
| 166 |                 status = smb_composite_sesssetup(session3, &setup);
 | 
|---|
| 167 |                 CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 168 | 
 | 
|---|
| 169 |                 talloc_free(session4);
 | 
|---|
| 170 |         }
 | 
|---|
| 171 |                 
 | 
|---|
| 172 |         printf("use the same tree as the existing connection\n");
 | 
|---|
| 173 |         tree = smbcli_tree_init(session, tctx, false);
 | 
|---|
| 174 |         tree->tid = cli->tree->tid;
 | 
|---|
| 175 | 
 | 
|---|
| 176 |         printf("create a file using the new vuid\n");
 | 
|---|
| 177 |         io.generic.level = RAW_OPEN_NTCREATEX;
 | 
|---|
| 178 |         io.ntcreatex.in.root_fid = 0;
 | 
|---|
| 179 |         io.ntcreatex.in.flags = 0;
 | 
|---|
| 180 |         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 | 
|---|
| 181 |         io.ntcreatex.in.create_options = 0;
 | 
|---|
| 182 |         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 | 
|---|
| 183 |         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 | 
|---|
| 184 |         io.ntcreatex.in.alloc_size = 0;
 | 
|---|
| 185 |         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 | 
|---|
| 186 |         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 | 
|---|
| 187 |         io.ntcreatex.in.security_flags = 0;
 | 
|---|
| 188 |         io.ntcreatex.in.fname = fname;
 | 
|---|
| 189 |         status = smb_raw_open(tree, tctx, &io);
 | 
|---|
| 190 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 191 |         fnum = io.ntcreatex.out.file.fnum;
 | 
|---|
| 192 | 
 | 
|---|
| 193 |         printf("write using the old vuid\n");
 | 
|---|
| 194 |         wr.generic.level = RAW_WRITE_WRITEX;
 | 
|---|
| 195 |         wr.writex.in.file.fnum = fnum;
 | 
|---|
| 196 |         wr.writex.in.offset = 0;
 | 
|---|
| 197 |         wr.writex.in.wmode = 0;
 | 
|---|
| 198 |         wr.writex.in.remaining = 0;
 | 
|---|
| 199 |         wr.writex.in.count = 1;
 | 
|---|
| 200 |         wr.writex.in.data = &c;
 | 
|---|
| 201 | 
 | 
|---|
| 202 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 203 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 204 | 
 | 
|---|
| 205 |         printf("write with the new vuid\n");
 | 
|---|
| 206 |         status = smb_raw_write(tree, &wr);
 | 
|---|
| 207 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 208 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 209 | 
 | 
|---|
| 210 |         printf("logoff the new vuid\n");
 | 
|---|
| 211 |         status = smb_raw_ulogoff(session);
 | 
|---|
| 212 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 213 | 
 | 
|---|
| 214 |         printf("the new vuid should not now be accessible\n");
 | 
|---|
| 215 |         status = smb_raw_write(tree, &wr);
 | 
|---|
| 216 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 217 | 
 | 
|---|
| 218 |         printf("second logoff for the new vuid should fail\n");
 | 
|---|
| 219 |         status = smb_raw_ulogoff(session);
 | 
|---|
| 220 |         CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV, ERRbaduid));
 | 
|---|
| 221 |         talloc_free(session);
 | 
|---|
| 222 | 
 | 
|---|
| 223 |         printf("the fnum should have been auto-closed\n");
 | 
|---|
| 224 |         cl.close.level = RAW_CLOSE_CLOSE;
 | 
|---|
| 225 |         cl.close.in.file.fnum = fnum;
 | 
|---|
| 226 |         cl.close.in.write_time = 0;
 | 
|---|
| 227 |         status = smb_raw_close(cli->tree, &cl);
 | 
|---|
| 228 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 229 | 
 | 
|---|
| 230 |         printf("create %d secondary security contexts on the same transport\n", 
 | 
|---|
| 231 |                (int)ARRAY_SIZE(sessions));
 | 
|---|
| 232 |         for (i=0; i <ARRAY_SIZE(sessions); i++) {
 | 
|---|
| 233 |                 setups[i].in.sesskey = cli->transport->negotiate.sesskey;
 | 
|---|
| 234 |                 setups[i].in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
 | 
|---|
| 235 |                 setups[i].in.workgroup = lp_workgroup(tctx->lp_ctx);
 | 
|---|
| 236 |                 
 | 
|---|
| 237 |                 setups[i].in.credentials = cmdline_credentials;
 | 
|---|
| 238 |                 setups[i].in.gensec_settings = gensec_settings;
 | 
|---|
| 239 | 
 | 
|---|
| 240 |                 sessions[i] = smbcli_session_init(cli->transport, tctx, false, options);
 | 
|---|
| 241 |                 composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]);
 | 
|---|
| 242 | 
 | 
|---|
| 243 |         }
 | 
|---|
| 244 | 
 | 
|---|
| 245 | 
 | 
|---|
| 246 |         printf("finishing %d secondary security contexts on the same transport\n", 
 | 
|---|
| 247 |                (int)ARRAY_SIZE(sessions));
 | 
|---|
| 248 |         for (i=0; i< ARRAY_SIZE(sessions); i++) {
 | 
|---|
| 249 |                 status = smb_composite_sesssetup_recv(composite_contexts[i]);
 | 
|---|
| 250 |                 CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 251 |                 sessions[i]->vuid = setups[i].out.vuid;
 | 
|---|
| 252 |                 printf("VUID: %d\n", sessions[i]->vuid);
 | 
|---|
| 253 |                 status = smb_raw_ulogoff(sessions[i]);
 | 
|---|
| 254 |                 CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 255 |         }
 | 
|---|
| 256 | 
 | 
|---|
| 257 | 
 | 
|---|
| 258 |         talloc_free(tree);
 | 
|---|
| 259 |         
 | 
|---|
| 260 | done:
 | 
|---|
| 261 |         return ret;
 | 
|---|
| 262 | }
 | 
|---|
| 263 | 
 | 
|---|
| 264 | 
 | 
|---|
| 265 | /*
 | 
|---|
| 266 |   test tree ops
 | 
|---|
| 267 | */
 | 
|---|
| 268 | static bool test_tree(struct smbcli_state *cli, struct torture_context *tctx)
 | 
|---|
| 269 | {
 | 
|---|
| 270 |         NTSTATUS status;
 | 
|---|
| 271 |         bool ret = true;
 | 
|---|
| 272 |         const char *share, *host;
 | 
|---|
| 273 |         struct smbcli_tree *tree;
 | 
|---|
| 274 |         union smb_tcon tcon;
 | 
|---|
| 275 |         union smb_open io;
 | 
|---|
| 276 |         union smb_write wr;
 | 
|---|
| 277 |         union smb_close cl;
 | 
|---|
| 278 |         int fnum;
 | 
|---|
| 279 |         const char *fname = BASEDIR "\\test.txt";
 | 
|---|
| 280 |         uint8_t c = 1;
 | 
|---|
| 281 | 
 | 
|---|
| 282 |         printf("TESTING TREE HANDLING\n");
 | 
|---|
| 283 | 
 | 
|---|
| 284 |         if (!torture_setup_dir(cli, BASEDIR)) {
 | 
|---|
| 285 |                 return false;
 | 
|---|
| 286 |         }
 | 
|---|
| 287 | 
 | 
|---|
| 288 |         share = torture_setting_string(tctx, "share", NULL);
 | 
|---|
| 289 |         host  = torture_setting_string(tctx, "host", NULL);
 | 
|---|
| 290 |         
 | 
|---|
| 291 |         printf("create a second tree context on the same session\n");
 | 
|---|
| 292 |         tree = smbcli_tree_init(cli->session, tctx, false);
 | 
|---|
| 293 | 
 | 
|---|
| 294 |         tcon.generic.level = RAW_TCON_TCONX;
 | 
|---|
| 295 |         tcon.tconx.in.flags = 0;
 | 
|---|
| 296 |         tcon.tconx.in.password = data_blob(NULL, 0);
 | 
|---|
| 297 |         tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
 | 
|---|
| 298 |         tcon.tconx.in.device = "A:";    
 | 
|---|
| 299 |         status = smb_raw_tcon(tree, tctx, &tcon);
 | 
|---|
| 300 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 301 |         
 | 
|---|
| 302 | 
 | 
|---|
| 303 |         tree->tid = tcon.tconx.out.tid;
 | 
|---|
| 304 |         printf("tid1=%d tid2=%d\n", cli->tree->tid, tree->tid);
 | 
|---|
| 305 | 
 | 
|---|
| 306 |         printf("try a tconx with a bad device type\n");
 | 
|---|
| 307 |         tcon.tconx.in.device = "FOO";   
 | 
|---|
| 308 |         status = smb_raw_tcon(tree, tctx, &tcon);
 | 
|---|
| 309 |         CHECK_STATUS(status, NT_STATUS_BAD_DEVICE_TYPE);
 | 
|---|
| 310 | 
 | 
|---|
| 311 | 
 | 
|---|
| 312 |         printf("create a file using the new tid\n");
 | 
|---|
| 313 |         io.generic.level = RAW_OPEN_NTCREATEX;
 | 
|---|
| 314 |         io.ntcreatex.in.root_fid = 0;
 | 
|---|
| 315 |         io.ntcreatex.in.flags = 0;
 | 
|---|
| 316 |         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 | 
|---|
| 317 |         io.ntcreatex.in.create_options = 0;
 | 
|---|
| 318 |         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 | 
|---|
| 319 |         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 | 
|---|
| 320 |         io.ntcreatex.in.alloc_size = 0;
 | 
|---|
| 321 |         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 | 
|---|
| 322 |         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 | 
|---|
| 323 |         io.ntcreatex.in.security_flags = 0;
 | 
|---|
| 324 |         io.ntcreatex.in.fname = fname;
 | 
|---|
| 325 |         status = smb_raw_open(tree, tctx, &io);
 | 
|---|
| 326 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 327 |         fnum = io.ntcreatex.out.file.fnum;
 | 
|---|
| 328 | 
 | 
|---|
| 329 |         printf("write using the old tid\n");
 | 
|---|
| 330 |         wr.generic.level = RAW_WRITE_WRITEX;
 | 
|---|
| 331 |         wr.writex.in.file.fnum = fnum;
 | 
|---|
| 332 |         wr.writex.in.offset = 0;
 | 
|---|
| 333 |         wr.writex.in.wmode = 0;
 | 
|---|
| 334 |         wr.writex.in.remaining = 0;
 | 
|---|
| 335 |         wr.writex.in.count = 1;
 | 
|---|
| 336 |         wr.writex.in.data = &c;
 | 
|---|
| 337 | 
 | 
|---|
| 338 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 339 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 340 | 
 | 
|---|
| 341 |         printf("write with the new tid\n");
 | 
|---|
| 342 |         status = smb_raw_write(tree, &wr);
 | 
|---|
| 343 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 344 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 345 | 
 | 
|---|
| 346 |         printf("disconnect the new tid\n");
 | 
|---|
| 347 |         status = smb_tree_disconnect(tree);
 | 
|---|
| 348 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 349 | 
 | 
|---|
| 350 |         printf("the new tid should not now be accessible\n");
 | 
|---|
| 351 |         status = smb_raw_write(tree, &wr);
 | 
|---|
| 352 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 353 | 
 | 
|---|
| 354 |         printf("the fnum should have been auto-closed\n");
 | 
|---|
| 355 |         cl.close.level = RAW_CLOSE_CLOSE;
 | 
|---|
| 356 |         cl.close.in.file.fnum = fnum;
 | 
|---|
| 357 |         cl.close.in.write_time = 0;
 | 
|---|
| 358 |         status = smb_raw_close(cli->tree, &cl);
 | 
|---|
| 359 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 360 | 
 | 
|---|
| 361 |         /* close down the new tree */
 | 
|---|
| 362 |         talloc_free(tree);
 | 
|---|
| 363 |         
 | 
|---|
| 364 | done:
 | 
|---|
| 365 |         return ret;
 | 
|---|
| 366 | }
 | 
|---|
| 367 | 
 | 
|---|
| 368 | /*
 | 
|---|
| 369 |   test tree with ulogoff
 | 
|---|
| 370 |   this demonstrates that a tcon isn't autoclosed by a ulogoff
 | 
|---|
| 371 |   the tcon can be reused using any other valid session later
 | 
|---|
| 372 | */
 | 
|---|
| 373 | static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context *tctx)
 | 
|---|
| 374 | {
 | 
|---|
| 375 |         NTSTATUS status;
 | 
|---|
| 376 |         bool ret = true;
 | 
|---|
| 377 |         const char *share, *host;
 | 
|---|
| 378 |         struct smbcli_session *session1;
 | 
|---|
| 379 |         struct smbcli_session *session2;
 | 
|---|
| 380 |         struct smb_composite_sesssetup setup;
 | 
|---|
| 381 |         struct smbcli_tree *tree;
 | 
|---|
| 382 |         union smb_tcon tcon;
 | 
|---|
| 383 |         union smb_open io;
 | 
|---|
| 384 |         union smb_write wr;
 | 
|---|
| 385 |         int fnum1, fnum2;
 | 
|---|
| 386 |         const char *fname1 = BASEDIR "\\test1.txt";
 | 
|---|
| 387 |         const char *fname2 = BASEDIR "\\test2.txt";
 | 
|---|
| 388 |         uint8_t c = 1;
 | 
|---|
| 389 |         struct smbcli_session_options options;
 | 
|---|
| 390 | 
 | 
|---|
| 391 |         printf("TESTING TREE with ulogoff\n");
 | 
|---|
| 392 | 
 | 
|---|
| 393 |         if (!torture_setup_dir(cli, BASEDIR)) {
 | 
|---|
| 394 |                 return false;
 | 
|---|
| 395 |         }
 | 
|---|
| 396 | 
 | 
|---|
| 397 |         share = torture_setting_string(tctx, "share", NULL);
 | 
|---|
| 398 |         host  = torture_setting_string(tctx, "host", NULL);
 | 
|---|
| 399 | 
 | 
|---|
| 400 |         lp_smbcli_session_options(tctx->lp_ctx, &options);
 | 
|---|
| 401 | 
 | 
|---|
| 402 |         printf("create the first new sessions\n");
 | 
|---|
| 403 |         session1 = smbcli_session_init(cli->transport, tctx, false, options);
 | 
|---|
| 404 |         setup.in.sesskey = cli->transport->negotiate.sesskey;
 | 
|---|
| 405 |         setup.in.capabilities = cli->transport->negotiate.capabilities;
 | 
|---|
| 406 |         setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 | 
|---|
| 407 |         setup.in.credentials = cmdline_credentials;
 | 
|---|
| 408 |         setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 | 
|---|
| 409 |         status = smb_composite_sesssetup(session1, &setup);
 | 
|---|
| 410 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 411 |         session1->vuid = setup.out.vuid;
 | 
|---|
| 412 |         printf("vuid1=%d\n", session1->vuid);
 | 
|---|
| 413 | 
 | 
|---|
| 414 |         printf("create a tree context on the with vuid1\n");
 | 
|---|
| 415 |         tree = smbcli_tree_init(session1, tctx, false);
 | 
|---|
| 416 |         tcon.generic.level = RAW_TCON_TCONX;
 | 
|---|
| 417 |         tcon.tconx.in.flags = 0;
 | 
|---|
| 418 |         tcon.tconx.in.password = data_blob(NULL, 0);
 | 
|---|
| 419 |         tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
 | 
|---|
| 420 |         tcon.tconx.in.device = "A:";
 | 
|---|
| 421 |         status = smb_raw_tcon(tree, tctx, &tcon);
 | 
|---|
| 422 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 423 |         tree->tid = tcon.tconx.out.tid;
 | 
|---|
| 424 |         printf("tid=%d\n", tree->tid);
 | 
|---|
| 425 | 
 | 
|---|
| 426 |         printf("create a file using vuid1\n");
 | 
|---|
| 427 |         io.generic.level = RAW_OPEN_NTCREATEX;
 | 
|---|
| 428 |         io.ntcreatex.in.root_fid = 0;
 | 
|---|
| 429 |         io.ntcreatex.in.flags = 0;
 | 
|---|
| 430 |         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 | 
|---|
| 431 |         io.ntcreatex.in.create_options = 0;
 | 
|---|
| 432 |         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 | 
|---|
| 433 |         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 | 
|---|
| 434 |         io.ntcreatex.in.alloc_size = 0;
 | 
|---|
| 435 |         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 | 
|---|
| 436 |         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 | 
|---|
| 437 |         io.ntcreatex.in.security_flags = 0;
 | 
|---|
| 438 |         io.ntcreatex.in.fname = fname1;
 | 
|---|
| 439 |         status = smb_raw_open(tree, tctx, &io);
 | 
|---|
| 440 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 441 |         fnum1 = io.ntcreatex.out.file.fnum;
 | 
|---|
| 442 | 
 | 
|---|
| 443 |         printf("write using vuid1\n");
 | 
|---|
| 444 |         wr.generic.level = RAW_WRITE_WRITEX;
 | 
|---|
| 445 |         wr.writex.in.file.fnum = fnum1;
 | 
|---|
| 446 |         wr.writex.in.offset = 0;
 | 
|---|
| 447 |         wr.writex.in.wmode = 0;
 | 
|---|
| 448 |         wr.writex.in.remaining = 0;
 | 
|---|
| 449 |         wr.writex.in.count = 1;
 | 
|---|
| 450 |         wr.writex.in.data = &c;
 | 
|---|
| 451 |         status = smb_raw_write(tree, &wr);
 | 
|---|
| 452 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 453 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 454 | 
 | 
|---|
| 455 |         printf("ulogoff the vuid1\n");
 | 
|---|
| 456 |         status = smb_raw_ulogoff(session1);
 | 
|---|
| 457 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 458 | 
 | 
|---|
| 459 |         printf("create the second new sessions\n");
 | 
|---|
| 460 |         session2 = smbcli_session_init(cli->transport, tctx, false, options);
 | 
|---|
| 461 |         setup.in.sesskey = cli->transport->negotiate.sesskey;
 | 
|---|
| 462 |         setup.in.capabilities = cli->transport->negotiate.capabilities;
 | 
|---|
| 463 |         setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 | 
|---|
| 464 |         setup.in.credentials = cmdline_credentials;
 | 
|---|
| 465 |         setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 | 
|---|
| 466 |         status = smb_composite_sesssetup(session2, &setup);
 | 
|---|
| 467 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 468 |         session2->vuid = setup.out.vuid;
 | 
|---|
| 469 |         printf("vuid2=%d\n", session2->vuid);
 | 
|---|
| 470 | 
 | 
|---|
| 471 |         printf("use the existing tree with vuid2\n");
 | 
|---|
| 472 |         tree->session = session2;
 | 
|---|
| 473 | 
 | 
|---|
| 474 |         printf("create a file using vuid2\n");
 | 
|---|
| 475 |         io.generic.level = RAW_OPEN_NTCREATEX;
 | 
|---|
| 476 |         io.ntcreatex.in.root_fid = 0;
 | 
|---|
| 477 |         io.ntcreatex.in.flags = 0;
 | 
|---|
| 478 |         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 | 
|---|
| 479 |         io.ntcreatex.in.create_options = 0;
 | 
|---|
| 480 |         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 | 
|---|
| 481 |         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 | 
|---|
| 482 |         io.ntcreatex.in.alloc_size = 0;
 | 
|---|
| 483 |         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 | 
|---|
| 484 |         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 | 
|---|
| 485 |         io.ntcreatex.in.security_flags = 0;
 | 
|---|
| 486 |         io.ntcreatex.in.fname = fname2;
 | 
|---|
| 487 |         status = smb_raw_open(tree, tctx, &io);
 | 
|---|
| 488 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 489 |         fnum2 = io.ntcreatex.out.file.fnum;
 | 
|---|
| 490 | 
 | 
|---|
| 491 |         printf("write using vuid2\n");
 | 
|---|
| 492 |         wr.generic.level = RAW_WRITE_WRITEX;
 | 
|---|
| 493 |         wr.writex.in.file.fnum = fnum2;
 | 
|---|
| 494 |         wr.writex.in.offset = 0;
 | 
|---|
| 495 |         wr.writex.in.wmode = 0;
 | 
|---|
| 496 |         wr.writex.in.remaining = 0;
 | 
|---|
| 497 |         wr.writex.in.count = 1;
 | 
|---|
| 498 |         wr.writex.in.data = &c;
 | 
|---|
| 499 |         status = smb_raw_write(tree, &wr);
 | 
|---|
| 500 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 501 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 502 | 
 | 
|---|
| 503 |         printf("ulogoff the vuid2\n");
 | 
|---|
| 504 |         status = smb_raw_ulogoff(session2);
 | 
|---|
| 505 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 506 | 
 | 
|---|
| 507 |         /* this also demonstrates that SMBtdis doesn't need a valid vuid */
 | 
|---|
| 508 |         printf("disconnect the existing tree connection\n");
 | 
|---|
| 509 |         status = smb_tree_disconnect(tree);
 | 
|---|
| 510 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 511 | 
 | 
|---|
| 512 |         printf("disconnect the existing tree connection\n");
 | 
|---|
| 513 |         status = smb_tree_disconnect(tree);
 | 
|---|
| 514 |         CHECK_STATUS(status, NT_STATUS_DOS(ERRSRV,ERRinvnid));
 | 
|---|
| 515 | 
 | 
|---|
| 516 |         /* close down the new tree */
 | 
|---|
| 517 |         talloc_free(tree);
 | 
|---|
| 518 |         
 | 
|---|
| 519 | done:
 | 
|---|
| 520 |         return ret;
 | 
|---|
| 521 | }
 | 
|---|
| 522 | 
 | 
|---|
| 523 | /*
 | 
|---|
| 524 |   test pid ops
 | 
|---|
| 525 |   this test demonstrates that exit() only sees the PID
 | 
|---|
| 526 |   used for the open() calls
 | 
|---|
| 527 | */
 | 
|---|
| 528 | static bool test_pid_exit_only_sees_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 | 
|---|
| 529 | {
 | 
|---|
| 530 |         NTSTATUS status;
 | 
|---|
| 531 |         bool ret = true;
 | 
|---|
| 532 |         union smb_open io;
 | 
|---|
| 533 |         union smb_write wr;
 | 
|---|
| 534 |         union smb_close cl;
 | 
|---|
| 535 |         int fnum;
 | 
|---|
| 536 |         const char *fname = BASEDIR "\\test.txt";
 | 
|---|
| 537 |         uint8_t c = 1;
 | 
|---|
| 538 |         uint16_t pid1, pid2;
 | 
|---|
| 539 | 
 | 
|---|
| 540 |         printf("TESTING PID HANDLING exit() only cares about open() PID\n");
 | 
|---|
| 541 | 
 | 
|---|
| 542 |         if (!torture_setup_dir(cli, BASEDIR)) {
 | 
|---|
| 543 |                 return false;
 | 
|---|
| 544 |         }
 | 
|---|
| 545 | 
 | 
|---|
| 546 |         pid1 = cli->session->pid;
 | 
|---|
| 547 |         pid2 = pid1 + 1;
 | 
|---|
| 548 | 
 | 
|---|
| 549 |         printf("pid1=%d pid2=%d\n", pid1, pid2);
 | 
|---|
| 550 | 
 | 
|---|
| 551 |         printf("create a file using pid1\n");
 | 
|---|
| 552 |         cli->session->pid = pid1;
 | 
|---|
| 553 |         io.generic.level = RAW_OPEN_NTCREATEX;
 | 
|---|
| 554 |         io.ntcreatex.in.root_fid = 0;
 | 
|---|
| 555 |         io.ntcreatex.in.flags = 0;
 | 
|---|
| 556 |         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 | 
|---|
| 557 |         io.ntcreatex.in.create_options = 0;
 | 
|---|
| 558 |         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 | 
|---|
| 559 |         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 | 
|---|
| 560 |         io.ntcreatex.in.alloc_size = 0;
 | 
|---|
| 561 |         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 | 
|---|
| 562 |         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 | 
|---|
| 563 |         io.ntcreatex.in.security_flags = 0;
 | 
|---|
| 564 |         io.ntcreatex.in.fname = fname;
 | 
|---|
| 565 |         status = smb_raw_open(cli->tree, mem_ctx, &io);
 | 
|---|
| 566 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 567 |         fnum = io.ntcreatex.out.file.fnum;
 | 
|---|
| 568 | 
 | 
|---|
| 569 |         printf("write using pid2\n");
 | 
|---|
| 570 |         cli->session->pid = pid2;
 | 
|---|
| 571 |         wr.generic.level = RAW_WRITE_WRITEX;
 | 
|---|
| 572 |         wr.writex.in.file.fnum = fnum;
 | 
|---|
| 573 |         wr.writex.in.offset = 0;
 | 
|---|
| 574 |         wr.writex.in.wmode = 0;
 | 
|---|
| 575 |         wr.writex.in.remaining = 0;
 | 
|---|
| 576 |         wr.writex.in.count = 1;
 | 
|---|
| 577 |         wr.writex.in.data = &c;
 | 
|---|
| 578 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 579 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 580 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 581 | 
 | 
|---|
| 582 |         printf("exit pid2\n");
 | 
|---|
| 583 |         cli->session->pid = pid2;
 | 
|---|
| 584 |         status = smb_raw_exit(cli->session);
 | 
|---|
| 585 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 586 | 
 | 
|---|
| 587 |         printf("the fnum should still be accessible via pid2\n");
 | 
|---|
| 588 |         cli->session->pid = pid2;
 | 
|---|
| 589 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 590 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 591 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 592 | 
 | 
|---|
| 593 |         printf("exit pid2\n");
 | 
|---|
| 594 |         cli->session->pid = pid2;
 | 
|---|
| 595 |         status = smb_raw_exit(cli->session);
 | 
|---|
| 596 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 597 | 
 | 
|---|
| 598 |         printf("the fnum should still be accessible via pid1 and pid2\n");
 | 
|---|
| 599 |         cli->session->pid = pid1;
 | 
|---|
| 600 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 601 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 602 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 603 |         cli->session->pid = pid2;
 | 
|---|
| 604 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 605 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 606 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 607 | 
 | 
|---|
| 608 |         printf("exit pid1\n");
 | 
|---|
| 609 |         cli->session->pid = pid1;
 | 
|---|
| 610 |         status = smb_raw_exit(cli->session);
 | 
|---|
| 611 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 612 | 
 | 
|---|
| 613 |         printf("the fnum should not now be accessible via pid1 or pid2\n");
 | 
|---|
| 614 |         cli->session->pid = pid1;
 | 
|---|
| 615 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 616 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 617 |         cli->session->pid = pid2;
 | 
|---|
| 618 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 619 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 620 | 
 | 
|---|
| 621 |         printf("the fnum should have been auto-closed\n");
 | 
|---|
| 622 |         cli->session->pid = pid1;
 | 
|---|
| 623 |         cl.close.level = RAW_CLOSE_CLOSE;
 | 
|---|
| 624 |         cl.close.in.file.fnum = fnum;
 | 
|---|
| 625 |         cl.close.in.write_time = 0;
 | 
|---|
| 626 |         status = smb_raw_close(cli->tree, &cl);
 | 
|---|
| 627 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 628 | 
 | 
|---|
| 629 | done:
 | 
|---|
| 630 |         return ret;
 | 
|---|
| 631 | }
 | 
|---|
| 632 | 
 | 
|---|
| 633 | /*
 | 
|---|
| 634 |   test pid ops with 2 sessions
 | 
|---|
| 635 | */
 | 
|---|
| 636 | static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tctx)
 | 
|---|
| 637 | {
 | 
|---|
| 638 |         NTSTATUS status;
 | 
|---|
| 639 |         bool ret = true;
 | 
|---|
| 640 |         struct smbcli_session *session;
 | 
|---|
| 641 |         struct smb_composite_sesssetup setup;
 | 
|---|
| 642 |         union smb_open io;
 | 
|---|
| 643 |         union smb_write wr;
 | 
|---|
| 644 |         union smb_close cl;
 | 
|---|
| 645 |         int fnum;
 | 
|---|
| 646 |         const char *fname = BASEDIR "\\test.txt";
 | 
|---|
| 647 |         uint8_t c = 1;
 | 
|---|
| 648 |         uint16_t vuid1, vuid2;
 | 
|---|
| 649 |         struct smbcli_session_options options;
 | 
|---|
| 650 | 
 | 
|---|
| 651 |         printf("TESTING PID HANDLING WITH 2 SESSIONS\n");
 | 
|---|
| 652 | 
 | 
|---|
| 653 |         if (!torture_setup_dir(cli, BASEDIR)) {
 | 
|---|
| 654 |                 return false;
 | 
|---|
| 655 |         }
 | 
|---|
| 656 | 
 | 
|---|
| 657 |         lp_smbcli_session_options(tctx->lp_ctx, &options);
 | 
|---|
| 658 | 
 | 
|---|
| 659 |         printf("create a second security context on the same transport\n");
 | 
|---|
| 660 |         session = smbcli_session_init(cli->transport, tctx, false, options);
 | 
|---|
| 661 | 
 | 
|---|
| 662 |         setup.in.sesskey = cli->transport->negotiate.sesskey;
 | 
|---|
| 663 |         setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
 | 
|---|
| 664 |         setup.in.workgroup = lp_workgroup(tctx->lp_ctx);
 | 
|---|
| 665 |         setup.in.credentials = cmdline_credentials;
 | 
|---|
| 666 |         setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx);
 | 
|---|
| 667 | 
 | 
|---|
| 668 |         status = smb_composite_sesssetup(session, &setup);
 | 
|---|
| 669 |         CHECK_STATUS(status, NT_STATUS_OK);     
 | 
|---|
| 670 |         session->vuid = setup.out.vuid;
 | 
|---|
| 671 | 
 | 
|---|
| 672 |         vuid1 = cli->session->vuid;
 | 
|---|
| 673 |         vuid2 = session->vuid;
 | 
|---|
| 674 | 
 | 
|---|
| 675 |         printf("vuid1=%d vuid2=%d\n", vuid1, vuid2);
 | 
|---|
| 676 | 
 | 
|---|
| 677 |         printf("create a file using the vuid1\n");
 | 
|---|
| 678 |         cli->session->vuid = vuid1;
 | 
|---|
| 679 |         io.generic.level = RAW_OPEN_NTCREATEX;
 | 
|---|
| 680 |         io.ntcreatex.in.root_fid = 0;
 | 
|---|
| 681 |         io.ntcreatex.in.flags = 0;
 | 
|---|
| 682 |         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 | 
|---|
| 683 |         io.ntcreatex.in.create_options = 0;
 | 
|---|
| 684 |         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 | 
|---|
| 685 |         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 | 
|---|
| 686 |         io.ntcreatex.in.alloc_size = 0;
 | 
|---|
| 687 |         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 | 
|---|
| 688 |         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 | 
|---|
| 689 |         io.ntcreatex.in.security_flags = 0;
 | 
|---|
| 690 |         io.ntcreatex.in.fname = fname;
 | 
|---|
| 691 |         status = smb_raw_open(cli->tree, tctx, &io);
 | 
|---|
| 692 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 693 |         fnum = io.ntcreatex.out.file.fnum;
 | 
|---|
| 694 | 
 | 
|---|
| 695 |         printf("write using the vuid1 (fnum=%d)\n", fnum);
 | 
|---|
| 696 |         cli->session->vuid = vuid1;
 | 
|---|
| 697 |         wr.generic.level = RAW_WRITE_WRITEX;
 | 
|---|
| 698 |         wr.writex.in.file.fnum = fnum;
 | 
|---|
| 699 |         wr.writex.in.offset = 0;
 | 
|---|
| 700 |         wr.writex.in.wmode = 0;
 | 
|---|
| 701 |         wr.writex.in.remaining = 0;
 | 
|---|
| 702 |         wr.writex.in.count = 1;
 | 
|---|
| 703 |         wr.writex.in.data = &c;
 | 
|---|
| 704 | 
 | 
|---|
| 705 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 706 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 707 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 708 | 
 | 
|---|
| 709 |         printf("exit the pid with vuid2\n");
 | 
|---|
| 710 |         cli->session->vuid = vuid2;
 | 
|---|
| 711 |         status = smb_raw_exit(cli->session);
 | 
|---|
| 712 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 713 | 
 | 
|---|
| 714 |         printf("the fnum should still be accessible\n");
 | 
|---|
| 715 |         cli->session->vuid = vuid1;
 | 
|---|
| 716 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 717 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 718 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 719 | 
 | 
|---|
| 720 |         printf("exit the pid with vuid1\n");
 | 
|---|
| 721 |         cli->session->vuid = vuid1;
 | 
|---|
| 722 |         status = smb_raw_exit(cli->session);
 | 
|---|
| 723 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 724 | 
 | 
|---|
| 725 |         printf("the fnum should not now be accessible\n");
 | 
|---|
| 726 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 727 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 728 | 
 | 
|---|
| 729 |         printf("the fnum should have been auto-closed\n");
 | 
|---|
| 730 |         cl.close.level = RAW_CLOSE_CLOSE;
 | 
|---|
| 731 |         cl.close.in.file.fnum = fnum;
 | 
|---|
| 732 |         cl.close.in.write_time = 0;
 | 
|---|
| 733 |         status = smb_raw_close(cli->tree, &cl);
 | 
|---|
| 734 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 735 | 
 | 
|---|
| 736 | done:
 | 
|---|
| 737 |         return ret;
 | 
|---|
| 738 | }
 | 
|---|
| 739 | 
 | 
|---|
| 740 | /*
 | 
|---|
| 741 |   test pid ops with 2 tcons
 | 
|---|
| 742 | */
 | 
|---|
| 743 | static bool test_pid_2tcon(struct smbcli_state *cli, struct torture_context *tctx)
 | 
|---|
| 744 | {
 | 
|---|
| 745 |         NTSTATUS status;
 | 
|---|
| 746 |         bool ret = true;
 | 
|---|
| 747 |         const char *share, *host;
 | 
|---|
| 748 |         struct smbcli_tree *tree;
 | 
|---|
| 749 |         union smb_tcon tcon;
 | 
|---|
| 750 |         union smb_open io;
 | 
|---|
| 751 |         union smb_write wr;
 | 
|---|
| 752 |         union smb_close cl;
 | 
|---|
| 753 |         int fnum1, fnum2;
 | 
|---|
| 754 |         const char *fname1 = BASEDIR "\\test1.txt";
 | 
|---|
| 755 |         const char *fname2 = BASEDIR "\\test2.txt";
 | 
|---|
| 756 |         uint8_t c = 1;
 | 
|---|
| 757 |         uint16_t tid1, tid2;
 | 
|---|
| 758 | 
 | 
|---|
| 759 |         printf("TESTING PID HANDLING WITH 2 TCONS\n");
 | 
|---|
| 760 | 
 | 
|---|
| 761 |         if (!torture_setup_dir(cli, BASEDIR)) {
 | 
|---|
| 762 |                 return false;
 | 
|---|
| 763 |         }
 | 
|---|
| 764 | 
 | 
|---|
| 765 |         share = torture_setting_string(tctx, "share", NULL);
 | 
|---|
| 766 |         host  = torture_setting_string(tctx, "host", NULL);
 | 
|---|
| 767 |         
 | 
|---|
| 768 |         printf("create a second tree context on the same session\n");
 | 
|---|
| 769 |         tree = smbcli_tree_init(cli->session, tctx, false);
 | 
|---|
| 770 | 
 | 
|---|
| 771 |         tcon.generic.level = RAW_TCON_TCONX;
 | 
|---|
| 772 |         tcon.tconx.in.flags = 0;
 | 
|---|
| 773 |         tcon.tconx.in.password = data_blob(NULL, 0);
 | 
|---|
| 774 |         tcon.tconx.in.path = talloc_asprintf(tctx, "\\\\%s\\%s", host, share);
 | 
|---|
| 775 |         tcon.tconx.in.device = "A:";    
 | 
|---|
| 776 |         status = smb_raw_tcon(tree, tctx, &tcon);
 | 
|---|
| 777 |         CHECK_STATUS(status, NT_STATUS_OK);     
 | 
|---|
| 778 | 
 | 
|---|
| 779 |         tree->tid = tcon.tconx.out.tid;
 | 
|---|
| 780 | 
 | 
|---|
| 781 |         tid1 = cli->tree->tid;
 | 
|---|
| 782 |         tid2 = tree->tid;
 | 
|---|
| 783 |         printf("tid1=%d tid2=%d\n", tid1, tid2);
 | 
|---|
| 784 | 
 | 
|---|
| 785 |         printf("create a file using the tid1\n");
 | 
|---|
| 786 |         cli->tree->tid = tid1;
 | 
|---|
| 787 |         io.generic.level = RAW_OPEN_NTCREATEX;
 | 
|---|
| 788 |         io.ntcreatex.in.root_fid = 0;
 | 
|---|
| 789 |         io.ntcreatex.in.flags = 0;
 | 
|---|
| 790 |         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 | 
|---|
| 791 |         io.ntcreatex.in.create_options = 0;
 | 
|---|
| 792 |         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 | 
|---|
| 793 |         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 | 
|---|
| 794 |         io.ntcreatex.in.alloc_size = 0;
 | 
|---|
| 795 |         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 | 
|---|
| 796 |         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 | 
|---|
| 797 |         io.ntcreatex.in.security_flags = 0;
 | 
|---|
| 798 |         io.ntcreatex.in.fname = fname1;
 | 
|---|
| 799 |         status = smb_raw_open(cli->tree, tctx, &io);
 | 
|---|
| 800 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 801 |         fnum1 = io.ntcreatex.out.file.fnum;
 | 
|---|
| 802 | 
 | 
|---|
| 803 |         printf("write using the tid1\n");
 | 
|---|
| 804 |         wr.generic.level = RAW_WRITE_WRITEX;
 | 
|---|
| 805 |         wr.writex.in.file.fnum = fnum1;
 | 
|---|
| 806 |         wr.writex.in.offset = 0;
 | 
|---|
| 807 |         wr.writex.in.wmode = 0;
 | 
|---|
| 808 |         wr.writex.in.remaining = 0;
 | 
|---|
| 809 |         wr.writex.in.count = 1;
 | 
|---|
| 810 |         wr.writex.in.data = &c;
 | 
|---|
| 811 | 
 | 
|---|
| 812 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 813 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 814 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 815 | 
 | 
|---|
| 816 |         printf("create a file using the tid2\n");
 | 
|---|
| 817 |         cli->tree->tid = tid2;
 | 
|---|
| 818 |         io.generic.level = RAW_OPEN_NTCREATEX;
 | 
|---|
| 819 |         io.ntcreatex.in.root_fid = 0;
 | 
|---|
| 820 |         io.ntcreatex.in.flags = 0;
 | 
|---|
| 821 |         io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
 | 
|---|
| 822 |         io.ntcreatex.in.create_options = 0;
 | 
|---|
| 823 |         io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
 | 
|---|
| 824 |         io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
 | 
|---|
| 825 |         io.ntcreatex.in.alloc_size = 0;
 | 
|---|
| 826 |         io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 | 
|---|
| 827 |         io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
 | 
|---|
| 828 |         io.ntcreatex.in.security_flags = 0;
 | 
|---|
| 829 |         io.ntcreatex.in.fname = fname2;
 | 
|---|
| 830 |         status = smb_raw_open(cli->tree, tctx, &io);
 | 
|---|
| 831 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 832 |         fnum2 = io.ntcreatex.out.file.fnum;
 | 
|---|
| 833 | 
 | 
|---|
| 834 |         printf("write using the tid2\n");
 | 
|---|
| 835 |         wr.generic.level = RAW_WRITE_WRITEX;
 | 
|---|
| 836 |         wr.writex.in.file.fnum = fnum2;
 | 
|---|
| 837 |         wr.writex.in.offset = 0;
 | 
|---|
| 838 |         wr.writex.in.wmode = 0;
 | 
|---|
| 839 |         wr.writex.in.remaining = 0;
 | 
|---|
| 840 |         wr.writex.in.count = 1;
 | 
|---|
| 841 |         wr.writex.in.data = &c;
 | 
|---|
| 842 | 
 | 
|---|
| 843 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 844 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 845 |         CHECK_VALUE(wr.writex.out.nwritten, 1);
 | 
|---|
| 846 | 
 | 
|---|
| 847 |         printf("exit the pid\n");
 | 
|---|
| 848 |         status = smb_raw_exit(cli->session);
 | 
|---|
| 849 |         CHECK_STATUS(status, NT_STATUS_OK);
 | 
|---|
| 850 | 
 | 
|---|
| 851 |         printf("the fnum1 on tid1 should not be accessible\n");
 | 
|---|
| 852 |         cli->tree->tid = tid1;
 | 
|---|
| 853 |         wr.writex.in.file.fnum = fnum1;
 | 
|---|
| 854 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 855 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 856 | 
 | 
|---|
| 857 |         printf("the fnum1 on tid1 should have been auto-closed\n");
 | 
|---|
| 858 |         cl.close.level = RAW_CLOSE_CLOSE;
 | 
|---|
| 859 |         cl.close.in.file.fnum = fnum1;
 | 
|---|
| 860 |         cl.close.in.write_time = 0;
 | 
|---|
| 861 |         status = smb_raw_close(cli->tree, &cl);
 | 
|---|
| 862 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 863 | 
 | 
|---|
| 864 |         printf("the fnum2 on tid2 should not be accessible\n");
 | 
|---|
| 865 |         cli->tree->tid = tid2;
 | 
|---|
| 866 |         wr.writex.in.file.fnum = fnum2;
 | 
|---|
| 867 |         status = smb_raw_write(cli->tree, &wr);
 | 
|---|
| 868 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 869 | 
 | 
|---|
| 870 |         printf("the fnum2 on tid2 should have been auto-closed\n");
 | 
|---|
| 871 |         cl.close.level = RAW_CLOSE_CLOSE;
 | 
|---|
| 872 |         cl.close.in.file.fnum = fnum2;
 | 
|---|
| 873 |         cl.close.in.write_time = 0;
 | 
|---|
| 874 |         status = smb_raw_close(cli->tree, &cl);
 | 
|---|
| 875 |         CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 | 
|---|
| 876 | 
 | 
|---|
| 877 | done:
 | 
|---|
| 878 |         return ret;
 | 
|---|
| 879 | }
 | 
|---|
| 880 | 
 | 
|---|
| 881 | 
 | 
|---|
| 882 | /* 
 | 
|---|
| 883 |    basic testing of session/tree context calls
 | 
|---|
| 884 | */
 | 
|---|
| 885 | static bool torture_raw_context_int(struct torture_context *tctx, 
 | 
|---|
| 886 |                                                                         struct smbcli_state *cli)
 | 
|---|
| 887 | {
 | 
|---|
| 888 |         bool ret = true;
 | 
|---|
| 889 | 
 | 
|---|
| 890 |         ret &= test_session(cli, tctx);
 | 
|---|
| 891 |         ret &= test_tree(cli, tctx);
 | 
|---|
| 892 |         ret &= test_tree_ulogoff(cli, tctx);
 | 
|---|
| 893 |         ret &= test_pid_exit_only_sees_open(cli, tctx);
 | 
|---|
| 894 |         ret &= test_pid_2sess(cli, tctx);
 | 
|---|
| 895 |         ret &= test_pid_2tcon(cli, tctx);
 | 
|---|
| 896 | 
 | 
|---|
| 897 |         smb_raw_exit(cli->session);
 | 
|---|
| 898 |         smbcli_deltree(cli->tree, BASEDIR);
 | 
|---|
| 899 | 
 | 
|---|
| 900 |         return ret;
 | 
|---|
| 901 | }
 | 
|---|
| 902 | /* 
 | 
|---|
| 903 |    basic testing of session/tree context calls
 | 
|---|
| 904 | */
 | 
|---|
| 905 | bool torture_raw_context(struct torture_context *torture, 
 | 
|---|
| 906 |                          struct smbcli_state *cli)
 | 
|---|
| 907 | {
 | 
|---|
| 908 |         bool ret = true;
 | 
|---|
| 909 |         if (lp_use_spnego(torture->lp_ctx)) {
 | 
|---|
| 910 |                 ret &= torture_raw_context_int(torture, cli);
 | 
|---|
| 911 |                 lp_set_cmdline(torture->lp_ctx, "use spnego", "False");
 | 
|---|
| 912 |         }
 | 
|---|
| 913 | 
 | 
|---|
| 914 |         ret &= torture_raw_context_int(torture, cli);
 | 
|---|
| 915 | 
 | 
|---|
| 916 |         return ret;
 | 
|---|
| 917 | }
 | 
|---|