Beispiel #1
0
} END_TEST

START_TEST (test_replica_mapping_id_to_guid) {
	struct GUID		*ret_guid, client_guid = GUID_random();
	enum MAPISTATUS		ret;
	TALLOC_CTX		*mem_ctx;
	uint16_t		repl_id;

	mem_ctx = talloc_new(NULL);
	ck_assert(mem_ctx != NULL);

	ret_guid = talloc_zero(mem_ctx, struct GUID);
	ck_assert(ret_guid != NULL);

	ret = openchangedb_replica_mapping_replid_to_guid(g_oc_ctx, USER1, 0x23, ret_guid);
	ck_assert(ret == MAPI_E_NOT_FOUND);

	ret = openchangedb_replica_mapping_guid_to_replid(g_oc_ctx, USER1, &client_guid, &repl_id);
	ck_assert(ret == MAPI_E_SUCCESS);

	ret = openchangedb_replica_mapping_replid_to_guid(g_oc_ctx, USER1, repl_id, ret_guid);
	ck_assert(ret == MAPI_E_SUCCESS);

	ck_assert(GUID_equal(&client_guid, ret_guid));
	ck_assert(repl_id > 0x01);

	talloc_free(mem_ctx);

} END_TEST
Beispiel #2
0
/*
  allocate a new rpc handle
*/
_PUBLIC_ struct dcesrv_handle *dcesrv_handle_new(struct dcesrv_connection_context *context, 
						 uint8_t handle_type)
{
	struct dcesrv_handle *h;
	struct dom_sid *sid;

	sid = context->conn->auth_state.session_info->security_token->user_sid;

	h = talloc(context->assoc_group, struct dcesrv_handle);
	if (!h) {
		return NULL;
	}
	h->data = NULL;
	h->sid = dom_sid_dup(h, sid);
	if (h->sid == NULL) {
		talloc_free(h);
		return NULL;
	}
	h->assoc_group = context->assoc_group;
	h->iface = context->iface;
	h->wire_handle.handle_type = handle_type;
	h->wire_handle.uuid = GUID_random();
	
	DLIST_ADD(context->assoc_group->handles, h);

	talloc_set_destructor(h, dcesrv_handle_destructor);

	return h;
}
Beispiel #3
0
/**
 * basic test for doing a durable open
 * and do a durable reopen on the same connection
 * while the first open is still active (fails)
 */
bool test_durable_v2_open_reopen1(struct torture_context *tctx,
				  struct smb2_tree *tree)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char fname[256];
	struct smb2_handle _h;
	struct smb2_handle *h = NULL;
	struct smb2_create io;
	struct GUID create_guid = GUID_random();
	bool ret = true;

	/* Choose a random name in case the state is left a little funky. */
	snprintf(fname, 256, "durable_v2_open_reopen1_%s.dat",
		 generate_random_str(tctx, 8));

	smb2_util_unlink(tree, fname);

	smb2_oplock_create_share(&io, fname,
				 smb2_util_share_access(""),
				 smb2_util_oplock_level("b"));
	io.in.durable_open = false;
	io.in.durable_open_v2 = true;
	io.in.persistent_open = false;
	io.in.create_guid = create_guid;
	io.in.timeout = UINT32_MAX;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h = io.out.file.handle;
	h = &_h;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, true);
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.timeout, io.in.timeout);

	/* try a durable reconnect while the file is still open */
	ZERO_STRUCT(io);
	io.in.fname = "";
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

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

	smb2_util_unlink(tree, fname);

	talloc_free(tree);

	talloc_free(mem_ctx);

	return ret;
}
Beispiel #4
0
static bool test_random_uuid(struct torture_context *torture)
{
	NTSTATUS status;
	struct dcerpc_pipe *p1, *p2;
	struct rpc_request *req;
	struct GUID uuid;
	struct dssetup_DsRoleGetPrimaryDomainInformation r1;
	struct lsa_GetUserName r2;
	struct lsa_String *authority_name_p = NULL;
	struct lsa_String *account_name_p = NULL;

	torture_comment(torture, "RPC-OBJECTUUID-RANDOM\n");

	status = torture_rpc_connection(torture, &p1, &ndr_table_dssetup);
	torture_assert_ntstatus_ok(torture, status, "opening dsetup pipe1");

	status = torture_rpc_connection(torture, &p2, &ndr_table_lsarpc);
	torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1");

	uuid = GUID_random();

	r1.in.level = DS_ROLE_BASIC_INFORMATION;
	status = dcerpc_ndr_request(p1, &uuid,
				    &ndr_table_dssetup,
				    NDR_DSSETUP_DSROLEGETPRIMARYDOMAININFORMATION,
				    torture, &r1);
	torture_assert_ntstatus_ok(torture, status, "DsRoleGetPrimaryDomainInformation failed");
	torture_assert_werr_ok(torture, r1.out.result, "DsRoleGetPrimaryDomainInformation failed");

	uuid = GUID_random();

	r2.in.system_name = "\\";
	r2.in.account_name = &account_name_p;
	r2.in.authority_name = &authority_name_p;
	r2.out.account_name = &account_name_p;
	r2.out.authority_name = &authority_name_p;

	status = dcerpc_ndr_request(p2, &uuid,
				    &ndr_table_lsarpc,
				    NDR_LSA_GETUSERNAME,
				    torture, &r2);
	torture_assert_ntstatus_ok(torture, status, "lsaClose failed");
	torture_assert_ntstatus_ok(torture, r2.out.result, "lsaClose failed");

	return true;
}
Beispiel #5
0
} END_TEST

START_TEST (test_IDSET_includes_guid_glob) {
        struct GUID       server_guid = GUID_random();
        struct GUID       random_guid = GUID_random();
        int               i;
        struct idset      *idset_in;
        struct rawidset   *rawidset_in;
        const uint16_t    repl_id = 0x0001;
        const uint64_t    ids[] = {0x180401000000,
                                   0x190401000000,
                                   0x1a0401000000,
                                   0x1b0401000000,
                                   0x500401000000,
                                   0x520401000000,
                                   0x530401000000,
                                   0x710401000000};
        const uint64_t    not_in_id = 0x2a0401000000;
        const size_t      ids_size = sizeof(ids) / sizeof(uint64_t);

        rawidset_in = RAWIDSET_make(mem_ctx, true, false);
        ck_assert(rawidset_in != NULL);
        for (i = 0; i < ids_size; i++) {
                RAWIDSET_push_eid(rawidset_in, (ids[i] << 16) | repl_id);
        }
        ck_assert_int_eq(rawidset_in->count, ids_size);
        rawidset_in->idbased = false;
        rawidset_in->repl.guid = server_guid;
        idset_in = RAWIDSET_convert_to_idset(mem_ctx, rawidset_in);
        ck_assert(idset_in != NULL);

        /* Case: All inserted elements in the range */
        for (i = 0; i < ids_size; i++) {
                ck_assert(IDSET_includes_guid_glob(idset_in, &server_guid, ids[i]));
        }

        /* Case: a different guid for the same id */
        ck_assert(!IDSET_includes_guid_glob(idset_in, &random_guid, ids[0]));

        /* Case: Not in range and different guid */
        ck_assert(!IDSET_includes_guid_glob(idset_in, &random_guid, not_in_id));

        /* Case: Not in range */
        ck_assert(!IDSET_includes_guid_glob(idset_in, &server_guid, not_in_id));

} END_TEST
} END_TEST

START_TEST(test_call_replica_mapping_guid_to_replid) {
        struct GUID guid = GUID_random();
	uint16_t    replid = 0;

	CHECK_SUCCESS(openchangedb_replica_mapping_guid_to_replid(oc_ctx, "recipient",
                                                                  &guid, &replid));

	ck_assert_int_eq(functions_called.guid_to_replid, 1);
        ck_assert_int_eq(replid, 0x03);
} END_TEST
bool secrets_fetch_domain_guid(const char *domain, struct GUID *guid)
{
	struct GUID *dyn_guid;
	fstring key;
	size_t size = 0;
	struct GUID new_guid;

#if _SAMBA_BUILD_ == 4
	if (strequal(domain, get_global_sam_name()) &&
	    (pdb_capabilities() & PDB_CAP_ADS)) {
		struct pdb_domain_info *domain_info;
		domain_info = pdb_get_domain_info(talloc_tos());
		if (!domain_info) {
			/* If we have a ADS-capable passdb backend, we
			 * must never make up our own SID, it will
			 * already be in the directory */
			DEBUG(0, ("Unable to fetch a Domain GUID from the directory!\n"));
			return false;
		}

		*guid = domain_info->guid;
		return true;
	}
#endif

	slprintf(key, sizeof(key)-1, "%s/%s", SECRETS_DOMAIN_GUID, domain);
	strupper_m(key);
	dyn_guid = (struct GUID *)secrets_fetch(key, &size);

	if (!dyn_guid) {
		if (lp_server_role() == ROLE_DOMAIN_PDC) {
			new_guid = GUID_random();
			if (!secrets_store_domain_guid(domain, &new_guid))
				return False;
			dyn_guid = (struct GUID *)secrets_fetch(key, &size);
		}
		if (dyn_guid == NULL) {
			return False;
		}
	}

	if (size != sizeof(struct GUID)) {
		DEBUG(1,("UUID size %d is wrong!\n", (int)size));
		SAFE_FREE(dyn_guid);
		return False;
	}

	*guid = *dyn_guid;
	SAFE_FREE(dyn_guid);
	return True;
}
Beispiel #8
0
static bool test_one_durable_v2_open_lease(struct torture_context *tctx,
					   struct smb2_tree *tree,
					   const char *fname,
					   bool request_persistent,
					   struct durable_open_vs_lease test)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	struct smb2_handle _h;
	struct smb2_handle *h = NULL;
	bool ret = true;
	struct smb2_create io;
	struct smb2_lease ls;
	uint64_t lease;

	smb2_util_unlink(tree, fname);

	lease = random();

	smb2_lease_create_share(&io, &ls, false /* dir */, fname,
				smb2_util_share_access(test.share_mode),
				lease,
				smb2_util_lease_state(test.type));
	io.in.durable_open = false;
	io.in.durable_open_v2 = true;
	io.in.persistent_open = request_persistent;
	io.in.create_guid = GUID_random();

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h = io.out.file.handle;
	h = &_h;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, test.durable);
	CHECK_VAL(io.out.persistent_open, test.persistent);
	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
	CHECK_VAL(io.out.lease_response.lease_key.data[0], lease);
	CHECK_VAL(io.out.lease_response.lease_key.data[1], ~lease);
	CHECK_VAL(io.out.lease_response.lease_state,
		  smb2_util_lease_state(test.type));
