Exemple #1
0
static bool spoolss_access_setup_sd(struct torture_context *tctx,
                                    struct dcerpc_pipe *p,
                                    const char *printername,
                                    const struct dom_sid *user_sid,
                                    struct security_descriptor **sd_orig)
{
    struct dcerpc_binding_handle *b = p->binding_handle;
    struct policy_handle handle;
    union spoolss_PrinterInfo info;
    struct spoolss_SetPrinterInfoCtr info_ctr;
    struct spoolss_SetPrinterInfo3 info3;
    struct spoolss_DevmodeContainer devmode_ctr;
    struct sec_desc_buf secdesc_ctr;
    struct security_ace *ace;
    struct security_descriptor *sd;

    torture_assert(tctx,
                   test_openprinter_handle(tctx, p, "", printername, "", SEC_FLAG_MAXIMUM_ALLOWED, WERR_OK, &handle),
                   "failed to open printer");

    torture_assert(tctx,
                   test_GetPrinter_level(tctx, b, &handle, 3, &info),
                   "failed to get sd");

    sd = security_descriptor_copy(tctx, info.info3.secdesc);
    *sd_orig = security_descriptor_copy(tctx, info.info3.secdesc);

    ace = talloc_zero(tctx, struct security_ace);

    ace->type		= SEC_ACE_TYPE_ACCESS_ALLOWED;
    ace->flags		= 0;
    ace->access_mask	= PRINTER_ALL_ACCESS;
    ace->trustee		= *user_sid;

    torture_assert_ntstatus_ok(tctx,
                               security_descriptor_dacl_add(sd, ace),
                               "failed to add new ace");

    ace = talloc_zero(tctx, struct security_ace);

    ace->type		= SEC_ACE_TYPE_ACCESS_ALLOWED;
    ace->flags		= SEC_ACE_FLAG_OBJECT_INHERIT |
                      SEC_ACE_FLAG_CONTAINER_INHERIT |
                      SEC_ACE_FLAG_INHERIT_ONLY;
    ace->access_mask	= SEC_GENERIC_ALL;
    ace->trustee		= *user_sid;

    torture_assert_ntstatus_ok(tctx,
                               security_descriptor_dacl_add(sd, ace),
                               "failed to add new ace");

    ZERO_STRUCT(info3);
    ZERO_STRUCT(info_ctr);
    ZERO_STRUCT(devmode_ctr);
    ZERO_STRUCT(secdesc_ctr);

    info_ctr.level = 3;
    info_ctr.info.info3 = &info3;
    secdesc_ctr.sd = sd;

    torture_assert(tctx,
                   test_SetPrinter(tctx, b, &handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
                   "failed to set sd");

    return true;
}
Exemple #2
0
/**
 * 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;
}
Exemple #3
0
/*
  load the current ACL from system.nfs4acl
*/
static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
				   TALLOC_CTX *mem_ctx,
				   struct security_descriptor **psd)
{
	NTSTATUS status;
	struct nfs4acl *acl;
	struct security_descriptor *sd;
	int i, num_ids;
	struct id_map *ids;

	acl = talloc_zero(mem_ctx, struct nfs4acl);
	NT_STATUS_HAVE_NO_MEMORY(acl);

	status = pvfs_xattr_ndr_load(pvfs, mem_ctx, name->full_name, fd, 
				     NFS4ACL_XATTR_NAME,
				     acl, (void *) ndr_pull_nfs4acl);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(acl);
		return status;
	}

	*psd = security_descriptor_initialise(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(*psd);

	sd = *psd;

	sd->type |= acl->a_flags;

	/* the number of ids to map is the acl count plus uid and gid */
	num_ids = acl->a_count +2;
	ids = talloc_array(sd, struct id_map, num_ids);
	NT_STATUS_HAVE_NO_MEMORY(ids);

	ids[0].xid.id = name->st.st_uid;
	ids[0].xid.type = ID_TYPE_UID;
	ids[0].sid = NULL;
	ids[0].status = ID_UNKNOWN;

	ids[1].xid.id = name->st.st_gid;
	ids[1].xid.type = ID_TYPE_GID;
	ids[1].sid = NULL;
	ids[1].status = ID_UNKNOWN;

	for (i=0;i<acl->a_count;i++) {
		struct nfs4ace *a = &acl->ace[i];
		ids[i+2].xid.id = a->e_id;
		if (a->e_flags & ACE4_IDENTIFIER_GROUP) {
			ids[i+2].xid.type = ID_TYPE_GID;
		} else {
			ids[i+2].xid.type = ID_TYPE_UID;
		}
		ids[i+2].sid = NULL;
		ids[i+2].status = ID_UNKNOWN;
	}

	/* Allocate memory for the sids from the security descriptor to be on
	 * the safe side. */
	status = wbc_xids_to_sids(ids, num_ids);
	NT_STATUS_NOT_OK_RETURN(status);

	sd->owner_sid = talloc_steal(sd, ids[0].sid);
	sd->group_sid = talloc_steal(sd, ids[1].sid);

	for (i=0;i<acl->a_count;i++) {
		struct nfs4ace *a = &acl->ace[i];
		struct security_ace ace;
		ace.type = a->e_type;
		ace.flags = a->e_flags;
		ace.access_mask = a->e_mask;
		ace.trustee = *ids[i+2].sid;
		security_descriptor_dacl_add(sd, &ace);
	}

	return NT_STATUS_OK;
}
Exemple #4
0
/*
  try creating with acls
 */
