static bool test_default_acl_posix(struct torture_context *tctx, struct smb2_tree *tree_unused) { struct smb2_tree *tree = NULL; NTSTATUS status; bool ok; bool ret = true; const char *dname = BASEDIR "\\testdir"; const char *fname = BASEDIR "\\testdir\\testfile"; struct smb2_handle fhandle = {{0}}; struct smb2_handle dhandle = {{0}}; union smb_fileinfo q; union smb_setfileinfo set; struct security_descriptor *sd = NULL; struct security_descriptor *exp_sd = NULL; char *owner_sid = NULL; char *group_sid = NULL; ok = torture_smb2_con_share(tctx, "acl_xattr_ign_sysacl_posix", &tree); torture_assert_goto(tctx, ok == true, ret, done, "Unable to connect to 'acl_xattr_ign_sysacl_posix'\n"); ok = smb2_util_setup_dir(tctx, tree, BASEDIR); torture_assert_goto(tctx, ok == true, ret, done, "Unable to setup testdir\n"); ZERO_STRUCT(dhandle); status = torture_smb2_testdir(tree, dname, &dhandle); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "torture_smb2_testdir\n"); torture_comment(tctx, "Get the original sd\n"); ZERO_STRUCT(q); q.query_secdesc.level = RAW_FILEINFO_SEC_DESC; q.query_secdesc.in.file.handle = dhandle; q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP; status = smb2_getinfo_file(tree, tctx, &q); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n"); sd = q.query_secdesc.out.sd; owner_sid = dom_sid_string(tctx, sd->owner_sid); group_sid = dom_sid_string(tctx, sd->group_sid); torture_comment(tctx, "owner [%s] group [%s]\n", owner_sid, group_sid); torture_comment(tctx, "Set ACL with no inheritable ACE\n"); sd = security_descriptor_dacl_create(tctx, 0, NULL, NULL, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_DIR_ALL, 0, NULL); ZERO_STRUCT(set); set.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; set.set_secdesc.in.file.handle = dhandle; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = sd; status = smb2_setinfo_file(tree, &set); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_setinfo_file\n"); TALLOC_FREE(sd); smb2_util_close(tree, dhandle); torture_comment(tctx, "Create file\n"); ZERO_STRUCT(fhandle); status = torture_smb2_testfile(tree, fname, &fhandle); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create_complex_file\n"); torture_comment(tctx, "Query file SD\n"); ZERO_STRUCT(q); q.query_secdesc.level = RAW_FILEINFO_SEC_DESC; q.query_secdesc.in.file.handle = fhandle; q.query_secdesc.in.secinfo_flags = SECINFO_DACL | SECINFO_OWNER | SECINFO_GROUP; status = smb2_getinfo_file(tree, tctx, &q); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file\n"); sd = q.query_secdesc.out.sd; smb2_util_close(tree, fhandle); ZERO_STRUCT(fhandle); torture_comment(tctx, "Checking actual file SD against expected SD\n"); exp_sd = security_descriptor_dacl_create( tctx, 0, owner_sid, group_sid, owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0, group_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0, SID_WORLD, SEC_ACE_TYPE_ACCESS_ALLOWED, FILE_GENERIC_READ|FILE_GENERIC_WRITE|FILE_GENERIC_EXECUTE, 0, SID_NT_SYSTEM, SEC_ACE_TYPE_ACCESS_ALLOWED, SEC_RIGHTS_FILE_ALL, 0, NULL); CHECK_SECURITY_DESCRIPTOR(sd, exp_sd); done: if (!smb2_util_handle_empty(fhandle)) { smb2_util_close(tree, fhandle); } if (!smb2_util_handle_empty(dhandle)) { smb2_util_close(tree, dhandle); } if (tree != NULL) { smb2_deltree(tree, BASEDIR); smb2_tdis(tree); } return ret; }
/** * test renaming after reauth. * compare security descriptors before and after rename/reauth */ bool test_session_reauth5(struct torture_context *tctx, struct smb2_tree *tree) { NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); char dname[256]; char fname[256]; char fname2[256]; struct smb2_handle _dh1; struct smb2_handle *dh1 = NULL; struct smb2_handle _h1; struct smb2_handle *h1 = NULL; struct smb2_create io1; bool ret = true; bool ok; union smb_fileinfo qfinfo; union smb_setfileinfo sfinfo; struct cli_credentials *anon_creds = NULL; uint32_t secinfo_flags = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL | SECINFO_PROTECTED_DACL | SECINFO_UNPROTECTED_DACL; struct security_descriptor *f_sd1; struct security_descriptor *d_sd1 = NULL; struct security_ace ace; struct dom_sid *extra_sid; /* Add some random component to the file name. */ snprintf(dname, 256, "session_reauth5_%s.d", generate_random_str(tctx, 8)); snprintf(fname, 256, "%s\\file.dat", dname); ok = smb2_util_setup_dir(tctx, tree, dname); CHECK_VAL(ok, true); status = torture_smb2_testdir(tree, dname, &_dh1); CHECK_STATUS(status, NT_STATUS_OK); dh1 = &_dh1; smb2_oplock_create_share(&io1, fname, smb2_util_share_access(""), smb2_util_oplock_level("b")); status = smb2_create(tree, mem_ctx, &io1); CHECK_STATUS(status, NT_STATUS_OK); _h1 = io1.out.file.handle; h1 = &_h1; CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b")); /* get the security descriptor */ ZERO_STRUCT(qfinfo); qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC; qfinfo.query_secdesc.in.file.handle = _h1; qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags; status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); f_sd1 = qfinfo.query_secdesc.out.sd; /* re-authenticate as anonymous */ anon_creds = cli_credentials_init_anon(mem_ctx); torture_assert(tctx, (anon_creds != NULL), "talloc error"); status = smb2_session_setup_spnego(tree->session, anon_creds, 0 /* previous_session_id */); CHECK_STATUS(status, NT_STATUS_OK); /* try to rename the file: fails */ snprintf(fname2, 256, "%s\\file2.dat", dname); smb2_util_unlink(tree, fname2); ZERO_STRUCT(sfinfo); sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION; sfinfo.rename_information.in.file.handle = _h1; sfinfo.rename_information.in.overwrite = true; sfinfo.rename_information.in.new_name = fname2; status = smb2_setinfo_file(tree, &sfinfo); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); /* re-authenticate as original user again */ status = smb2_session_setup_spnego(tree->session, cmdline_credentials, 0 /* previous_session_id */); CHECK_STATUS(status, NT_STATUS_OK); /* give full access on the file to anonymous */ extra_sid = dom_sid_parse_talloc(tctx, SID_NT_ANONYMOUS); ZERO_STRUCT(ace); ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED; ace.flags = 0; ace.access_mask = SEC_RIGHTS_FILE_ALL; ace.trustee = *extra_sid; status = security_descriptor_dacl_add(f_sd1, &ace); CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(sfinfo); sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; sfinfo.set_secdesc.in.file.handle = _h1; sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags; sfinfo.set_secdesc.in.sd = f_sd1; status = smb2_setinfo_file(tree, &sfinfo); CHECK_STATUS(status, NT_STATUS_OK); /* re-get the security descriptor */ ZERO_STRUCT(qfinfo); qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC; qfinfo.query_secdesc.in.file.handle = _h1; qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags; status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); /* re-authenticate as anonymous - again */ anon_creds = cli_credentials_init_anon(mem_ctx); torture_assert(tctx, (anon_creds != NULL), "talloc error"); status = smb2_session_setup_spnego(tree->session, anon_creds, 0 /* previous_session_id */); CHECK_STATUS(status, NT_STATUS_OK); /* try to rename the file: fails */ ZERO_STRUCT(sfinfo); sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION; sfinfo.rename_information.in.file.handle = _h1; sfinfo.rename_information.in.overwrite = true; sfinfo.rename_information.in.new_name = fname2; status = smb2_setinfo_file(tree, &sfinfo); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); /* give full access on the parent dir to anonymous */ ZERO_STRUCT(qfinfo); qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC; qfinfo.query_secdesc.in.file.handle = _dh1; qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags; status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); d_sd1 = qfinfo.query_secdesc.out.sd; ZERO_STRUCT(ace); ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED; ace.flags = 0; ace.access_mask = SEC_RIGHTS_FILE_ALL; ace.trustee = *extra_sid; status = security_descriptor_dacl_add(d_sd1, &ace); CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(sfinfo); sfinfo.set_secdesc.level = RAW_SFILEINFO_SEC_DESC; sfinfo.set_secdesc.in.file.handle = _dh1; sfinfo.set_secdesc.in.secinfo_flags = secinfo_flags; sfinfo.set_secdesc.in.secinfo_flags = SECINFO_DACL; sfinfo.set_secdesc.in.sd = d_sd1; status = smb2_setinfo_file(tree, &sfinfo); CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(qfinfo); qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC; qfinfo.query_secdesc.in.file.handle = _dh1; qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags; status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); smb2_util_close(tree, _dh1); dh1 = NULL; /* try to rename the file: still fails */ ZERO_STRUCT(sfinfo); sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION; sfinfo.rename_information.in.file.handle = _h1; sfinfo.rename_information.in.overwrite = true; sfinfo.rename_information.in.new_name = fname2; status = smb2_setinfo_file(tree, &sfinfo); CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); /* re-authenticate as original user - again */ status = smb2_session_setup_spnego(tree->session, cmdline_credentials, 0 /* previous_session_id */); CHECK_STATUS(status, NT_STATUS_OK); /* rename the file - for verification that it works */ ZERO_STRUCT(sfinfo); sfinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION; sfinfo.rename_information.in.file.handle = _h1; sfinfo.rename_information.in.overwrite = true; sfinfo.rename_information.in.new_name = fname2; status = smb2_setinfo_file(tree, &sfinfo); CHECK_STATUS(status, NT_STATUS_OK); /* closs the file, check it is gone and reopen under the new name */ smb2_util_close(tree, _h1); ZERO_STRUCT(io1); smb2_generic_create_share(&io1, NULL /* lease */, false /* dir */, fname, NTCREATEX_DISP_OPEN, smb2_util_share_access(""), smb2_util_oplock_level("b"), 0 /* leasekey */, 0 /* leasestate */); status = smb2_create(tree, mem_ctx, &io1); CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); ZERO_STRUCT(io1); smb2_generic_create_share(&io1, NULL /* lease */, false /* dir */, fname2, NTCREATEX_DISP_OPEN, smb2_util_share_access(""), smb2_util_oplock_level("b"), 0 /* leasekey */, 0 /* leasestate */); status = smb2_create(tree, mem_ctx, &io1); CHECK_STATUS(status, NT_STATUS_OK); _h1 = io1.out.file.handle; h1 = &_h1; CHECK_CREATED(&io1, EXISTED, FILE_ATTRIBUTE_ARCHIVE); CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b")); /* try to access the file via the old handle */ ZERO_STRUCT(qfinfo); qfinfo.query_secdesc.level = RAW_FILEINFO_SEC_DESC; qfinfo.query_secdesc.in.file.handle = _h1; qfinfo.query_secdesc.in.secinfo_flags = secinfo_flags; status = smb2_getinfo_file(tree, mem_ctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); done: if (dh1 != NULL) { smb2_util_close(tree, *dh1); } if (h1 != NULL) { smb2_util_close(tree, *h1); } smb2_deltree(tree, dname); talloc_free(tree); talloc_free(mem_ctx); return ret; }