done:
	if (h != NULL) {
		smb2_util_close(tree, *h);
	}
	smb2_util_unlink(tree, fname);
	talloc_free(mem_ctx);

	return ret;
}
Beispiel #9
0
} END_TEST

START_TEST (test_replica_mapping_sanity_checks) {
	struct GUID		client_guid = GUID_random();
	enum MAPISTATUS		ret;

	ret = openchangedb_replica_mapping_guid_to_replid(g_oc_ctx, USER1, NULL, NULL);
	ck_assert(ret == MAPI_E_INVALID_PARAMETER);

	ret = openchangedb_replica_mapping_guid_to_replid(g_oc_ctx, USER1, &client_guid, NULL);
	ck_assert(ret == MAPI_E_INVALID_PARAMETER);

	ret = openchangedb_replica_mapping_replid_to_guid(g_oc_ctx, USER1, 0x23, NULL);
	ck_assert(ret == MAPI_E_INVALID_PARAMETER);

} END_TEST
Beispiel #10
0
} END_TEST

START_TEST (test_replica_mapping_guid_to_id) {
	struct GUID		client_guid = GUID_random();
	enum MAPISTATUS		ret;
	uint16_t		repl_id;

	ret = openchangedb_replica_mapping_guid_to_replid(g_oc_ctx, USER1, &client_guid, &repl_id);
	ck_assert(ret == MAPI_E_SUCCESS);
	ck_assert_int_eq(repl_id, 0x03);

	ret = openchangedb_replica_mapping_guid_to_replid(g_oc_ctx, USER1, &client_guid, &repl_id);
	ck_assert(ret == MAPI_E_SUCCESS);
	ck_assert_int_eq(repl_id, 0x03);

} END_TEST
Beispiel #11
0
static bool test_RemoteActivation(struct torture_context *tctx, 
								 struct dcerpc_pipe *p)
{
	struct RemoteActivation r;
	NTSTATUS status;
	struct GUID iids[1];
	uint16_t protseq[3] = { EPM_PROTOCOL_TCP, EPM_PROTOCOL_NCALRPC, EPM_PROTOCOL_UUID };

	ZERO_STRUCT(r.in);
	r.in.this_object.version.MajorVersion = 5;
	r.in.this_object.version.MinorVersion = 1;
	r.in.this_object.cid = GUID_random();
	GUID_from_string(CLSID_IMAGEDOC, &r.in.Clsid);
	r.in.ClientImpLevel = RPC_C_IMP_LEVEL_IDENTIFY;
	r.in.num_protseqs = 3;
	r.in.protseq = protseq;
	r.in.Interfaces = 1;
	GUID_from_string(DCERPC_IUNKNOWN_UUID, &iids[0]);
	r.in.pIIDs = iids;

	status = dcerpc_RemoteActivation(p, tctx, &r);
	torture_assert_ntstatus_ok(tctx, status, "RemoteActivation");

	torture_assert_werr_ok(tctx, r.out.result, "RemoteActivation");

	torture_assert_werr_ok(tctx, *r.out.hr, "RemoteActivation");

	torture_assert_werr_ok(tctx, r.out.results[0], "RemoteActivation");

	GUID_from_string(DCERPC_ICLASSFACTORY_UUID, &iids[0]);
	r.in.Interfaces = 1;
	r.in.Mode = MODE_GET_CLASS_OBJECT;

	status = dcerpc_RemoteActivation(p, tctx, &r);
	torture_assert_ntstatus_ok(tctx, status, 
							   "RemoteActivation(GetClassObject)");

	torture_assert_werr_ok(tctx, r.out.result, 
						   "RemoteActivation(GetClassObject)");

	torture_assert_werr_ok(tctx, *r.out.hr, "RemoteActivation(GetClassObject)");

	torture_assert_werr_ok(tctx, r.out.results[0], 
						   "RemoteActivation(GetClassObject)");

	return true;
}
Beispiel #12
0
void lpcfg_smbcli_options(struct loadparm_context *lp_ctx,
			 struct smbcli_options *options)
{
	options->max_xmit = lpcfg_max_xmit(lp_ctx);
	options->max_mux = lpcfg_max_mux(lp_ctx);
	options->use_spnego = lpcfg_nt_status_support(lp_ctx) && lpcfg_client_use_spnego(lp_ctx);
	options->signing = lpcfg_client_signing(lp_ctx);
	options->request_timeout = SMB_REQUEST_TIMEOUT;
	options->ntstatus_support = lpcfg_nt_status_support(lp_ctx);
	options->min_protocol = lpcfg_client_min_protocol(lp_ctx);
	options->max_protocol = lpcfg__client_max_protocol(lp_ctx);
	options->unicode = lpcfg_unicode(lp_ctx);
	options->use_oplocks = true;
	options->use_level2_oplocks = true;
	options->smb2_capabilities = SMB2_CAP_ALL;
	options->client_guid = GUID_random();
}
Beispiel #13
0
static bool test_one_durable_v2_open_oplock(struct torture_context *tctx,
					    struct smb2_tree *tree,
					    const char *fname,
					    bool request_persistent,
					    struct durable_open_vs_oplock test)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	struct smb2_handle _h;
	struct smb2_handle *h = NULL;
	bool ret = true;
	struct smb2_create io;

	smb2_util_unlink(tree, fname);

	smb2_oplock_create_share(&io, fname,
				 smb2_util_share_access(test.share_mode),
				 smb2_util_oplock_level(test.level));
	io.in.durable_open = false;
	io.in.durable_open_v2 = true;
	io.in.persistent_open = request_persistent;
	io.in.create_guid = GUID_random();

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h = io.out.file.handle;
	h = &_h;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, test.durable);
	CHECK_VAL(io.out.persistent_open, test.persistent);
	CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level(test.level));

done:
	if (h != NULL) {
		smb2_util_close(tree, *h);
	}
	smb2_util_unlink(tree, fname);
	talloc_free(mem_ctx);

	return ret;
}
Beispiel #14
0
/**
   \details Test the SyncOpenAdvisor (0x83) and SetSyncNotificationGuid (0x88)
   operations

   This function:
   -# logs on
   -# creates a notification advisor
   -# sets a GUID on the advisor
   -# cleans up

   \param mt pointer on the top-level mapitest structure

   \return true on success, otherwise false
 */
_PUBLIC_ bool mapitest_oxcnotif_SyncOpenAdvisor(struct mapitest *mt)
{
	enum MAPISTATUS		retval;
	bool			ret = true;
	mapi_object_t		obj_store;
	mapi_object_t		obj_notifier;

	mapi_object_init(&obj_store);
	mapi_object_init(&obj_notifier);

	/* Logon */
	retval = OpenMsgStore(mt->session, &obj_store);
	mapitest_print_retval_clean(mt, "OpenMsgStore", retval);
	if (retval != MAPI_E_SUCCESS) {
		ret = false;
		goto cleanup;
	}

	/* Create advisor */
	retval = SyncOpenAdvisor(&obj_store, &obj_notifier);
	mapitest_print_retval_clean(mt, "SyncOpenAdvisor", retval);
	if (retval != MAPI_E_SUCCESS) {
		ret = false;
		goto cleanup;
	}

	/* Set GUID */
	retval = SetSyncNotificationGuid(&obj_notifier, GUID_random());
	mapitest_print_retval_clean(mt, "SetSyncNotificationGuid", retval);
	if (retval != MAPI_E_SUCCESS) {
		ret = false;
		goto cleanup;
	}

	/* Cleanup */
cleanup:
	mapi_object_release(&obj_notifier);
	mapi_object_release(&obj_store);

	return ret;
}
/*
  create a transport structure based on an established socket
*/
struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
					   TALLOC_CTX *parent_ctx,
					   struct smbcli_options *options)
{
	struct smb2_transport *transport;
	struct GUID client_guid;
	uint32_t smb2_capabilities = 0;