static bool test_create_acl_ext(struct torture_context *tctx, struct smb2_tree *tree, bool test_dir)
{
    bool ret = true;
    struct smb2_create io;
    NTSTATUS status;
    struct security_ace ace;
    struct security_descriptor *sd;
    struct dom_sid *test_sid;
    union smb_fileinfo q = {};
    uint32_t attrib =
        FILE_ATTRIBUTE_HIDDEN |
        FILE_ATTRIBUTE_SYSTEM |
        (test_dir ? FILE_ATTRIBUTE_DIRECTORY : 0);
    NTSTATUS (*delete_func)(struct smb2_tree *, const char *) =
        test_dir ? smb2_util_rmdir : smb2_util_unlink;

    smb2_deltree(tree, FNAME);

    ZERO_STRUCT(io);
    io.in.desired_access     = SEC_FLAG_MAXIMUM_ALLOWED;
    io.in.file_attributes    = FILE_ATTRIBUTE_NORMAL;
    io.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.in.share_access =
        NTCREATEX_SHARE_ACCESS_DELETE |
        NTCREATEX_SHARE_ACCESS_READ |
        NTCREATEX_SHARE_ACCESS_WRITE;
    io.in.create_options = NTCREATEX_OPTIONS_ASYNC_ALERT | 0x00200000 |
                           (test_dir ?  NTCREATEX_OPTIONS_DIRECTORY :
                            (NTCREATEX_OPTIONS_NON_DIRECTORY_FILE));

    io.in.fname = FNAME;

    torture_comment(tctx, "basic create\n");

    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    q.query_secdesc.in.file.handle = io.out.file.handle;
    q.query_secdesc.in.secinfo_flags =
        SECINFO_OWNER |
        SECINFO_GROUP |
        SECINFO_DACL;
    status = smb2_getinfo_file(tree, tctx, &q);
    CHECK_STATUS(status, NT_STATUS_OK);
    sd = q.query_secdesc.out.sd;

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "adding a new ACE\n");
    test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);

    ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
    ace.flags = 0;
    ace.access_mask = SEC_STD_ALL;
    ace.trustee = *test_sid;

    status = security_descriptor_dacl_add(sd, &ace);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "creating a file with an initial ACL\n");

    io.in.sec_desc = sd;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "creating with attributes\n");

    io.in.sec_desc = NULL;
    io.in.file_attributes = attrib;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "creating with attributes and ACL\n");

    io.in.sec_desc = sd;
    io.in.file_attributes = attrib;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
    FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));

    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "creating with attributes, ACL and owner\n");
    sd = security_descriptor_dacl_create(tctx,
                                         0, SID_WORLD, SID_BUILTIN_USERS,
                                         SID_WORLD,
                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
                                         SEC_RIGHTS_FILE_READ | SEC_STD_ALL,
                                         0,
                                         NULL);

    io.in.sec_desc = sd;
    io.in.file_attributes = attrib;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);

    FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, io.out.file.handle, sd));
    FAIL_UNLESS(smb2_util_verify_attrib(tctx, tree, io.out.file.handle, attrib));

done:
    status = smb2_util_close(tree, io.out.file.handle);
    CHECK_STATUS(status, NT_STATUS_OK);
    status = delete_func(tree, FNAME);
    CHECK_STATUS(status, NT_STATUS_OK);

    return ret;
}
Exemple #5
0
/**
 * test setting security descriptor after reauth.
 */
bool test_session_reauth4(struct torture_context *tctx, struct smb2_tree *tree)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char fname[256];
	struct smb2_handle _h1;
	struct smb2_handle *h1 = NULL;
	struct smb2_create io1;
	bool ret = true;
	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 *sd1;
	struct security_ace ace;
	struct dom_sid *extra_sid;

	/* Add some random component to the file name. */
	snprintf(fname, 256, "session_reauth4_%s.dat",
		 generate_random_str(tctx, 8));

	smb2_util_unlink(tree, fname);

	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);

	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);

	/* 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_STD_ALL | SEC_FILE_ALL;
	ace.trustee = *extra_sid;

	status = security_descriptor_dacl_add(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_DACL;
	sfinfo.set_secdesc.in.sd = sd1;

	status = smb2_setinfo_file(tree, &sfinfo);
	CHECK_STATUS(status, NT_STATUS_OK);

	/* 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);

	/* 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);

	ret = true;

done:
	if (h1 != NULL) {
		smb2_util_close(tree, *h1);
	}

	smb2_util_unlink(tree, fname);

	talloc_free(tree);

	talloc_free(mem_ctx);

	return ret;
}
Exemple #6
0
/* basic testing of all SMB2 setinfo calls 
   for each call we test that it succeeds, and where possible test 
   for consistency between the calls. 
*/
BOOL torture_smb2_setinfo(struct torture_context *torture)
{
	struct smb2_tree *tree;
	BOOL ret = True;
	TALLOC_CTX *mem_ctx = talloc_new(NULL);
	struct smb2_handle handle;
	char *fname;
	char *fname_new;
	union smb_fileinfo finfo2;
	union smb_setfileinfo sfinfo;
	struct security_ace ace;
	struct security_descriptor *sd;
	struct dom_sid *test_sid;
	NTSTATUS status, status2=NT_STATUS_OK;
	const char *call_name;
	time_t basetime = (time(NULL) - 86400) & ~1;
	int n = time(NULL) % 100;
	
	ZERO_STRUCT(handle);
	
	fname = talloc_asprintf(mem_ctx, BASEDIR "fnum_test_%d.txt", n);
	fname_new = talloc_asprintf(mem_ctx, BASEDIR "fnum_test_new_%d.txt", n);

	if (!torture_smb2_connection(mem_ctx, &tree)) {
		return False;
	}

#define RECREATE_FILE(fname) do { \
	smb2_util_close(tree, handle); \
	status = smb2_create_complex_file(tree, fname, &handle); \
	if (!NT_STATUS_IS_OK(status)) { \
		printf("(%s) ERROR: open of %s failed (%s)\n", \
		       __location__, fname, nt_errstr(status)); \
		ret = False; \
		goto done; \
	}} while (0)

