Пример #1
0
/*
 * Test creating a file with a NULL DACL.
 */
static bool test_create_null_dacl(struct torture_context *tctx,
                                  struct smb2_tree *tree)
{
    NTSTATUS status;
    struct smb2_create io;
    const char *fname = "nulldacl.txt";
    bool ret = true;
    struct smb2_handle handle;
    union smb_fileinfo q;
    union smb_setfileinfo s;
    struct security_descriptor *sd = security_descriptor_initialise(tctx);
    struct security_acl dacl;

    torture_comment(tctx, "TESTING SEC_DESC WITH A NULL DACL\n");

    smb2_util_unlink(tree, fname);

    ZERO_STRUCT(io);
    io.level = RAW_OPEN_SMB2;
    io.in.create_flags = 0;
    io.in.desired_access = SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC
                           | SEC_STD_WRITE_OWNER;
    io.in.create_options = 0;
    io.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
    io.in.share_access =
        NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
    io.in.alloc_size = 0;
    io.in.create_disposition = NTCREATEX_DISP_CREATE;
    io.in.impersonation_level = NTCREATEX_IMPERSONATION_ANONYMOUS;
    io.in.security_flags = 0;
    io.in.fname = fname;
    io.in.sec_desc = sd;
    /* XXX create_options ? */
    io.in.create_options		= NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
                                  NTCREATEX_OPTIONS_ASYNC_ALERT	|
                                  NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
                                  0x00200000;

    torture_comment(tctx, "creating a file with a empty sd\n");
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    handle = io.out.file.handle;

    torture_comment(tctx, "get the original sd\n");
    q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    q.query_secdesc.in.file.handle = 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);

    /*
     * Testing the created DACL,
     * the server should add the inherited DACL
     * when SEC_DESC_DACL_PRESENT isn't specified
     */
    if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
        ret = false;
        torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
    }
    if (q.query_secdesc.out.sd->dacl == NULL) {
        ret = false;
        torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
    }

    torture_comment(tctx, "set NULL DACL\n");
    sd->type |= SEC_DESC_DACL_PRESENT;

    s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    s.set_secdesc.in.file.handle = handle;
    s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    s.set_secdesc.in.sd = sd;
    status = smb2_setinfo_file(tree, &s);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "get the sd\n");
    q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    q.query_secdesc.in.file.handle = 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);

    /* Testing the modified DACL */
    if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
        ret = false;
        torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
    }
    if (q.query_secdesc.out.sd->dacl != NULL) {
        ret = false;
        torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
    }

    io.in.create_disposition = NTCREATEX_DISP_OPEN;

    torture_comment(tctx, "try open for read control\n");
    io.in.desired_access = SEC_STD_READ_CONTROL;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_ACCESS_FLAGS(io.out.file.handle,
                       SEC_STD_READ_CONTROL);
    smb2_util_close(tree, io.out.file.handle);

    torture_comment(tctx, "try open for write\n");
    io.in.desired_access = SEC_FILE_WRITE_DATA;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_ACCESS_FLAGS(io.out.file.handle,
                       SEC_FILE_WRITE_DATA);
    smb2_util_close(tree, io.out.file.handle);

    torture_comment(tctx, "try open for read\n");
    io.in.desired_access = SEC_FILE_READ_DATA;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_ACCESS_FLAGS(io.out.file.handle,
                       SEC_FILE_READ_DATA);
    smb2_util_close(tree, io.out.file.handle);

    torture_comment(tctx, "try open for generic write\n");
    io.in.desired_access = SEC_GENERIC_WRITE;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_ACCESS_FLAGS(io.out.file.handle,
                       SEC_RIGHTS_FILE_WRITE);
    smb2_util_close(tree, io.out.file.handle);

    torture_comment(tctx, "try open for generic read\n");
    io.in.desired_access = SEC_GENERIC_READ;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_ACCESS_FLAGS(io.out.file.handle,
                       SEC_RIGHTS_FILE_READ);
    smb2_util_close(tree, io.out.file.handle);

    torture_comment(tctx, "set DACL with 0 aces\n");
    ZERO_STRUCT(dacl);
    dacl.revision = SECURITY_ACL_REVISION_NT4;
    dacl.num_aces = 0;
    sd->dacl = &dacl;

    s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    s.set_secdesc.in.file.handle = handle;
    s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    s.set_secdesc.in.sd = sd;
    status = smb2_setinfo_file(tree, &s);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "get the sd\n");
    q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    q.query_secdesc.in.file.handle = 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);

    /* Testing the modified DACL */
    if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
        ret = false;
        torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
    }
    if (q.query_secdesc.out.sd->dacl == NULL) {
        ret = false;
        torture_fail_goto(tctx, done, "no DACL has been created on the server!\n");
    }
    if (q.query_secdesc.out.sd->dacl->num_aces != 0) {
        torture_result(tctx, TORTURE_FAIL, "DACL has %u aces!\n",
                       q.query_secdesc.out.sd->dacl->num_aces);
        ret = false;
        goto done;
    }

    torture_comment(tctx, "try open for read control\n");
    io.in.desired_access = SEC_STD_READ_CONTROL;
    status = smb2_create(tree, tctx, &io);
    CHECK_STATUS(status, NT_STATUS_OK);
    CHECK_ACCESS_FLAGS(io.out.file.handle,
                       SEC_STD_READ_CONTROL);
    smb2_util_close(tree, io.out.file.handle);

    torture_comment(tctx, "try open for write => access_denied\n");
    io.in.desired_access = SEC_FILE_WRITE_DATA;
    status = smb2_create(tree, tctx, &io);
    if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    torture_comment(tctx, "try open for read => access_denied\n");
    io.in.desired_access = SEC_FILE_READ_DATA;
    status = smb2_create(tree, tctx, &io);
    if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    torture_comment(tctx, "try open for generic write => access_denied\n");
    io.in.desired_access = SEC_GENERIC_WRITE;
    status = smb2_create(tree, tctx, &io);
    if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    torture_comment(tctx, "try open for generic read => access_denied\n");
    io.in.desired_access = SEC_GENERIC_READ;
    status = smb2_create(tree, tctx, &io);
    if (torture_setting_bool(tctx, "hide_on_access_denied", false)) {
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
    } else {
        CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
    }

    torture_comment(tctx, "set empty sd\n");
    sd->type &= ~SEC_DESC_DACL_PRESENT;
    sd->dacl = NULL;

    s.set_secdesc.level = RAW_SFILEINFO_SEC_DESC;
    s.set_secdesc.in.file.handle = handle;
    s.set_secdesc.in.secinfo_flags = SECINFO_DACL;
    s.set_secdesc.in.sd = sd;
    status = smb2_setinfo_file(tree, &s);
    CHECK_STATUS(status, NT_STATUS_OK);

    torture_comment(tctx, "get the sd\n");
    q.query_secdesc.level = RAW_FILEINFO_SEC_DESC;
    q.query_secdesc.in.file.handle = 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);

    /* Testing the modified DACL */
    if (!(q.query_secdesc.out.sd->type & SEC_DESC_DACL_PRESENT)) {
        ret = false;
        torture_fail_goto(tctx, done, "DACL_PRESENT flag not set by the server!\n");
    }
    if (q.query_secdesc.out.sd->dacl != NULL) {
        ret = false;
        torture_fail_goto(tctx, done, "DACL has been created on the server!\n");
    }