	transport = talloc_zero(parent_ctx, struct smb2_transport);
	if (!transport) return NULL;

	transport->ev = sock->event.ctx;
	transport->options = *options;

	TALLOC_FREE(sock->event.fde);
	TALLOC_FREE(sock->event.te);

	client_guid = GUID_random();

	/* TODO: hand this in via the options? */
	smb2_capabilities = SMB2_CAP_ALL;

	transport->conn = smbXcli_conn_create(transport,
					      sock->sock->fd,
					      sock->hostname,
					      options->signing,
					      0, /* smb1_capabilities */
					      &client_guid,
					      smb2_capabilities);
	if (transport->conn == NULL) {
		talloc_free(transport);
		return NULL;
	}
	sock->sock->fd = -1;
	TALLOC_FREE(sock);

	talloc_set_destructor(transport, transport_destructor);

	return transport;
}
Beispiel #16
0
static PyObject *uuid_random(PyObject *self, PyObject *args)
{
    struct GUID guid;
    PyObject *pyobj;
    char *str;

    if (!PyArg_ParseTuple(args, ""))
        return NULL;

    guid = GUID_random();

    str = GUID_string(NULL, &guid);
    if (str == NULL) {
        PyErr_SetString(PyExc_TypeError, "can't convert uuid to string");
        return NULL;
    }

    pyobj = PyString_FromString(str);

    talloc_free(str);

    return pyobj;
}
Beispiel #17
0
static bool test_fsrvp_sc_create(struct torture_context *tctx,
				 struct dcerpc_pipe *p,
				 const char *share,
				 enum test_fsrvp_inject inject,
				 struct fssagent_share_mapping_1 **sc_map)
{
	struct fss_IsPathSupported r_pathsupport_get;
	struct fss_GetSupportedVersion r_version_get;
	struct fss_SetContext r_context_set;
	struct fss_StartShadowCopySet r_scset_start;
	struct fss_AddToShadowCopySet r_scset_add1;
	struct fss_AddToShadowCopySet r_scset_add2;
	struct fss_PrepareShadowCopySet r_scset_prep;
	struct fss_CommitShadowCopySet r_scset_commit;
	struct fss_ExposeShadowCopySet r_scset_expose;
	struct fss_GetShareMapping r_sharemap_get;
	struct dcerpc_binding_handle *b = p->binding_handle;
	NTSTATUS status;
	time_t start_time;
	TALLOC_CTX *tmp_ctx = talloc_new(tctx);
	struct fssagent_share_mapping_1 *map = NULL;
	int sleep_time;

	/*
	 * PrepareShadowCopySet & CommitShadowCopySet often exceed the default
	 * 60 second dcerpc request timeout against Windows Server "8" Beta.
	 */
	dcerpc_binding_handle_set_timeout(b, 240);

	ZERO_STRUCT(r_pathsupport_get);
	r_pathsupport_get.in.ShareName = share;
	status = dcerpc_fss_IsPathSupported_r(b, tmp_ctx, &r_pathsupport_get);
	torture_assert_ntstatus_ok(tctx, status,
				   "IsPathSupported failed");
	torture_assert_int_equal(tctx, r_pathsupport_get.out.result, 0,
				 "failed IsPathSupported response");
	torture_assert(tctx, r_pathsupport_get.out.SupportedByThisProvider,
		       "path not supported");

	ZERO_STRUCT(r_version_get);
	status = dcerpc_fss_GetSupportedVersion_r(b, tmp_ctx, &r_version_get);
	torture_assert_ntstatus_ok(tctx, status,
				   "GetSupportedVersion failed");
	torture_assert_int_equal(tctx, r_version_get.out.result, 0,
				 "failed GetSupportedVersion response");

	ZERO_STRUCT(r_context_set);
	r_context_set.in.Context = FSRVP_CTX_BACKUP;
	status = dcerpc_fss_SetContext_r(b, tmp_ctx, &r_context_set);
	torture_assert_ntstatus_ok(tctx, status, "SetContext failed");
	torture_assert_int_equal(tctx, r_context_set.out.result, 0,
				 "failed SetContext response");

	if (inject == TEST_FSRVP_TOUT_SET_CTX) {
		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
					    "sequence timeout", 180);
		torture_comment(tctx, "sleeping for %d\n", sleep_time);
		smb_msleep((sleep_time * 1000) + 500);
	}

	ZERO_STRUCT(r_scset_start);
	r_scset_start.in.ClientShadowCopySetId = GUID_random();
	status = dcerpc_fss_StartShadowCopySet_r(b, tmp_ctx, &r_scset_start);
	torture_assert_ntstatus_ok(tctx, status,
				   "StartShadowCopySet failed");
	if (inject == TEST_FSRVP_TOUT_SET_CTX) {
		/* expect error due to message sequence timeout after set_ctx */
		torture_assert_int_equal(tctx, r_scset_start.out.result,
					 FSRVP_E_BAD_STATE,
					 "StartShadowCopySet timeout response");
		goto done;
	}
	torture_assert_int_equal(tctx, r_scset_start.out.result, 0,
				 "failed StartShadowCopySet response");
	torture_comment(tctx, "%s: shadow-copy set created\n",
			GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId));

	if (inject == TEST_FSRVP_TOUT_START_SET) {
		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
					    "sequence timeout", 180);
		torture_comment(tctx, "sleeping for %d\n", sleep_time);
		smb_msleep((sleep_time * 1000) + 500);
	}

	ZERO_STRUCT(r_scset_add1);
	r_scset_add1.in.ClientShadowCopyId = GUID_random();
	r_scset_add1.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
	r_scset_add1.in.ShareName = share;
	status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add1);
	torture_assert_ntstatus_ok(tctx, status,
				   "AddToShadowCopySet failed");
	if (inject == TEST_FSRVP_TOUT_START_SET) {
		torture_assert_int_equal(tctx, r_scset_add1.out.result,
					 HRES_ERROR_V(HRES_E_INVALIDARG),
					 "AddToShadowCopySet timeout response");
		goto done;
	}
	torture_assert_int_equal(tctx, r_scset_add1.out.result, 0,
				 "failed AddToShadowCopySet response");
	torture_comment(tctx, "%s(%s): %s added to shadow-copy set\n",
			GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
			GUID_string(tmp_ctx, r_scset_add1.out.pShadowCopyId),
			r_scset_add1.in.ShareName);

	/* attempts to add the same share twice should fail */
	ZERO_STRUCT(r_scset_add2);
	r_scset_add2.in.ClientShadowCopyId = GUID_random();
	r_scset_add2.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
	r_scset_add2.in.ShareName = share;
	status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add2);
	torture_assert_ntstatus_ok(tctx, status,
				   "AddToShadowCopySet failed");
	torture_assert_int_equal(tctx, r_scset_add2.out.result,
				 FSRVP_E_OBJECT_ALREADY_EXISTS,
				 "failed AddToShadowCopySet response");

	if (inject == TEST_FSRVP_TOUT_ADD_TO_SET) {
		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
					    "sequence timeout", 1800);
		torture_comment(tctx, "sleeping for %d\n", sleep_time);
		smb_msleep((sleep_time * 1000) + 500);
	}

	start_time = time_mono(NULL);
	ZERO_STRUCT(r_scset_prep);
	r_scset_prep.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
//	r_scset_prep.in.TimeOutInMilliseconds = (1800 * 1000);	/* win8 */
	r_scset_prep.in.TimeOutInMilliseconds = (240 * 1000);
	status = dcerpc_fss_PrepareShadowCopySet_r(b, tmp_ctx, &r_scset_prep);
	torture_assert_ntstatus_ok(tctx, status,
				   "PrepareShadowCopySet failed");
	if (inject == TEST_FSRVP_TOUT_ADD_TO_SET) {
		torture_assert_int_equal(tctx, r_scset_prep.out.result,
					 HRES_ERROR_V(HRES_E_INVALIDARG),
					 "PrepareShadowCopySet tout response");
		goto done;
	}
	torture_assert_int_equal(tctx, r_scset_prep.out.result, 0,
				 "failed PrepareShadowCopySet response");
	torture_comment(tctx, "%s: prepare completed in %llu secs\n",
			GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
			(unsigned long long)(time_mono(NULL) - start_time));

	if (inject == TEST_FSRVP_TOUT_PREPARE) {
		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
					    "sequence timeout", 1800);
		torture_comment(tctx, "sleeping for %d\n", sleep_time);
		smb_msleep((sleep_time * 1000) + 500);
	}

	start_time = time_mono(NULL);
	ZERO_STRUCT(r_scset_commit);
	r_scset_commit.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
	r_scset_commit.in.TimeOutInMilliseconds = (180 * 1000);	/* win8 */
	status = dcerpc_fss_CommitShadowCopySet_r(b, tmp_ctx, &r_scset_commit);
	torture_assert_ntstatus_ok(tctx, status,
				   "CommitShadowCopySet failed");
	if (inject == TEST_FSRVP_TOUT_PREPARE) {
		torture_assert_int_equal(tctx, r_scset_commit.out.result,
					 HRES_ERROR_V(HRES_E_INVALIDARG),
					 "CommitShadowCopySet tout response");
		goto done;
	}
	torture_assert_int_equal(tctx, r_scset_commit.out.result, 0,
				 "failed CommitShadowCopySet response");
	torture_comment(tctx, "%s: commit completed in %llu secs\n",
			GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId),
			(unsigned long long)(time_mono(NULL) - start_time));

	if (inject == TEST_FSRVP_TOUT_COMMIT) {
		sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss",
					    "sequence timeout", 180);
		torture_comment(tctx, "sleeping for %d\n", sleep_time);
		smb_msleep((sleep_time * 1000) + 500);
	} else if (inject == TEST_FSRVP_STOP_B4_EXPOSE) {
		/* return partial snapshot information */
		map = talloc_zero(tctx, struct fssagent_share_mapping_1);
		map->ShadowCopySetId = *r_scset_start.out.pShadowCopySetId;
		map->ShadowCopyId = *r_scset_add1.out.pShadowCopyId;
		goto done;
	}