#define RECREATE_BOTH do { \
		RECREATE_FILE(fname); \
	} while (0)

	RECREATE_BOTH;
	
#define CHECK_CALL(call, rightstatus) do { \
	call_name = #call; \
	sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
	sfinfo.generic.in.file.handle = handle; \
	status = smb2_setinfo_file(tree, &sfinfo); \
	if (!NT_STATUS_EQUAL(status, rightstatus)) { \
		printf("(%s) %s - %s (should be %s)\n", __location__, #call, \
			nt_errstr(status), nt_errstr(rightstatus)); \
		ret = False; \
		goto done; \
	} \
	} while (0)

#define CHECK1(call) \
	do { if (NT_STATUS_IS_OK(status)) { \
		finfo2.generic.level = RAW_FILEINFO_ ## call; \
		finfo2.generic.in.file.handle = handle; \
		status2 = smb2_getinfo_file(tree, mem_ctx, &finfo2); \
		if (!NT_STATUS_IS_OK(status2)) { \
			printf("(%s) %s - %s\n", __location__, #call, nt_errstr(status2)); \
		ret = False; \
		goto done; \
		} \
	}} while (0)

#define CHECK_VALUE(call, stype, field, value) do { \
 	CHECK1(call); \
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
		printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
		       call_name, #stype, #field, \
		       (uint_t)value, (uint_t)finfo2.stype.out.field); \
		torture_smb2_all_info(tree, handle); \
		ret = False; \
		goto done; \
	}} while (0)

#define CHECK_TIME(call, stype, field, value) do { \
 	CHECK1(call); \
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
		printf("(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
		        call_name, #stype, #field, \
		        (uint_t)value, \
			(uint_t)nt_time_to_unix(finfo2.stype.out.field)); \
		printf("\t%s", timestring(mem_ctx, value)); \
		printf("\t%s\n", nt_time_string(mem_ctx, finfo2.stype.out.field)); \
		torture_smb2_all_info(tree, handle); \
		ret = False; \
		goto done; \
	}} while (0)

