@@ -5835,6 +5835,104 @@ static bool torture_rename_dir_openfile(struct torture_context *tctx,
58355835 return ret ;
58365836}
58375837
5838+ /*
5839+ * Verifies the lease epoch is not incremented by the server (returns what the
5840+ * client sent in the request) if a lease was not granted ie lease_level=NONE.
5841+ */
5842+ static bool test_lease_epoch (struct torture_context * tctx ,
5843+ struct smb2_tree * tree )
5844+ {
5845+ struct smb2_create c ;
5846+ struct smb2_lease ls1 ;
5847+ struct smb2_handle h1 = {};
5848+ struct smb2_write wr ;
5849+ char dat = 'x' ;
5850+ DATA_BLOB data = (DATA_BLOB ) {.data = (uint8_t * )& dat , .length = 1 };
5851+ struct smb2_lock lck = {0 };
5852+ struct smb2_lock_element el [1 ];
5853+ uint64_t lease1 = 1 ;
5854+ struct GUID create_guid = GUID_random ();
5855+ char * fname = NULL ;
5856+ NTSTATUS status ;
5857+ bool ret = true;
5858+
5859+ fname = talloc_asprintf (tctx , "lease_break-%ld.dat" , random ());
5860+ torture_assert_not_null_goto (tctx , fname , ret , done ,
5861+ "talloc_asprintf failed\n" );
5862+
5863+ c = (struct smb2_create ) {
5864+ .in .desired_access = SEC_RIGHTS_FILE_ALL ,
5865+ .in .share_access = NTCREATEX_SHARE_ACCESS_MASK ,
5866+ .in .create_disposition = NTCREATEX_DISP_OPEN_IF ,
5867+ .in .fname = fname ,
5868+ };
5869+
5870+ status = smb2_create (tree , tctx , & c );
5871+ torture_assert_ntstatus_ok_goto (tctx , status , ret , done ,
5872+ "smb2_create failed\n" );
5873+ h1 = c .out .file .handle ;
5874+
5875+ ZERO_STRUCT (wr );
5876+ wr .in .file .handle = h1 ;
5877+ wr .in .offset = 0 ;
5878+ wr .in .data = data ;
5879+ status = smb2_write (tree , & wr );
5880+ torture_assert_ntstatus_ok (tctx , status , "smb2_write failed\n" );
5881+
5882+ ZERO_ARRAY (el );
5883+ ZERO_STRUCT (lck );
5884+ el [0 ].offset = 0 ;
5885+ el [0 ].length = 1 ;
5886+ el [0 ].flags = SMB2_LOCK_FLAG_EXCLUSIVE |SMB2_LOCK_FLAG_FAIL_IMMEDIATELY ;
5887+ lck .in .locks = el ;
5888+ lck .in .lock_count = 1 ;
5889+ lck .in .file .handle = h1 ;
5890+
5891+ status = smb2_lock (tree , & lck );
5892+ torture_assert_ntstatus_equal_goto (
5893+ tctx , status , NT_STATUS_OK ,
5894+ ret , done , "smb2_lock failed\n" );
5895+
5896+
5897+ smb2_lease_v2_create_share (& c ,
5898+ & ls1 ,
5899+ false,
5900+ fname ,
5901+ smb2_util_share_access ("RWD" ),
5902+ lease1 ,
5903+ NULL ,
5904+ smb2_util_lease_state ("R" ),
5905+ 100 );
5906+ c .in .durable_open_v2 = true;
5907+ c .in .create_guid = create_guid ;
5908+ status = smb2_create (tree , tree , & c );
5909+ torture_assert_ntstatus_ok_goto (tctx , status , ret , done ,
5910+ "smb2_create failed\n" );
5911+
5912+ torture_assert_int_equal_goto (
5913+ tctx ,
5914+ c .out .oplock_level ,
5915+ SMB2_OPLOCK_LEVEL_LEASE ,
5916+ ret , done ,
5917+ "Bad lease level\n" );
5918+ torture_assert_int_equal_goto (
5919+ tctx ,
5920+ c .out .lease_response_v2 .lease_state ,
5921+ 0 ,
5922+ ret , done ,
5923+ "Bad lease level\n" );
5924+ torture_assert_int_equal_goto (
5925+ tctx ,
5926+ c .out .lease_response_v2 .lease_epoch ,
5927+ 100 ,
5928+ ret ,
5929+ done ,
5930+ "Bad lease epoch\n" );
5931+
5932+ done :
5933+ return ret ;
5934+ }
5935+
58385936struct torture_suite * torture_smb2_lease_init (TALLOC_CTX * ctx )
58395937{
58405938 struct torture_suite * suite =
@@ -5896,6 +5994,7 @@ struct torture_suite *torture_smb2_lease_init(TALLOC_CTX *ctx)
58965994 test_initial_delete_disconnect );
58975995 torture_suite_add_2smb2_test (suite , "rename_dir_openfile" ,
58985996 torture_rename_dir_openfile );
5997+ torture_suite_add_1smb2_test (suite , "lease-epoch" , test_lease_epoch );
58995998
59005999 suite -> description = talloc_strdup (suite , "SMB2-LEASE tests" );
59016000
0 commit comments