Beispiel #18
0
/**
 * lease_v2 variant of reopen2
 * basic test for doing a durable open
 * tcp disconnect, reconnect, do a durable reopen (succeeds)
 */
bool test_durable_v2_open_reopen2_lease_v2(struct torture_context *tctx,
					   struct smb2_tree *tree)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char fname[256];
	struct smb2_handle _h;
	struct smb2_handle *h = NULL;
	struct smb2_create io;
	struct GUID create_guid = GUID_random();
	struct smb2_lease ls;
	uint64_t lease_key;
	bool ret = true;
	struct smbcli_options options;
	uint32_t caps;

	caps = smb2cli_conn_server_capabilities(tree->session->transport->conn);
	if (!(caps & SMB2_CAP_LEASING)) {
		torture_skip(tctx, "leases are not supported");
	}

	options = tree->session->transport->options;

	/* Choose a random name in case the state is left a little funky. */
	snprintf(fname, 256, "durable_v2_open_reopen2_%s.dat",
		 generate_random_str(tctx, 8));

	smb2_util_unlink(tree, fname);

	lease_key = random();
	smb2_lease_v2_create(&io, &ls, false /* dir */, fname,
			     lease_key, 0, /* parent lease key */
			     smb2_util_lease_state("RWH"), 0 /* lease epoch */);
	io.in.durable_open = false;
	io.in.durable_open_v2 = true;
	io.in.persistent_open = false;
	io.in.create_guid = create_guid;
	io.in.timeout = UINT32_MAX;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h = io.out.file.handle;
	h = &_h;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, true);
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.timeout, io.in.timeout);
	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
	CHECK_VAL(io.out.lease_response_v2.lease_key.data[0], lease_key);
	CHECK_VAL(io.out.lease_response_v2.lease_key.data[1], ~lease_key);

	/* disconnect, reconnect and then do durable reopen */
	TALLOC_FREE(tree);

	if (!torture_smb2_connection_ext(tctx, 0, &options, &tree)) {
		torture_warning(tctx, "couldn't reconnect, bailing\n");
		ret = false;
		goto done;
	}

	/* a few failure tests: */

	/*
	 * several attempts without lease attached:
	 * all fail with NT_STATUS_OBJECT_NAME_NOT_FOUND
	 * irrespective of file name provided
	 */

	ZERO_STRUCT(io);
	io.in.fname = "";
	io.in.durable_handle_v2 = h;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	ZERO_STRUCT(io);
	io.in.fname = "__non_existing_fname__";
	io.in.durable_handle_v2 = h;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_handle_v2 = h;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	/*
	 * attempt with lease provided, but
	 * with a changed lease key. => fails
	 */
	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_open_v2 = false;
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid;
	io.in.lease_request_v2 = &ls;
	io.in.oplock_level = SMB2_OPLOCK_LEVEL_LEASE;
	/* a wrong lease key lets the request fail */
	ls.lease_key.data[0]++;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	/* restore the correct lease key */
	ls.lease_key.data[0]--;


	/*
	 * this last failing attempt is almost correct:
	 * only problem is: we use the wrong filename...
	 * Note that this gives INVALID_PARAMETER.
	 * This is different from oplocks!
	 */
	ZERO_STRUCT(io);
	io.in.fname = "__non_existing_fname__";
	io.in.durable_open_v2 = false;
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid;
	io.in.lease_request_v2 = &ls;
	io.in.oplock_level = SMB2_OPLOCK_LEVEL_LEASE;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

	/*
	 * Now for a succeeding reconnect:
	 */

	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_open_v2 = false;
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid;
	io.in.lease_request_v2 = &ls;
	io.in.oplock_level = SMB2_OPLOCK_LEVEL_LEASE;

	/* the requested lease state is irrelevant */
	ls.lease_state = smb2_util_lease_state("");

	h = NULL;

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

	CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, false); /* no dh2q response blob */
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
	CHECK_VAL(io.out.lease_response_v2.lease_key.data[0], lease_key);
	CHECK_VAL(io.out.lease_response_v2.lease_key.data[1], ~lease_key);
	CHECK_VAL(io.out.lease_response_v2.lease_state,
		  smb2_util_lease_state("RWH"));
	CHECK_VAL(io.out.lease_response_v2.lease_flags, 0);
	CHECK_VAL(io.out.lease_response_v2.lease_duration, 0);
	_h = io.out.file.handle;
	h = &_h;

	/* disconnect one more time */
	TALLOC_FREE(tree);

	if (!torture_smb2_connection_ext(tctx, 0, &options, &tree)) {
		torture_warning(tctx, "couldn't reconnect, bailing\n");
		ret = false;
		goto done;
	}

	/*
	 * demonstrate that various parameters are ignored
	 * in the reconnect
	 */

	ZERO_STRUCT(io);
	/*
	 * These are completely ignored by the server
	 */
	io.in.security_flags = 0x78;
	io.in.oplock_level = 0x78;
	io.in.impersonation_level = 0x12345678;
	io.in.create_flags = 0x12345678;
	io.in.reserved = 0x12345678;
	io.in.desired_access = 0x12345678;
	io.in.file_attributes = 0x12345678;
	io.in.share_access = 0x12345678;
	io.in.create_disposition = 0x12345678;
	io.in.create_options = 0x12345678;
	io.in.fname = "__non_existing_fname__";

	/*
	 * only these are checked:
	 * - io.in.fname
	 * - io.in.durable_handle_v2,
	 * - io.in.create_guid
	 * - io.in.lease_request_v2->lease_key
	 */

	io.in.fname = fname;
	io.in.durable_open_v2 = false;
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid;
	io.in.lease_request_v2 = &ls;

	/* the requested lease state is irrelevant */
	ls.lease_state = smb2_util_lease_state("");

	h = NULL;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, false); /* no dh2q response blob */
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE);
	CHECK_VAL(io.out.lease_response_v2.lease_key.data[0], lease_key);
	CHECK_VAL(io.out.lease_response_v2.lease_key.data[1], ~lease_key);
	CHECK_VAL(io.out.lease_response_v2.lease_state,
		  smb2_util_lease_state("RWH"));
	CHECK_VAL(io.out.lease_response_v2.lease_flags, 0);
	CHECK_VAL(io.out.lease_response_v2.lease_duration, 0);

	_h = io.out.file.handle;
	h = &_h;

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

	smb2_util_unlink(tree, fname);

	talloc_free(tree);

	talloc_free(mem_ctx);

	return ret;
}
Beispiel #19
0
/**
 * Test durable request / reconnect with AppInstanceId
 */
bool test_durable_v2_open_app_instance(struct torture_context *tctx,
				       struct smb2_tree *tree1,
				       struct smb2_tree *tree2)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char fname[256];
	struct smb2_handle _h1, _h2;
	struct smb2_handle *h1 = NULL, *h2 = NULL;
	struct smb2_create io1, io2;
	bool ret = true;
	struct GUID create_guid_1 = GUID_random();
	struct GUID create_guid_2 = GUID_random();
	struct GUID app_instance_id = GUID_random();

	/* Choose a random name in case the state is left a little funky. */
	snprintf(fname, 256, "durable_v2_open_app_instance_%s.dat",
		 generate_random_str(tctx, 8));

	smb2_util_unlink(tree1, fname);

	ZERO_STRUCT(break_info);
	tree1->session->transport->oplock.handler = torture_oplock_handler;
	tree1->session->transport->oplock.private_data = tree1;

	smb2_oplock_create_share(&io1, fname,
				 smb2_util_share_access(""),
				 smb2_util_oplock_level("b"));
	io1.in.durable_open = false;
	io1.in.durable_open_v2 = true;
	io1.in.persistent_open = false;
	io1.in.create_guid = create_guid_1;
	io1.in.app_instance_id = &app_instance_id;
	io1.in.timeout = UINT32_MAX;

	status = smb2_create(tree1, 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"));
	CHECK_VAL(io1.out.durable_open, false);
	CHECK_VAL(io1.out.durable_open_v2, true);
	CHECK_VAL(io1.out.persistent_open, false);
	CHECK_VAL(io1.out.timeout, io1.in.timeout);

	/*
	 * try to open the file as durable from a second tree with
	 * a different create guid but the same app_instance_id
	 * while the first handle is still open.
	 */

	smb2_oplock_create_share(&io2, fname,
				 smb2_util_share_access(""),
				 smb2_util_oplock_level("b"));
	io2.in.durable_open = false;
	io2.in.durable_open_v2 = true;
	io2.in.persistent_open = false;
	io2.in.create_guid = create_guid_2;
	io2.in.app_instance_id = &app_instance_id;
	io2.in.timeout = UINT32_MAX;

	status = smb2_create(tree2, mem_ctx, &io2);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h2 = io2.out.file.handle;
	h2 = &_h2;
	CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b"));
	CHECK_VAL(io2.out.durable_open, false);
	CHECK_VAL(io2.out.durable_open_v2, true);
	CHECK_VAL(io2.out.persistent_open, false);
	CHECK_VAL(io2.out.timeout, io2.in.timeout);

	CHECK_VAL(break_info.count, 0);

	status = smb2_util_close(tree1, *h1);
	CHECK_STATUS(status, NT_STATUS_FILE_CLOSED);
	h1 = NULL;

done:
	if (h1 != NULL) {
		smb2_util_close(tree1, *h1);
	}
	if (h2 != NULL) {
		smb2_util_close(tree2, *h2);
	}

	smb2_util_unlink(tree2, fname);

	talloc_free(tree1);
	talloc_free(tree2);

	talloc_free(mem_ctx);

	return ret;
}
Beispiel #20
0
/**
 * Basic test for doing a durable open
 * and do a session reconnect while the first
 * session is still active and the handle is
 * still open in the client.
 * This closes the original session and  a
 * durable reconnect on the new session succeeds.
 */