#define CHECK_STATUS(status, correct) do { \
	if (!NT_STATUS_EQUAL(status, correct)) { \
		printf("(%s) Incorrect status %s - should be %s\n", \
		       __location__, nt_errstr(status), nt_errstr(correct)); \
		ret = False; \
		goto done; \
	}} while (0)

	torture_smb2_all_info(tree, handle);
	
	printf("test basic_information level\n");
	basetime += 86400;
	unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
	unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
	unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
	unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, create_time, basetime + 100);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, access_time, basetime + 200);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, write_time,  basetime + 300);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, change_time, basetime + 400);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib,     FILE_ATTRIBUTE_READONLY);

	printf("a zero time means don't change\n");
	unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
	unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
	unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
	unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, create_time, basetime + 100);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, access_time, basetime + 200);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, write_time,  basetime + 300);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, change_time, basetime + 400);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib,     FILE_ATTRIBUTE_NORMAL);

	printf("change the attribute\n");
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_HIDDEN;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);

	printf("zero attrib means don't change\n");
	sfinfo.basic_info.in.attrib = 0;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);

	printf("restore attribute\n");
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_NORMAL);

	printf("test disposition_information level\n");
	sfinfo.disposition_info.in.delete_on_close = 1;
	CHECK_CALL(DISPOSITION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, delete_pending, 1);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, nlink, 0);

	sfinfo.disposition_info.in.delete_on_close = 0;
	CHECK_CALL(DISPOSITION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, delete_pending, 0);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, nlink, 1);

	printf("test allocation_information level\n");
	sfinfo.allocation_info.in.alloc_size = 0;
	CHECK_CALL(ALLOCATION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 0);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, alloc_size, 0);

	sfinfo.allocation_info.in.alloc_size = 4096;
	CHECK_CALL(ALLOCATION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, alloc_size, 4096);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 0);

	printf("test end_of_file_info level\n");
	sfinfo.end_of_file_info.in.size = 37;
	CHECK_CALL(END_OF_FILE_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 37);

	sfinfo.end_of_file_info.in.size = 7;
	CHECK_CALL(END_OF_FILE_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 7);

	printf("test position_information level\n");
	sfinfo.position_information.in.position = 123456;
	CHECK_CALL(POSITION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, position, 123456);

	printf("test mode_information level\n");
	sfinfo.mode_information.in.mode = 2;
	CHECK_CALL(MODE_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, mode, 2);

	sfinfo.mode_information.in.mode = 1;
	CHECK_CALL(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);

	sfinfo.mode_information.in.mode = 0;
	CHECK_CALL(MODE_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);

	printf("test sec_desc level\n");
	ZERO_STRUCT(finfo2);
	finfo2.query_secdesc.in.secinfo_flags =
		SECINFO_OWNER |
		SECINFO_GROUP |
		SECINFO_DACL;
 	CHECK1(SEC_DESC);
	sd = finfo2.query_secdesc.out.sd;

	test_sid = dom_sid_parse_talloc(mem_ctx, "S-1-5-32-1234-5432");
	ZERO_STRUCT(ace);
	ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
	ace.flags = 0;
	ace.access_mask = SEC_STD_ALL;
	ace.trustee = *test_sid;
	status = security_descriptor_dacl_add(sd, &ace);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("add a new ACE to the DACL\n");

	sfinfo.set_secdesc.in.secinfo_flags = finfo2.query_secdesc.in.secinfo_flags;
	sfinfo.set_secdesc.in.sd = sd;
	CHECK_CALL(SEC_DESC, NT_STATUS_OK);
 	CHECK1(SEC_DESC);

	if (!security_acl_equal(finfo2.query_secdesc.out.sd->dacl, sd->dacl)) {
		printf("%s: security descriptors don't match!\n", __location__);
		printf("got:\n");
		NDR_PRINT_DEBUG(security_descriptor, finfo2.query_secdesc.out.sd);
		printf("expected:\n");
		NDR_PRINT_DEBUG(security_descriptor, sd);
		ret = False;
	}

	printf("remove it again\n");

	status = security_descriptor_dacl_del(sd, test_sid);
	CHECK_STATUS(status, NT_STATUS_OK);

	sfinfo.set_secdesc.in.secinfo_flags = finfo2.query_secdesc.in.secinfo_flags;
	sfinfo.set_secdesc.in.sd = sd;
	CHECK_CALL(SEC_DESC, NT_STATUS_OK);
 	CHECK1(SEC_DESC);

	if (!security_acl_equal(finfo2.query_secdesc.out.sd->dacl, sd->dacl)) {
		printf("%s: security descriptors don't match!\n", __location__);
		printf("got:\n");
		NDR_PRINT_DEBUG(security_descriptor, finfo2.query_secdesc.out.sd);
		printf("expected:\n");
		NDR_PRINT_DEBUG(security_descriptor, sd);
		ret = False;
	}

