root/source4/torture/raw/context.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. test_session
  2. test_tree
  3. test_tree_ulogoff
  4. test_pid_exit_only_sees_open
  5. test_pid_2sess
  6. test_pid_2tcon
  7. torture_raw_context_int
  8. torture_raw_context

   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)
     /* [<][>][^][v][top][bottom][index][help] */
  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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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)
     /* [<][>][^][v][top][bottom][index][help] */
 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, 
     /* [<][>][^][v][top][bottom][index][help] */
 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, 
     /* [<][>][^][v][top][bottom][index][help] */
 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 }

/* [<][>][^][v][top][bottom][index][help] */