bool test_durable_v2_open_reopen1a(struct torture_context *tctx,
				   struct smb2_tree *tree)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char fname[256];
	struct smb2_handle _h;
	struct smb2_handle *h = NULL;
	struct smb2_create io, io2;
	struct GUID create_guid = GUID_random();
	bool ret = true;
	struct smb2_tree *tree2 = NULL;
	uint64_t previous_session_id;
	struct smbcli_options options;

	options = tree->session->transport->options;

	/* Choose a random name in case the state is left a little funky. */
	snprintf(fname, 256, "durable_v2_open_reopen1a_%s.dat",
		 generate_random_str(tctx, 8));

	smb2_util_unlink(tree, fname);

	smb2_oplock_create_share(&io, fname,
				 smb2_util_share_access(""),
				 smb2_util_oplock_level("b"));
	io.in.durable_open = false;
	io.in.durable_open_v2 = true;
	io.in.persistent_open = false;
	io.in.create_guid = create_guid;
	io.in.timeout = UINT32_MAX;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h = io.out.file.handle;
	h = &_h;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, true);
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.timeout, io.in.timeout);

	/*
	 * a session reconnect on a second tcp connection
	 */

	previous_session_id = smb2cli_session_current_id(tree->session->smbXcli);

	if (!torture_smb2_connection_ext(tctx, previous_session_id,
					 &options, &tree2))
	{
		torture_warning(tctx, "couldn't reconnect, bailing\n");
		ret = false;
		goto done;
	}

	/*
	 * check that this has deleted the old session
	 */

	ZERO_STRUCT(io);
	io.in.fname = "";
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_USER_SESSION_DELETED);

	/*
	 * but a durable reconnect on the new session succeeds:
	 */

	ZERO_STRUCT(io2);
	io2.in.fname = "";
	io2.in.durable_handle_v2 = h;
	io2.in.create_guid = create_guid;
	status = smb2_create(tree2, mem_ctx, &io2);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_CREATED(&io2, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io2.out.oplock_level, smb2_util_oplock_level("b"));
	CHECK_VAL(io2.out.durable_open, false);
	CHECK_VAL(io2.out.durable_open_v2, false); /* no dh2q response blob */
	CHECK_VAL(io2.out.persistent_open, false);
	CHECK_VAL(io2.out.timeout, io.in.timeout);
	_h = io2.out.file.handle;
	h = &_h;

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

	smb2_util_unlink(tree, fname);

	talloc_free(tree);

	talloc_free(mem_ctx);

	return ret;
}
Beispiel #21
0
uint32_t _fss_AddToShadowCopySet(struct pipes_struct *p,
				 struct fss_AddToShadowCopySet *r)
{
	uint32_t ret;
	struct fss_sc_set *sc_set;
	struct fss_sc *sc;
	struct fss_sc_smap *sc_smap;
	int snum;
	char *service;
	char *base_vol;
	char *share;
	char *path_name;
	struct connection_struct *conn;
	NTSTATUS status;
	TALLOC_CTX *tmp_ctx = talloc_new(p->mem_ctx);
	if (tmp_ctx == NULL) {
		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
		goto err_out;
	}

	if (!fss_permitted(p)) {
		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
		goto err_tmp_free;
	}

	sc_set = sc_set_lookup(fss_global.sc_sets, &r->in.ShadowCopySetId);
	if (sc_set == NULL) {
		ret = HRES_ERROR_V(HRES_E_INVALIDARG);
		goto err_tmp_free;
	}

	status = fss_unc_parse(tmp_ctx, r->in.ShareName, NULL, &share);
	if (!NT_STATUS_IS_OK(status)) {
		ret = fss_ntstatus_map(status);
		goto err_tmp_free;
	}

	snum = find_service(tmp_ctx, share, &service);
	if ((snum == -1) || (service == NULL)) {
		DEBUG(0, ("share at %s not found\n", r->in.ShareName));
		ret = HRES_ERROR_V(HRES_E_INVALIDARG);
		goto err_tmp_free;
	}

	path_name = lp_path(tmp_ctx, snum);
	if (path_name == NULL) {
		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
		goto err_tmp_free;
	}

	status = fss_vfs_conn_create(tmp_ctx, server_event_context(),
				     p->msg_ctx, p->session_info, snum, &conn);
	if (!NT_STATUS_IS_OK(status)) {
		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
		goto err_tmp_free;
	}
	if (!become_user_by_session(conn, p->session_info)) {
		DEBUG(0, ("failed to become user\n"));
		fss_vfs_conn_destroy(conn);
		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
		goto err_tmp_free;
	}

	status = SMB_VFS_SNAP_CHECK_PATH(conn, tmp_ctx, path_name, &base_vol);
	unbecome_user();
	fss_vfs_conn_destroy(conn);
	if (!NT_STATUS_IS_OK(status)) {
		ret = FSRVP_E_NOT_SUPPORTED;
		goto err_tmp_free;
	}

	if ((sc_set->state != FSS_SC_STARTED)
	 && (sc_set->state != FSS_SC_ADDED)) {
		ret = FSRVP_E_BAD_STATE;
		goto err_tmp_free;
	}

	/* stop msg seq timer */
	TALLOC_FREE(fss_global.seq_tmr);

	/*
	 * server MUST look up the ShadowCopy in ShadowCopySet.ShadowCopyList
	 * where ShadowCopy.VolumeName matches the file store on which the
	 * share identified by ShareName is hosted. If an entry is found, the
	 * server MUST fail the call with FSRVP_E_OBJECT_ALREADY_EXISTS.
	 * If no entry is found, the server MUST create a new ShadowCopy
	 * object
	 * XXX Windows appears to allow multiple mappings for the same vol!
	 */
	sc = sc_lookup_volname(sc_set->scs, base_vol);
	if (sc != NULL) {
		ret = FSRVP_E_OBJECT_ALREADY_EXISTS;
		goto err_tmr_restart;
	}

	sc = talloc_zero(sc_set, struct fss_sc);
	if (sc == NULL) {
		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
		goto err_tmr_restart;
	}
	talloc_steal(sc, base_vol);
	sc->volume_name = base_vol;
	sc->sc_set = sc_set;
	sc->create_ts = time(NULL);

	sc->id = GUID_random();	/* Windows servers ignore client ids */
	sc->id_str = GUID_string(sc, &sc->id);
	if (sc->id_str == NULL) {
		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
		goto err_sc_free;
	}

	sc_smap = talloc_zero(sc, struct fss_sc_smap);
	if (sc_smap == NULL) {
		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
		goto err_sc_free;
	}

	talloc_steal(sc_smap, service);
	sc_smap->share_name = service;
	sc_smap->is_exposed = false;
	/*
	 * generate the sc_smap share name now. It is a unique identifier for
	 * the smap used as a tdb key for state storage.
	 */
	ret = map_share_name(sc_smap, sc);
	if (ret) {
		goto err_sc_free;
	}

	/* add share map to shadow-copy */
	DLIST_ADD_END(sc->smaps, sc_smap, struct fss_sc_smap *);
	sc->smaps_count++;
	/* add shadow-copy to shadow-copy set */
	DLIST_ADD_END(sc_set->scs, sc, struct fss_sc *);
	sc_set->scs_count++;
	DEBUG(4, ("added volume %s to shadow copy set with GUID %s\n",
		  sc->volume_name, sc_set->id_str));

	/* start the Message Sequence Timer with timeout of 1800 seconds */
	fss_seq_tout_set(fss_global.mem_ctx, 1800, sc_set, &fss_global.seq_tmr);

	sc_set->state = FSS_SC_ADDED;
	r->out.pShadowCopyId = &sc->id;