done:
	status = smb2_util_close(tree, handle);
	if (NT_STATUS_IS_ERR(status)) {
		printf("Failed to delete %s - %s\n", fname, nt_errstr(status));
	}
	smb2_util_unlink(tree, fname);

	talloc_free(mem_ctx);
	return ret;
}
Exemple #7
0
NTSTATUS gp_create_gpt_security_descriptor (TALLOC_CTX *mem_ctx, struct security_descriptor *ds_sd, struct security_descriptor **ret)
{
	struct security_descriptor *fs_sd;
	NTSTATUS status;
	uint32_t i;

	/* Allocate the file system security descriptor */
	fs_sd = talloc(mem_ctx, struct security_descriptor);
	NT_STATUS_HAVE_NO_MEMORY(fs_sd);

	/* Copy the basic information from the directory server security descriptor */
	fs_sd->owner_sid = talloc_memdup(fs_sd, ds_sd->owner_sid, sizeof(struct dom_sid));
	if (fs_sd->owner_sid == NULL) {
		TALLOC_FREE(fs_sd);
		return NT_STATUS_NO_MEMORY;
	}

	fs_sd->group_sid = talloc_memdup(fs_sd, ds_sd->group_sid, sizeof(struct dom_sid));
	if (fs_sd->group_sid == NULL) {
		TALLOC_FREE(fs_sd);
		return NT_STATUS_NO_MEMORY;
	}

	fs_sd->type = ds_sd->type;
	fs_sd->revision = ds_sd->revision;

	/* Copy the sacl */
	fs_sd->sacl = security_acl_dup(fs_sd, ds_sd->sacl);
	if (fs_sd->sacl == NULL) {
		TALLOC_FREE(fs_sd);
		return NT_STATUS_NO_MEMORY;
	}

	/* Copy the dacl */
	fs_sd->dacl = talloc_zero(fs_sd, struct security_acl);
	if (fs_sd->dacl == NULL) {
		TALLOC_FREE(fs_sd);
		return NT_STATUS_NO_MEMORY;
	}

	for (i = 0; i < ds_sd->dacl->num_aces; i++) {
		char *trustee = dom_sid_string(fs_sd, &ds_sd->dacl->aces[i].trustee);
		struct security_ace *ace;

		/* Don't add the allow for SID_BUILTIN_PREW2K */
		if (!(ds_sd->dacl->aces[i].type & SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) &&
				strcmp(trustee, SID_BUILTIN_PREW2K) == 0) {
			talloc_free(trustee);
			continue;
		}

		/* Copy the ace from the directory server security descriptor */
		ace = talloc_memdup(fs_sd, &ds_sd->dacl->aces[i], sizeof(struct security_ace));
		if (ace == NULL) {
			TALLOC_FREE(fs_sd);
			return NT_STATUS_NO_MEMORY;
		}

		/* Set specific inheritance flags for within the GPO */
		ace->flags |= SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_CONTAINER_INHERIT;
		if (strcmp(trustee, SID_CREATOR_OWNER) == 0) {
			ace->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
		}

		/* Get a directory access mask from the assigned access mask on the LDAP object */
		ace->access_mask = gp_ads_to_dir_access_mask(ace->access_mask);

		/* Add the ace to the security descriptor DACL */
		status = security_descriptor_dacl_add(fs_sd, ace);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(0, ("Failed to add a dacl to file system security descriptor\n"));
			return status;
		}

		/* Clean up the allocated data in this iteration */
		talloc_free(trustee);
	}

	*ret = fs_sd;
	return NT_STATUS_OK;
}
Exemple #8
0
static bool elog_check_access( EVENTLOG_INFO *info, const struct security_token *token )
{
	char *tdbname = elog_tdbname(talloc_tos(), info->logname );
	struct security_descriptor *sec_desc;
	struct security_ace *ace;
	NTSTATUS status;

	if ( !tdbname )
		return False;

	/* get the security descriptor for the file */

	sec_desc = get_nt_acl_no_snum( info, tdbname );
	TALLOC_FREE( tdbname );

	if ( !sec_desc ) {
		DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
			tdbname));
		return False;
	}

	ace = talloc_zero(sec_desc, struct security_ace);
	if (ace == NULL) {
		TALLOC_FREE(sec_desc);
		return false;
	}

	ace->type		= SEC_ACE_TYPE_ACCESS_ALLOWED;
	ace->flags		= 0;
	ace->access_mask	= REG_KEY_ALL;
	ace->trustee		= global_sid_System;

	status = security_descriptor_dacl_add(sec_desc, ace);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(sec_desc);
		return false;
	}

	/* root free pass */

	if ( geteuid() == sec_initial_uid() ) {
		DEBUG(5,("elog_check_access: running as root, using system token\n"));
		token = get_system_token();
	}

	/* run the check, try for the max allowed */

	status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
		&info->access_granted);

	TALLOC_FREE(sec_desc);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(8,("elog_check_access: se_access_check() return %s\n",
			nt_errstr(status)));
		return False;
	}

	/* we have to have READ permission for a successful open */

	return ( info->access_granted & SEC_FILE_READ_DATA );
}
Exemple #9
0
/* basic testing of all SMB2 setinfo calls 
   for each call we test that it succeeds, and where possible test 
   for consistency between the calls. 
*/
bool torture_smb2_setinfo(struct torture_context *tctx)
{
	struct smb2_tree *tree;
	bool ret = true;
	struct smb2_handle handle;
	char *fname;
	union smb_fileinfo finfo2;
	union smb_setfileinfo sfinfo;
	struct security_ace ace;
	struct security_descriptor *sd;
	struct dom_sid *test_sid;
	NTSTATUS status, status2=NT_STATUS_OK;
	const char *call_name;
	time_t basetime = (time(NULL) - 86400) & ~1;
	int n = time(NULL) % 100;
	struct ea_struct ea;
	
	ZERO_STRUCT(handle);
	
	fname = talloc_asprintf(tctx, BASEDIR "fnum_test_%d.txt", n);

	if (!torture_smb2_connection(tctx, &tree)) {
		return false;
	}

#define RECREATE_FILE(fname) do { \
	smb2_util_close(tree, handle); \
	status = smb2_create_complex_file(tree, fname, &handle); \
	if (!NT_STATUS_IS_OK(status)) { \
		torture_result(tctx, TORTURE_FAIL, "(%s) ERROR: open of %s failed (%s)\n", \
		       __location__, fname, nt_errstr(status)); \
		ret = false; \
		goto done; \
	}} while (0)

#define RECREATE_BOTH do { \
		RECREATE_FILE(fname); \
	} while (0)

	RECREATE_BOTH;
	