done:
    smb2_util_close(tree, handle);
    smb2_util_unlink(tree, fname);
    smb2_tdis(tree);
    smb2_logoff(tree->session);
    return ret;
}
Пример #2
0
/* 
   basic testing of SMB2 connection calls
*/
BOOL torture_smb2_connect(struct torture_context *torture)
{
	TALLOC_CTX *mem_ctx = talloc_new(NULL);
	struct smb2_tree *tree;
	struct smb2_handle h1, h2;
	NTSTATUS status;

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

	h1 = torture_smb2_create(tree, "test9.dat");
	h2 = torture_smb2_create(tree, "test9.dat");
	status = torture_smb2_write(tree, h1);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Write failed - %s\n", nt_errstr(status));
		return False;
	}
	status = torture_smb2_close(tree, h1);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Close failed - %s\n", nt_errstr(status));
		return False;
	}
	status = torture_smb2_close(tree, h2);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Close failed - %s\n", nt_errstr(status));
		return False;
	}

	status = smb2_util_close(tree, h1);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_CLOSED)) {
		printf("close should have closed the handle - %s\n", nt_errstr(status));
		return False;
	}

	status = smb2_tdis(tree);
	if (!NT_STATUS_IS_OK(status)) {
		printf("tdis failed - %s\n", nt_errstr(status));
		return False;
	}

	status = smb2_tdis(tree);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_NAME_DELETED)) {
		printf("tdis should have disabled session - %s\n", nt_errstr(status));
		return False;
	}

 	status = smb2_logoff(tree->session);
	if (!NT_STATUS_IS_OK(status)) {
		printf("Logoff failed - %s\n", nt_errstr(status));
		return False;
	}

	status = smb2_logoff(tree->session);
	if (!NT_STATUS_EQUAL(status, NT_STATUS_USER_SESSION_DELETED)) {
		printf("Logoff should have disabled session - %s\n", nt_errstr(status));
		return False;
	}

	status = smb2_keepalive(tree->session->transport);
	if (!NT_STATUS_IS_OK(status)) {
		printf("keepalive failed? - %s\n", nt_errstr(status));
		return False;
	}

	talloc_free(mem_ctx);

	return True;
}