	talloc_free(tmp_ctx);
	return 0;

err_sc_free:
	talloc_free(sc);
err_tmr_restart:
	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr);
err_tmp_free:
	talloc_free(tmp_ctx);
err_out:
	return ret;
}
Beispiel #22
0
uint32_t _fss_StartShadowCopySet(struct pipes_struct *p,
				 struct fss_StartShadowCopySet *r)
{
	struct fss_sc_set *sc_set;
	uint32_t ret;

	if (!fss_permitted(p)) {
		ret = HRES_ERROR_V(HRES_E_ACCESSDENIED);
		goto err_out;
	}

	if (!fss_global.ctx_set) {
		DEBUG(3, ("invalid sequence: start sc set requested without "
			  "prior context set\n"));
		ret = FSRVP_E_BAD_STATE;
		goto err_out;
	}

	/*
	 * At any given time, Windows servers allow only one shadow copy set to
	 * be going through the creation process.
	 */
	if (sc_set_active(fss_global.sc_sets)) {
		DEBUG(3, ("StartShadowCopySet called while in progress\n"));
		ret = FSRVP_E_SHADOW_COPY_SET_IN_PROGRESS;
		goto err_out;
	}

	/* stop msg seq timer */
	TALLOC_FREE(fss_global.seq_tmr);

	sc_set = talloc_zero(fss_global.mem_ctx, struct fss_sc_set);
	if (sc_set == NULL) {
		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
		goto err_tmr_restart;
	}

	sc_set->id = GUID_random();	/* Windows servers ignore client ids */
	sc_set->id_str = GUID_string(sc_set, &sc_set->id);
	if (sc_set->id_str == NULL) {
		ret = HRES_ERROR_V(HRES_E_OUTOFMEMORY);
		goto err_sc_set_free;
	}
	sc_set->state = FSS_SC_STARTED;
	sc_set->context = fss_global.cur_ctx;
	DLIST_ADD_END(fss_global.sc_sets, sc_set, struct fss_sc_set *);
	fss_global.sc_sets_count++;
	DEBUG(6, ("%s: shadow-copy set %u added\n",
		  sc_set->id_str, fss_global.sc_sets_count));

	/* start msg seq timer */
	fss_seq_tout_set(fss_global.mem_ctx, 180, sc_set, &fss_global.seq_tmr);

	r->out.pShadowCopySetId = &sc_set->id;

	return 0;

err_sc_set_free:
	talloc_free(sc_set);
err_tmr_restart:
	fss_seq_tout_set(fss_global.mem_ctx, 180, NULL, &fss_global.seq_tmr);
err_out:
	return ret;
}
Beispiel #23
0
/**
 * testing various create blob combinations.
 */
bool test_durable_v2_open_create_blob(struct torture_context *tctx,
				      struct smb2_tree *tree)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char fname[256];
	struct smb2_handle _h;
	struct smb2_handle *h = NULL;
	struct smb2_create io;
	struct GUID create_guid = GUID_random();
	bool ret = true;
	struct smbcli_options options;

	options = tree->session->transport->options;

	/* Choose a random name in case the state is left a little funky. */
	snprintf(fname, 256, "durable_v2_open_create_blob_%s.dat",
		 generate_random_str(tctx, 8));

	smb2_util_unlink(tree, fname);

	smb2_oplock_create_share(&io, fname,
				 smb2_util_share_access(""),
				 smb2_util_oplock_level("b"));
	io.in.durable_open = false;
	io.in.durable_open_v2 = true;
	io.in.persistent_open = false;
	io.in.create_guid = create_guid;
	io.in.timeout = UINT32_MAX;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h = io.out.file.handle;
	h = &_h;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, true);
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.timeout, io.in.timeout);

	/* disconnect */
	TALLOC_FREE(tree);

	/* create a new session (same client_guid) */
	if (!torture_smb2_connection_ext(tctx, 0, &options, &tree)) {
		torture_warning(tctx, "couldn't reconnect, bailing\n");
		ret = false;
		goto done;
	}

	/*
	 * check invalid combinations of durable handle
	 * request and reconnect blobs
	 * See MS-SMB2: 3.3.5.9.12
	 * Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context
	 */
	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_handle_v2 = h; /* durable v2 reconnect request */
	io.in.durable_open = true;   /* durable v1 handle request */
	io.in.create_guid = create_guid;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_handle = h;     /* durable v1 reconnect request */
	io.in.durable_open_v2 = true; /* durable v2 handle request */
	io.in.create_guid = create_guid;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_handle = h;    /* durable v1 reconnect request */
	io.in.durable_handle_v2 = h; /* durable v2 reconnect request */
	io.in.create_guid = create_guid;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_handle_v2 = h;  /* durable v2 reconnect request */
	io.in.durable_open_v2 = true; /* durable v2 handle request */
	io.in.create_guid = create_guid;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);

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

	smb2_util_unlink(tree, fname);

	talloc_free(tree);

	talloc_free(mem_ctx);

	return ret;
}
Beispiel #24
0
/*
  test netlogon operations
*/
static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
{
	struct cldap_socket *cldap;
	NTSTATUS status;
	struct cldap_netlogon search, empty_search;
	struct netlogon_samlogon_response n1;
	struct GUID guid;
	int i;
	struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
	struct tsocket_address *dest_addr;
	int ret;

	ret = tsocket_address_inet_from_strings(tctx, "ip",
						dest,
						lp_cldap_port(tctx->lp_ctx),
						&dest_addr);

	status = cldap_socket_init(tctx, NULL, NULL, dest_addr, &cldap);
	CHECK_STATUS(status, NT_STATUS_OK);

	ZERO_STRUCT(search);
	search.in.dest_address = NULL;
	search.in.dest_port = 0;
	search.in.acct_control = -1;
	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	search.in.map_response = true;

	empty_search = search;

	printf("Trying without any attributes\n");
	search = empty_search;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	n1 = search.out.netlogon;

	search.in.user         = "******";
	search.in.realm        = n1.data.nt5_ex.dns_domain;
	search.in.host         = "__cldap_torture__";

	printf("Scanning for netlogon levels\n");
	for (i=0;i<256;i++) {
		search.in.version = i;
		printf("Trying netlogon level %d\n", i);
		status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	printf("Scanning for netlogon level bits\n");
	for (i=0;i<31;i++) {
		search.in.version = (1<<i);
		printf("Trying netlogon level 0x%x\n", i);
		status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	search.in.version = NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_IP;

	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=NULL\n");

	search.in.user = NULL;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);

	printf("Trying with User=Administrator\n");

	search.in.user = "******";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);

	search.in.version = NETLOGON_NT_VERSION_5;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=NULL\n");

	search.in.user = NULL;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE);

	printf("Trying with User=Administrator\n");

	search.in.user = "******";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN);

	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;

	printf("Trying with a GUID\n");
	search.in.realm       = NULL;
	search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
	CHECK_STRING(GUID_string(tctx, &search.out.netlogon.data.nt5_ex.domain_uuid), search.in.domain_guid);

	printf("Trying with a incorrect GUID\n");
	guid = GUID_random();
	search.in.user        = NULL;
	search.in.domain_guid = GUID_string(tctx, &guid);
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a AAC\n");
	search.in.acct_control = ACB_WSTRUST|ACB_SVRTRUST;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a zero AAC\n");
	search.in.acct_control = 0x0;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a zero AAC and user=Administrator\n");
	search.in.acct_control = 0x0;
	search.in.user = "******";
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "Administrator");

	printf("Trying with a bad AAC\n");
	search.in.user = NULL;
	search.in.acct_control = 0xFF00FF00;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a user only\n");
	search = empty_search;
	search.in.user = "******";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);

	printf("Trying with just a bad username\n");
	search.in.user = "******";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);

	printf("Trying with just a bad domain\n");
	search = empty_search;
	search.in.realm = "___no_such_domain___";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a incorrect domain and correct guid\n");
	search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);

	printf("Trying with a incorrect domain and incorrect guid\n");
	search.in.domain_guid = GUID_string(tctx, &guid);
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);

	printf("Trying with a incorrect GUID and correct domain\n");
	search.in.domain_guid = GUID_string(tctx, &guid);
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);

	return true;
}
Beispiel #25
0
/**
 * durable reconnect test:
 * connect with v1, reconnect with v2 : fails (no create_guid...)
 */