#define CHECK_CALL(call, rightstatus) do { \
	call_name = #call; \
	sfinfo.generic.level = RAW_SFILEINFO_ ## call; \
	sfinfo.generic.in.file.handle = handle; \
	status = smb2_setinfo_file(tree, &sfinfo); \
	if (!NT_STATUS_EQUAL(status, rightstatus)) { \
		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s (should be %s)\n", __location__, #call, \
			nt_errstr(status), nt_errstr(rightstatus)); \
		ret = false; \
		goto done; \
	} \
	} while (0)

#define CHECK1(call) \
	do { if (NT_STATUS_IS_OK(status)) { \
		finfo2.generic.level = RAW_FILEINFO_ ## call; \
		finfo2.generic.in.file.handle = handle; \
		status2 = smb2_getinfo_file(tree, tctx, &finfo2); \
		if (!NT_STATUS_IS_OK(status2)) { \
			torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__, #call, nt_errstr(status2)); \
		ret = false; \
		goto done; \
		} \
	}} while (0)

#define CHECK_VALUE(call, stype, field, value) do { \
 	CHECK1(call); \
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && finfo2.stype.out.field != value) { \
		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
		       call_name, #stype, #field, \
		       (unsigned int)value, (unsigned int)finfo2.stype.out.field); \
		torture_smb2_all_info(tree, handle); \
		ret = false; \
		goto done; \
	}} while (0)