bool test_durable_v2_open_reopen2c(struct torture_context *tctx,
				   struct smb2_tree *tree)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char fname[256];
	struct smb2_handle _h;
	struct smb2_handle *h = NULL;
	struct smb2_create io;
	struct GUID create_guid = GUID_random();
	bool ret = true;
	struct smbcli_options options;

	options = tree->session->transport->options;

	/* Choose a random name in case the state is left a little funky. */
	snprintf(fname, 256, "durable_v2_open_reopen2c_%s.dat",
		 generate_random_str(tctx, 8));

	smb2_util_unlink(tree, fname);

	smb2_oplock_create_share(&io, fname,
				 smb2_util_share_access(""),
				 smb2_util_oplock_level("b"));
	io.in.durable_open = true;
	io.in.durable_open_v2 = false;
	io.in.persistent_open = false;
	io.in.create_guid = create_guid;
	io.in.timeout = UINT32_MAX;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h = io.out.file.handle;
	h = &_h;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
	CHECK_VAL(io.out.durable_open, true);
	CHECK_VAL(io.out.durable_open_v2, false);
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.timeout, 0);

	/* disconnect, leaving the durable open */
	TALLOC_FREE(tree);

	if (!torture_smb2_connection_ext(tctx, 0, &options, &tree)) {
		torture_warning(tctx, "couldn't reconnect, bailing\n");
		ret = false;
		goto done;
	}

	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_handle_v2 = h;     /* durable v2 reconnect */
	io.in.create_guid = create_guid;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

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

	smb2_util_unlink(tree, fname);

	talloc_free(tree);

	talloc_free(mem_ctx);

	return ret;
}
Beispiel #26
0
NTSTATUS gp_create_gpo (struct gp_context *gp_ctx, const char *display_name, struct gp_object **ret)
{
	struct GUID guid_struct;
	char *guid_str;
	char *name;
	struct security_descriptor *sd;
	TALLOC_CTX *mem_ctx;
	struct gp_object *gpo;
	NTSTATUS status;

	/* Create a forked memory context, as a base for everything here */
	mem_ctx = talloc_new(gp_ctx);
	NT_STATUS_HAVE_NO_MEMORY(mem_ctx);

	/* Create the gpo struct to return later */
	gpo = talloc(gp_ctx, struct gp_object);
	if (gpo == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* Generate a GUID */
	guid_struct = GUID_random();
	guid_str = GUID_string2(mem_ctx, &guid_struct);
	if (guid_str == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}
	name = strupper_talloc(mem_ctx, guid_str);
	if (name == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* Prepare the GPO struct */
	gpo->dn = NULL;
	gpo->name = name;
	gpo->flags = 0;
	gpo->version = 0;
	gpo->display_name = talloc_strdup(gpo, display_name);
	if (gpo->display_name == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	gpo->file_sys_path = talloc_asprintf(gpo, "\\\\%s\\sysvol\\%s\\Policies\\%s", lpcfg_dnsdomain(gp_ctx->lp_ctx), lpcfg_dnsdomain(gp_ctx->lp_ctx), name);
	if (gpo->file_sys_path == NULL) {
		TALLOC_FREE(mem_ctx);
		return NT_STATUS_NO_MEMORY;
	}

	/* Create the GPT */
	status = gp_create_gpt(gp_ctx, name, gpo->file_sys_path);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to create GPT\n"));
		talloc_free(mem_ctx);
		return status;
	}


	/* Create the LDAP GPO, including CN=User and CN=Machine */
	status = gp_create_ldap_gpo(gp_ctx, gpo);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to create LDAP group policy object\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* Get the new security descriptor */
	status = gp_get_gpo_info(gp_ctx, gpo->dn, &gpo);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to fetch LDAP group policy object\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* Create matching file and DS security descriptors */
	status = gp_create_gpt_security_descriptor(mem_ctx, gpo->security_descriptor, &sd);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to convert ADS security descriptor to filesystem security descriptor\n"));
		talloc_free(mem_ctx);
		return status;
	}

	/* Set the security descriptor on the filesystem for this GPO */
	status = gp_set_gpt_security_descriptor(gp_ctx, gpo, sd);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to set security descriptor (ACL) on the file system\n"));
		talloc_free(mem_ctx);
		return status;
	}

	talloc_free(mem_ctx);

	*ret = gpo;
	return NT_STATUS_OK;
}
Beispiel #27
0
/*
  test netlogon operations
*/
static bool test_ldap_netlogon(struct torture_context *tctx,
			       request_netlogon_t request_netlogon,
			       void *cldap,
			       const char *dest)
{
	NTSTATUS status;
	struct cldap_netlogon search, empty_search;
	struct netlogon_samlogon_response n1;
	struct GUID guid;
	int i;

	ZERO_STRUCT(search);
	search.in.dest_address = NULL;
	search.in.dest_port = 0;
	search.in.acct_control = -1;
	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	search.in.map_response = true;

	empty_search = search;

	printf("Trying without any attributes\n");
	search = empty_search;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	n1 = search.out.netlogon;

	search.in.user         = "******";
	search.in.realm        = n1.data.nt5_ex.dns_domain;
	search.in.host         = "__cldap_torture__";

	printf("Scanning for netlogon levels\n");
	for (i=0;i<256;i++) {
		search.in.version = i;
		printf("Trying netlogon level %d\n", i);
		status = request_netlogon(cldap, tctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	printf("Scanning for netlogon level bits\n");
	for (i=0;i<31;i++) {
		search.in.version = (1<<i);
		printf("Trying netlogon level 0x%x\n", i);
		status = request_netlogon(cldap, tctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	search.in.version = NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_IP;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=NULL\n");
	search.in.user = NULL;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	torture_assert(tctx,
		       strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") == NULL,
		       "PDC name should not be in UNC form");

	printf("Trying with User=Administrator\n");
	search.in.user = "******";
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	torture_assert(tctx,
		       strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") == NULL,
		       "PDC name should not be in UNC form");

	search.in.version = NETLOGON_NT_VERSION_5;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=NULL\n");
	search.in.user = NULL;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	torture_assert(tctx,
		       strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
		       "PDC name should be in UNC form");

	printf("Trying with User=Administrator\n");
	search.in.user = "******";
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	torture_assert(tctx,
		       strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") != NULL,
		       "PDC name should be in UNC form");

	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;

	printf("Trying with a GUID\n");
	search.in.realm       = NULL;
	search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
	CHECK_STRING(GUID_string(tctx, &search.out.netlogon.data.nt5_ex.domain_uuid), search.in.domain_guid);
	torture_assert(tctx,
		       strstr(search.out.netlogon.data.nt5_ex.pdc_name, "\\\\") == NULL,
		       "PDC name should not be in UNC form");

	printf("Trying with a incorrect GUID\n");
	guid = GUID_random();
	search.in.user        = NULL;
	search.in.domain_guid = GUID_string(tctx, &guid);
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a AAC\n");
	search.in.acct_control = ACB_WSTRUST|ACB_SVRTRUST;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a zero AAC\n");
	search.in.acct_control = 0x0;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a zero AAC and user=Administrator\n");
	search.in.acct_control = 0x0;
	search.in.user = "******";
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "Administrator");

	printf("Trying with a bad AAC\n");
	search.in.user = NULL;
	search.in.acct_control = 0xFF00FF00;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a user only\n");
	search = empty_search;
	search.in.user = "******";
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);

	printf("Trying with just a bad username\n");
	search.in.user = "******";
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);

	printf("Trying with just a bad domain\n");
	search = empty_search;
	search.in.realm = "___no_such_domain___";
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a incorrect domain and correct guid\n");
	search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);

	printf("Trying with a incorrect domain and incorrect guid\n");
	search.in.domain_guid = GUID_string(tctx, &guid);
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);

	printf("Trying with a incorrect GUID and correct domain\n");
	search.in.domain_guid = GUID_string(tctx, &guid);
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);

	printf("Proof other results\n");
	search.in.user = "******";
	status = request_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.forest, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.domain_name, n1.data.nt5_ex.domain_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.pdc_name, n1.data.nt5_ex.pdc_name);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.server_site, n1.data.nt5_ex.server_site);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.client_site, n1.data.nt5_ex.client_site);

	return true;
}
Beispiel #28
0
/**
 * basic test for doing a durable open
 * tcp disconnect, reconnect, do a durable reopen (succeeds)
 */
bool test_durable_v2_open_reopen2(struct torture_context *tctx,
				  struct smb2_tree *tree)
{
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = talloc_new(tctx);
	char fname[256];
	struct smb2_handle _h;
	struct smb2_handle *h = NULL;
	struct smb2_create io;
	struct GUID create_guid = GUID_random();
	struct GUID create_guid_invalid = GUID_random();
	bool ret = true;

	/* Choose a random name in case the state is left a little funky. */
	snprintf(fname, 256, "durable_v2_open_reopen2_%s.dat",
		 generate_random_str(tctx, 8));

	smb2_util_unlink(tree, fname);