#define CHECK_TIME(call, stype, field, value) do { \
 	CHECK1(call); \
	if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(status2) && nt_time_to_unix(finfo2.stype.out.field) != value) { \
		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s/%s should be 0x%x - 0x%x\n", __location__, \
		        call_name, #stype, #field, \
		        (unsigned int)value, \
			(unsigned int)nt_time_to_unix(finfo2.stype.out.field)); \
		torture_warning(tctx, "\t%s", timestring(tctx, value)); \
		torture_warning(tctx, "\t%s\n", nt_time_string(tctx, finfo2.stype.out.field)); \
		torture_smb2_all_info(tree, handle); \
		ret = false; \
		goto done; \
	}} while (0)

#define CHECK_STATUS(status, correct) do { \
	if (!NT_STATUS_EQUAL(status, correct)) { \
		torture_result(tctx, TORTURE_FAIL, "(%s) Incorrect status %s - should be %s\n", \
		       __location__, nt_errstr(status), nt_errstr(correct)); \
		ret = false; \
		goto done; \
	}} while (0)

	torture_smb2_all_info(tree, handle);
	
	torture_comment(tctx, "Test basic_information level\n");
	basetime += 86400;
	unix_to_nt_time(&sfinfo.basic_info.in.create_time, basetime + 100);
	unix_to_nt_time(&sfinfo.basic_info.in.access_time, basetime + 200);
	unix_to_nt_time(&sfinfo.basic_info.in.write_time,  basetime + 300);
	unix_to_nt_time(&sfinfo.basic_info.in.change_time, basetime + 400);
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_READONLY;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, create_time, basetime + 100);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, access_time, basetime + 200);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, write_time,  basetime + 300);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, change_time, basetime + 400);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib,     FILE_ATTRIBUTE_READONLY);

	torture_comment(tctx, "a zero time means don't change\n");
	unix_to_nt_time(&sfinfo.basic_info.in.create_time, 0);
	unix_to_nt_time(&sfinfo.basic_info.in.access_time, 0);
	unix_to_nt_time(&sfinfo.basic_info.in.write_time,  0);
	unix_to_nt_time(&sfinfo.basic_info.in.change_time, 0);
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, create_time, basetime + 100);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, access_time, basetime + 200);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, write_time,  basetime + 300);
	CHECK_TIME(SMB2_ALL_INFORMATION, all_info2, change_time, basetime + 400);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib,     FILE_ATTRIBUTE_NORMAL);

	torture_comment(tctx, "change the attribute\n");
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_HIDDEN;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);

	torture_comment(tctx, "zero attrib means don't change\n");
	sfinfo.basic_info.in.attrib = 0;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_HIDDEN);

	torture_comment(tctx, "can't change a file to a directory\n");
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_DIRECTORY;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_INVALID_PARAMETER);

	torture_comment(tctx, "restore attribute\n");
	sfinfo.basic_info.in.attrib = FILE_ATTRIBUTE_NORMAL;
	CHECK_CALL(BASIC_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, attrib, FILE_ATTRIBUTE_NORMAL);

	torture_comment(tctx, "Test disposition_information level\n");
	sfinfo.disposition_info.in.delete_on_close = 1;
	CHECK_CALL(DISPOSITION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, delete_pending, 1);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, nlink, 0);

	sfinfo.disposition_info.in.delete_on_close = 0;
	CHECK_CALL(DISPOSITION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, delete_pending, 0);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, nlink, 1);

	torture_comment(tctx, "Test allocation_information level\n");
	sfinfo.allocation_info.in.alloc_size = 0;
	CHECK_CALL(ALLOCATION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 0);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, alloc_size, 0);

	sfinfo.allocation_info.in.alloc_size = 4096;
	CHECK_CALL(ALLOCATION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, alloc_size, 4096);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 0);

	torture_comment(tctx, "Test end_of_file_info level\n");
	sfinfo.end_of_file_info.in.size = 37;
	CHECK_CALL(END_OF_FILE_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 37);

	sfinfo.end_of_file_info.in.size = 7;
	CHECK_CALL(END_OF_FILE_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, size, 7);

	torture_comment(tctx, "Test position_information level\n");
	sfinfo.position_information.in.position = 123456;
	CHECK_CALL(POSITION_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(POSITION_INFORMATION, position_information, position, 123456);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, position, 123456);

	torture_comment(tctx, "Test mode_information level\n");
	sfinfo.mode_information.in.mode = 2;
	CHECK_CALL(MODE_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 2);
	CHECK_VALUE(SMB2_ALL_INFORMATION, all_info2, mode, 2);

	sfinfo.mode_information.in.mode = 1;
	CHECK_CALL(MODE_INFORMATION, NT_STATUS_INVALID_PARAMETER);

	sfinfo.mode_information.in.mode = 0;
	CHECK_CALL(MODE_INFORMATION, NT_STATUS_OK);
	CHECK_VALUE(MODE_INFORMATION, mode_information, mode, 0);

	torture_comment(tctx, "Test sec_desc level\n");
	ZERO_STRUCT(finfo2);
	finfo2.query_secdesc.in.secinfo_flags =
		SECINFO_OWNER |
		SECINFO_GROUP |
		SECINFO_DACL;
 	CHECK1(SEC_DESC);
	sd = finfo2.query_secdesc.out.sd;

	test_sid = dom_sid_parse_talloc(tctx, SID_NT_AUTHENTICATED_USERS);
	ZERO_STRUCT(ace);
	ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED;
	ace.flags = 0;
	ace.access_mask = SEC_STD_ALL;
	ace.trustee = *test_sid;
	status = security_descriptor_dacl_add(sd, &ace);
	CHECK_STATUS(status, NT_STATUS_OK);

	torture_comment(tctx, "add a new ACE to the DACL\n");

	sfinfo.set_secdesc.in.secinfo_flags = finfo2.query_secdesc.in.secinfo_flags;
	sfinfo.set_secdesc.in.sd = sd;
	CHECK_CALL(SEC_DESC, NT_STATUS_OK);
	FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, handle, sd));

	torture_comment(tctx, "remove it again\n");

	status = security_descriptor_dacl_del(sd, test_sid);
	CHECK_STATUS(status, NT_STATUS_OK);

	sfinfo.set_secdesc.in.secinfo_flags = finfo2.query_secdesc.in.secinfo_flags;
	sfinfo.set_secdesc.in.sd = sd;
	CHECK_CALL(SEC_DESC, NT_STATUS_OK);
	FAIL_UNLESS(smb2_util_verify_sd(tctx, tree, handle, sd));

	torture_comment(tctx, "Check zero length EA's behavior\n");

	/* Set a new EA. */
	sfinfo.full_ea_information.in.eas.num_eas = 1;
	ea.flags = 0;
	ea.name.private_length = 6;
	ea.name.s = "NewEA";
	ea.value = data_blob_string_const("testme");
	sfinfo.full_ea_information.in.eas.eas = &ea;
	CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);

	/* Does it still exist ? */
	finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
	finfo2.generic.in.file.handle = handle;
	finfo2.all_eas.in.continue_flags = 1;
	status2 = smb2_getinfo_file(tree, tctx, &finfo2);
	if (!NT_STATUS_IS_OK(status2)) {
		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
			"SMB2_ALL_EAS", nt_errstr(status2));
		ret = false;
		goto done;
	}

	/* Note on Windows EA name is returned capitalized. */
	if (!find_returned_ea(&finfo2, "NewEA", "testme")) {
		torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'NewEA'\n", __location__);
		ret = false;
	}

	/* Now zero it out (should delete it) */
	sfinfo.full_ea_information.in.eas.num_eas = 1;
	ea.flags = 0;
	ea.name.private_length = 6;
	ea.name.s = "NewEA";
	ea.value = data_blob_null;
	sfinfo.full_ea_information.in.eas.eas = &ea;
	CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);

	/* Does it still exist ? */
	finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
	finfo2.generic.in.file.handle = handle;
	finfo2.all_eas.in.continue_flags = 1;
	status2 = smb2_getinfo_file(tree, tctx, &finfo2);
	if (!NT_STATUS_IS_OK(status2)) {
		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
			"SMB2_ALL_EAS", nt_errstr(status2));
		ret = false;
		goto done;
	}

	if (find_returned_ea(&finfo2, "NewEA", NULL)) {
		torture_result(tctx, TORTURE_FAIL, "(%s) EA 'NewEA' should be deleted\n", __location__);
		ret = false;
	}

	/* Set a zero length EA. */
	sfinfo.full_ea_information.in.eas.num_eas = 1;
	ea.flags = 0;
	ea.name.private_length = 6;
	ea.name.s = "ZeroEA";
	ea.value = data_blob_null;
	sfinfo.full_ea_information.in.eas.eas = &ea;
	CHECK_CALL(FULL_EA_INFORMATION, NT_STATUS_OK);

	/* Does it still exist ? */
	finfo2.generic.level = RAW_FILEINFO_SMB2_ALL_EAS;
	finfo2.generic.in.file.handle = handle;
	finfo2.all_eas.in.continue_flags = 1;
	status2 = smb2_getinfo_file(tree, tctx, &finfo2);
	if (!NT_STATUS_IS_OK(status2)) {
		torture_result(tctx, TORTURE_FAIL, "(%s) %s - %s\n", __location__,
			"SMB2_ALL_EAS", nt_errstr(status2));
		ret = false;
		goto done;
	}

	/* Over SMB2 ZeroEA should not exist. */
	if (!find_returned_ea(&finfo2, "EAONE", "VALUE1")) {
		torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'EAONE'\n", __location__);
		ret = false;
	}
	if (!find_returned_ea(&finfo2, "SECONDEA", "ValueTwo")) {
		torture_result(tctx, TORTURE_FAIL, "(%s) Missing EA 'SECONDEA'\n", __location__);
		ret = false;
	}
	if (find_returned_ea(&finfo2, "ZeroEA", NULL)) {
		torture_result(tctx, TORTURE_FAIL, "(%s) Found null EA 'ZeroEA'\n", __location__);
		ret = false;
	}

done:
	status = smb2_util_close(tree, handle);
	if (NT_STATUS_IS_ERR(status)) {
		torture_warning(tctx, "Failed to delete %s - %s\n", fname, nt_errstr(status));
	}
	smb2_util_unlink(tree, fname);

	return ret;
}
Exemple #10
0
/*
  test setfileacl
*/
static bool test_appendacl(struct smbcli_state *cli, struct torture_context *tctx)
{
	struct smb_composite_appendacl **io;
	struct smb_composite_appendacl **io_orig;
	struct composite_context **c;
	struct tevent_context *event_ctx;

	struct security_descriptor *test_sd;
	struct security_ace *ace;
	struct dom_sid *test_sid;

	const int num_ops = 50;
	int *count = talloc_zero(tctx, int);
	struct smb_composite_savefile io1;

	NTSTATUS status;
	int i;

	io_orig = talloc_array(tctx, struct smb_composite_appendacl *, num_ops);

	printf ("creating %d empty files and getting their acls with appendacl\n", num_ops);

	for (i = 0; i < num_ops; i++) {
		io1.in.fname = talloc_asprintf(io_orig, BASEDIR "\\test%d.txt", i);
		io1.in.data  = NULL;
		io1.in.size  = 0;
	  
		status = smb_composite_savefile(cli->tree, &io1);
		if (!NT_STATUS_IS_OK(status)) {
			printf("(%s) savefile failed: %s\n", __location__, nt_errstr(status));
			return false;
		}

		io_orig[i] = talloc (io_orig, struct smb_composite_appendacl);
		io_orig[i]->in.fname = talloc_steal(io_orig[i], io1.in.fname);
		io_orig[i]->in.sd = security_descriptor_initialise(io_orig[i]);
		status = smb_composite_appendacl(cli->tree, io_orig[i], io_orig[i]);
		if (!NT_STATUS_IS_OK(status)) {
			printf("(%s) appendacl failed: %s\n", __location__, nt_errstr(status));
			return false;
		}
	}
	

	/* fill Security Descriptor with aces to be added */

	test_sd = security_descriptor_initialise(tctx);
	test_sid = dom_sid_parse_talloc (tctx, "S-1-5-32-1234-5432");

	ace = talloc_zero(tctx, struct security_ace);

	ace->type = SEC_ACE_TYPE_ACCESS_ALLOWED;
	ace->flags = 0;
	ace->access_mask = SEC_STD_ALL;
	ace->trustee = *test_sid;

	status = security_descriptor_dacl_add(test_sd, ace);
	if (!NT_STATUS_IS_OK(status)) {
		printf("(%s) appendacl failed: %s\n", __location__, nt_errstr(status));
		return false;
	}

	/* set parameters for appendacl async call */

	printf("testing parallel appendacl with %d ops\n", num_ops);

	c = talloc_array(tctx, struct composite_context *, num_ops);
	io = talloc_array(tctx, struct  smb_composite_appendacl *, num_ops);

	for (i=0; i < num_ops; i++) {
		io[i] = talloc (io, struct smb_composite_appendacl);
		io[i]->in.sd = test_sd;
		io[i]->in.fname = talloc_asprintf(io[i], BASEDIR "\\test%d.txt", i);

		c[i] = smb_composite_appendacl_send(cli->tree, io[i]);
		c[i]->async.fn = loadfile_complete;
		c[i]->async.private_data = count;
	}

	event_ctx = tctx->ev;
	printf("waiting for completion\n");
	while (*count != num_ops) {
		event_loop_once(event_ctx);
		if (torture_setting_bool(tctx, "progress", true)) {
			printf("(%s) count=%d\r", __location__, *count);
			fflush(stdout);
		}
	}
	printf("count=%d\n", *count);

	for (i=0; i < num_ops; i++) {
		status = smb_composite_appendacl_recv(c[i], io[i]);
		if (!NT_STATUS_IS_OK(status)) {
			printf("(%s) appendacl[%d] failed - %s\n", __location__, i, nt_errstr(status));
			return false;
		}
		
		security_descriptor_dacl_add(io_orig[i]->out.sd, ace);
		if (!security_acl_equal(io_orig[i]->out.sd->dacl, io[i]->out.sd->dacl)) {
			printf("(%s) appendacl[%d] failed - needed acl isn't set\n", __location__, i);
			return false;
		}
	}
	

	talloc_free (ace);
	talloc_free (test_sid);
	talloc_free (test_sd);
		
	return true;
}