	smb2_oplock_create_share(&io, fname,
				 smb2_util_share_access(""),
				 smb2_util_oplock_level("b"));
	io.in.durable_open = false;
	io.in.durable_open_v2 = true;
	io.in.persistent_open = false;
	io.in.create_guid = create_guid;
	io.in.timeout = UINT32_MAX;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	_h = io.out.file.handle;
	h = &_h;
	CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, true);
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.timeout, io.in.timeout);

	/* disconnect, leaving the durable open */
	TALLOC_FREE(tree);

	if (!torture_smb2_connection(tctx, &tree)) {
		torture_warning(tctx, "couldn't reconnect, bailing\n");
		ret = false;
		goto done;
	}

	/*
	 * first a few failure cases
	 */

	ZERO_STRUCT(io);
	io.in.fname = "";
	io.in.durable_handle_v2 = h;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	ZERO_STRUCT(io);
	io.in.fname = "__non_existing_fname__";
	io.in.durable_handle_v2 = h;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_handle_v2 = h;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	/* a non-zero but non-matching create_guid does not change it: */
	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid_invalid;
	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);

	/*
	 * now success:
	 * The important difference is that the create_guid is provided.
	 */
	ZERO_STRUCT(io);
	io.in.fname = fname;
	io.in.durable_open_v2 = false;
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid;
	h = NULL;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, false); /* no dh2q response blob */
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
	_h = io.out.file.handle;
	h = &_h;

	/* disconnect one more time */
	TALLOC_FREE(tree);

	if (!torture_smb2_connection(tctx, &tree)) {
		torture_warning(tctx, "couldn't reconnect, bailing\n");
		ret = false;
		goto done;
	}

	ZERO_STRUCT(io);
	/* These are completely ignored by the server */
	io.in.security_flags = 0x78;
	io.in.oplock_level = 0x78;
	io.in.impersonation_level = 0x12345678;
	io.in.create_flags = 0x12345678;
	io.in.reserved = 0x12345678;
	io.in.desired_access = 0x12345678;
	io.in.file_attributes = 0x12345678;
	io.in.share_access = 0x12345678;
	io.in.create_disposition = 0x12345678;
	io.in.create_options = 0x12345678;
	io.in.fname = "__non_existing_fname__";

	/*
	 * only io.in.durable_handle_v2 and
	 * io.in.create_guid are checked
	 */
	io.in.durable_open_v2 = false;
	io.in.durable_handle_v2 = h;
	io.in.create_guid = create_guid;
	h = NULL;

	status = smb2_create(tree, mem_ctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE);
	CHECK_VAL(io.out.durable_open, false);
	CHECK_VAL(io.out.durable_open_v2, false); /* no dh2q response blob */
	CHECK_VAL(io.out.persistent_open, false);
	CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("b"));
	_h = io.out.file.handle;
	h = &_h;

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

	smb2_util_unlink(tree, fname);

	talloc_free(tree);

	talloc_free(mem_ctx);

	return ret;
}
Beispiel #29
0
/*
  test netlogon operations
*/
static BOOL test_cldap_netlogon(TALLOC_CTX *mem_ctx, const char *dest)
{
	struct cldap_socket *cldap = cldap_socket_init(mem_ctx, NULL);
	NTSTATUS status;
	struct cldap_netlogon search, empty_search;
	union nbt_cldap_netlogon n1;
	struct GUID guid;
	int i;
	BOOL ret = True;

	ZERO_STRUCT(search);
	search.in.dest_address = dest;
	search.in.acct_control = -1;
	search.in.version = 6;

	empty_search = search;

	printf("Trying without any attributes\n");
	search = empty_search;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	n1 = search.out.netlogon;

	search.in.user         = "******";
	search.in.realm        = n1.logon5.dns_domain;
	search.in.host         = "__cldap_torture__";

	printf("Scanning for netlogon levels\n");
	for (i=0;i<256;i++) {
		search.in.version = i;
		printf("Trying netlogon level %d\n", i);
		status = cldap_netlogon(cldap, mem_ctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	printf("Scanning for netlogon level bits\n");
	for (i=0;i<31;i++) {
		search.in.version = (1<<i);
		printf("Trying netlogon level 0x%x\n", i);
		status = cldap_netlogon(cldap, mem_ctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	search.in.version = 6;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=NULL\n");

	search.in.user = NULL;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=Administrator\n");

	search.in.user = "******";
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a GUID\n");
	search.in.realm       = NULL;
	search.in.domain_guid = GUID_string(mem_ctx, &n1.logon5.domain_uuid);
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a incorrect GUID\n");
	guid = GUID_random();
	search.in.user        = NULL;
	search.in.domain_guid = GUID_string(mem_ctx, &guid);
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a AAC\n");
	search.in.acct_control = 0x180;
	search.in.realm = n1.logon5.dns_domain;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a bad AAC\n");
	search.in.acct_control = 0xFF00FF00;
	search.in.realm = n1.logon5.dns_domain;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a user only\n");
	search = empty_search;
	search.in.user = "******";
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with just a bad username\n");
	search.in.user = "******";
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with just a bad domain\n");
	search = empty_search;
	search.in.realm = "___no_such_domain___";
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a incorrect domain and correct guid\n");
	search.in.domain_guid = GUID_string(mem_ctx, &n1.logon5.domain_uuid);
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a incorrect domain and incorrect guid\n");
	search.in.domain_guid = GUID_string(mem_ctx, &guid);
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a incorrect GUID and correct domain\n");
	search.in.domain_guid = GUID_string(mem_ctx, &guid);
	search.in.realm = n1.logon5.dns_domain;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

done:
	return ret;	
}
struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx,
				   int fd,
				   const char *remote_name,
				   const char *remote_realm,
				   int signing_state, int flags)
{
	struct cli_state *cli = NULL;
	bool use_spnego = lp_client_use_spnego();
	bool force_dos_errors = false;
	bool force_ascii = false;
	bool use_level_II_oplocks = false;
	uint32_t smb1_capabilities = 0;
	uint32_t smb2_capabilities = 0;
	struct GUID client_guid = GUID_random();

	/* Check the effective uid - make sure we are not setuid */
	if (is_setuid_root()) {
		DEBUG(0,("libsmb based programs must *NOT* be setuid root.\n"));
		return NULL;
	}

	cli = talloc_zero(mem_ctx, struct cli_state);
	if (!cli) {
		return NULL;
	}

	cli->server_domain = talloc_strdup(cli, "");
	if (!cli->server_domain) {
		goto error;
	}
	cli->server_os = talloc_strdup(cli, "");
	if (!cli->server_os) {
		goto error;
	}
	cli->server_type = talloc_strdup(cli, "");
	if (!cli->server_type) {
		goto error;
	}

	cli->dfs_mountpoint = talloc_strdup(cli, "");
	if (!cli->dfs_mountpoint) {
		goto error;
	}
	cli->raw_status = NT_STATUS_INTERNAL_ERROR;
	cli->map_dos_errors = true; /* remove this */
	cli->timeout = CLIENT_TIMEOUT;
	cli->case_sensitive = false;

	/* Set the CLI_FORCE_DOSERR environment variable to test
	   client routines using DOS errors instead of STATUS32
	   ones.  This intended only as a temporary hack. */	
	if (getenv("CLI_FORCE_DOSERR")) {
		force_dos_errors = true;
	}
	if (flags & CLI_FULL_CONNECTION_FORCE_DOS_ERRORS) {
		force_dos_errors = true;
	}

	if (getenv("CLI_FORCE_ASCII")) {
		force_ascii = true;
	}
	if (!lp_unicode()) {
		force_ascii = true;
	}
	if (flags & CLI_FULL_CONNECTION_FORCE_ASCII) {
		force_ascii = true;
	}

	if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) {
		use_spnego = false;
	} else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
		cli->use_kerberos = true;
	}
	if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) &&
	     cli->use_kerberos) {
		cli->fallback_after_kerberos = true;
	}

	if (flags & CLI_FULL_CONNECTION_USE_CCACHE) {
		cli->use_ccache = true;
	}

	if (flags & CLI_FULL_CONNECTION_USE_NT_HASH) {
		cli->pw_nt_hash = true;
	}

	if (flags & CLI_FULL_CONNECTION_OPLOCKS) {
		cli->use_oplocks = true;
	}
	if (flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) {
		use_level_II_oplocks = true;
	}

	if (signing_state == SMB_SIGNING_DEFAULT) {
		signing_state = lp_client_signing();
	}

	smb1_capabilities = 0;
	smb1_capabilities |= CAP_LARGE_FILES;
	smb1_capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
	smb1_capabilities |= CAP_LOCK_AND_READ | CAP_NT_FIND;
	smb1_capabilities |= CAP_DFS | CAP_W2K_SMBS;
	smb1_capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX;
	smb1_capabilities |= CAP_LWIO;

	if (!force_dos_errors) {
		smb1_capabilities |= CAP_STATUS32;
	}

	if (!force_ascii) {
		smb1_capabilities |= CAP_UNICODE;
	}

	if (use_spnego) {
		smb1_capabilities |= CAP_EXTENDED_SECURITY;
	}

	if (use_level_II_oplocks) {
		smb1_capabilities |= CAP_LEVEL_II_OPLOCKS;
	}

	smb2_capabilities = SMB2_CAP_ALL;

	if (remote_realm) {
		cli->remote_realm = talloc_strdup(cli, remote_realm);
		if (cli->remote_realm == NULL) {
			goto error;
		}
	}

	cli->conn = smbXcli_conn_create(cli, fd, remote_name,
					signing_state,
					smb1_capabilities,
					&client_guid,
					smb2_capabilities);
	if (cli->conn == NULL) {
		goto error;
	}

	cli->smb1.pid = (uint16_t)getpid();
	cli->smb1.vc_num = cli->smb1.pid;
	cli->smb1.tcon = smbXcli_tcon_create(cli);
	if (cli->smb1.tcon == NULL) {
		goto error;
	}
	smb1cli_tcon_set_id(cli->smb1.tcon, UINT16_MAX);
	cli->smb1.session = smbXcli_session_create(cli, cli->conn);
	if (cli->smb1.session == NULL) {
		goto error;
	}

	cli->initialised = 1;
	return cli;

        /* Clean up after malloc() error */

 error:

	TALLOC_FREE(cli);
        return NULL;
}