Beispiel #1
0
/**
   \details Initialize the EMSABP context and open connections to
   Samba databases.

   \param lp_ctx pointer to the loadparm context
   \param tdb_ctx pointer to the EMSABP TDB context

   \return Allocated emsabp_context on success, otherwise NULL
 */
_PUBLIC_ struct emsabp_context *emsabp_init(struct loadparm_context *lp_ctx,
					    TDB_CONTEXT *tdb_ctx)
{
	TALLOC_CTX		*mem_ctx;
	struct emsabp_context	*emsabp_ctx;
	struct tevent_context	*ev;
	const char		*samdb_url;

	/* Sanity checks */
	if (!lp_ctx) return NULL;

	mem_ctx = talloc_named(NULL, 0, "emsabp_init");
	
	emsabp_ctx = talloc_zero(mem_ctx, struct emsabp_context);
	if (!emsabp_ctx) {
		talloc_free(mem_ctx);
		return NULL;
	}

	emsabp_ctx->mem_ctx = mem_ctx;

	ev = tevent_context_init(mem_ctx);
	if (!ev) {
		talloc_free(mem_ctx);
		return NULL;
	}
	tevent_loop_allow_nesting(ev);

	/* Save a pointer to the loadparm context */
	emsabp_ctx->lp_ctx = lp_ctx;


	/* Retrieve samdb url (local or external) */
	samdb_url = lpcfg_parm_string(lp_ctx, NULL, "dcerpc_mapiproxy", "samdb_url");

	/* return an opaque context pointer on samDB database */
	if (!samdb_url) {
		emsabp_ctx->samdb_ctx = samdb_connect(mem_ctx, ev, lp_ctx, system_session(lp_ctx), 0);
	} else {
		emsabp_ctx->samdb_ctx = samdb_connect_url(mem_ctx, ev, lp_ctx, system_session(lp_ctx), 0, samdb_url);
	}

	if (!emsabp_ctx->samdb_ctx) {
		talloc_free(mem_ctx);
		DEBUG(0, ("[%s:%d]: Connection to \"sam.ldb\" failed\n", __FUNCTION__, __LINE__));
		return NULL;
	}

	/* Reference the global TDB context to the current emsabp context */
	emsabp_ctx->tdb_ctx = tdb_ctx;

	/* Initialize a temporary (on-memory) TDB database to store
	 * temporary MId used within EMSABP */
	emsabp_ctx->ttdb_ctx = emsabp_tdb_init_tmp(emsabp_ctx->mem_ctx);
	if (!emsabp_ctx->ttdb_ctx) {
		smb_panic("unable to create on-memory TDB database");
	}

	return emsabp_ctx;
}
Beispiel #2
0
int mit_samba_context_init(struct mit_samba_context **_ctx)
{
	NTSTATUS status;
	struct mit_samba_context *ctx;
	const char *s4_conf_file;
	int ret;
	struct samba_kdc_base_context base_ctx;

	ctx = talloc_zero(NULL, struct mit_samba_context);
	if (!ctx) {
		ret = ENOMEM;
		goto done;
	}

	base_ctx.ev_ctx = tevent_context_init(ctx);
	if (!base_ctx.ev_ctx) {
		ret = ENOMEM;
		goto done;
	}
	tevent_loop_allow_nesting(base_ctx.ev_ctx);
	base_ctx.lp_ctx = loadparm_init_global(false);
	if (!base_ctx.lp_ctx) {
		ret = ENOMEM;
		goto done;
	}

	setup_logging("mitkdc", DEBUG_STDOUT);

	/* init s4 configuration */
	s4_conf_file = lpcfg_configfile(base_ctx.lp_ctx);
	if (s4_conf_file) {
		lpcfg_load(base_ctx.lp_ctx, s4_conf_file);
	} else {
		lpcfg_load_default(base_ctx.lp_ctx);
	}

	status = samba_kdc_setup_db_ctx(ctx, &base_ctx, &ctx->db_ctx);
	if (!NT_STATUS_IS_OK(status)) {
		ret = EINVAL;
		goto done;
	}

	/* init heimdal's krb_context and log facilities */
	ret = smb_krb5_init_context_basic(ctx,
					  ctx->db_ctx->lp_ctx,
					  &ctx->context);
	if (ret) {
		goto done;
	}

	ret = 0;

done:
	if (ret) {
		mit_samba_context_free(ctx);
	} else {
		*_ctx = ctx;
	}
	return ret;
}
Beispiel #3
0
static NTSTATUS provider_rpc_connection(TALLOC_CTX *parent_ctx,
                                        struct dcerpc_pipe **p,
                                        const char *binding,
                                        struct cli_credentials *credentials,
                                        const struct ndr_interface_table *table,
                                        struct loadparm_context *lp_ctx)
{
    NTSTATUS		status;
    struct tevent_context	*ev;

    if (!binding) {
        OC_DEBUG(3, "You must specify a ncacn binding string");
        return NT_STATUS_INVALID_PARAMETER;
    }

    ev = tevent_context_init(parent_ctx);
    tevent_loop_allow_nesting(ev);

    status = dcerpc_pipe_connect(parent_ctx,
                                 p, binding, table,
                                 credentials, ev, lp_ctx);

    if (!NT_STATUS_IS_OK(status)) {
        OC_DEBUG(3, "Failed to connect to remote server: %s %s",
                 binding, nt_errstr(status));
    }

    /* dcerpc_pipe_connect set errno, we have to unset it */
    errno = 0;
    return status;
}
Beispiel #4
0
/**
   \details Initialize ldb_context to samdb, creates one for all emsmdbp
   contexts

   \param lp_ctx pointer to the loadparm context
 */
static struct ldb_context *samdb_init(struct loadparm_context *lp_ctx)
{
	TALLOC_CTX		*mem_ctx;
	struct tevent_context	*ev;
	const char		*samdb_url;

	if (samdb_ctx) return samdb_ctx;

	mem_ctx = talloc_autofree_context();
	ev = tevent_context_init(mem_ctx);
	if (!ev) {
		OC_PANIC(false, ("Fail to initialize tevent_context\n"));
		return NULL;
	}
	tevent_loop_allow_nesting(ev);

	/* Retrieve samdb url (local or external) */
	samdb_url = lpcfg_parm_string(lp_ctx, NULL, "dcerpc_mapiproxy", "samdb_url");

	if (!samdb_url) {
		samdb_ctx = samdb_connect(mem_ctx, ev, lp_ctx, system_session(lp_ctx), 0);
	} else {
		samdb_ctx = samdb_connect_url(mem_ctx, ev, lp_ctx, system_session(lp_ctx),
					      LDB_FLG_RECONNECT, samdb_url);
	}

	return samdb_ctx;
}
Beispiel #5
0
/*
  create a event_context structure. This must be the first events
  call, and all subsequent calls pass this event_context as the first
  element. Event handlers also receive this as their first argument.

  This samba4 specific call sets the samba4 debug handler.
*/
struct tevent_context *s4_event_context_init(TALLOC_CTX *mem_ctx)
{
	struct tevent_context *ev;

	ev = tevent_context_init_byname(mem_ctx, NULL);
	if (ev) {
		samba_tevent_set_debug(ev, "s4_tevent");
		tevent_loop_allow_nesting(ev);
	}
	return ev;
}
Beispiel #6
0
_PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security,
				   TALLOC_CTX *out_mem_ctx,
				   struct tevent_context *ev,
				   const DATA_BLOB in, DATA_BLOB *out)
{
	NTSTATUS status;
	const struct gensec_security_ops *ops = gensec_security->ops;
	TALLOC_CTX *frame = NULL;
	struct tevent_req *subreq = NULL;
	bool ok;

	if (ops->update_send == NULL) {

		if (ev == NULL) {
			frame = talloc_stackframe();

			ev = samba_tevent_context_init(frame);
			if (ev == NULL) {
				status = NT_STATUS_NO_MEMORY;
				goto fail;
			}

			/*
			 * TODO: remove this hack once the backends
			 * are fixed.
			 */
			tevent_loop_allow_nesting(ev);
		}

		status = ops->update(gensec_security, out_mem_ctx,
				     ev, in, out);
		TALLOC_FREE(frame);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		/*
		 * Because callers using the
		 * gensec_start_mech_by_auth_type() never call
		 * gensec_want_feature(), it isn't sensible for them
		 * to have to call gensec_have_feature() manually, and
		 * these are not points of negotiation, but are
		 * asserted by the client
		 */
		status = gensec_verify_dcerpc_auth_level(gensec_security);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		return NT_STATUS_OK;
	}

	frame = talloc_stackframe();

	if (ev == NULL) {
		ev = samba_tevent_context_init(frame);
		if (ev == NULL) {
			status = NT_STATUS_NO_MEMORY;
			goto fail;
		}

		/*
		 * TODO: remove this hack once the backends
		 * are fixed.
		 */
		tevent_loop_allow_nesting(ev);
	}

	subreq = ops->update_send(frame, ev, gensec_security, in);
	if (subreq == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto fail;
	}
	ok = tevent_req_poll_ntstatus(subreq, ev, &status);
	if (!ok) {
		goto fail;
	}
	status = ops->update_recv(subreq, out_mem_ctx, out);
 fail:
	TALLOC_FREE(frame);
	return status;
}
Beispiel #7
0
static PyObject *py_tevent_context_set_allow_nesting(TeventContext_Object *self)
{
	tevent_loop_allow_nesting(self->ev);
	Py_RETURN_NONE;
}
Beispiel #8
0
_PUBLIC_ NTSTATUS gensec_update_ev(struct gensec_security *gensec_security,
				   TALLOC_CTX *out_mem_ctx,
				   struct tevent_context *ev,
				   const DATA_BLOB in, DATA_BLOB *out)
{
	NTSTATUS status;
	const struct gensec_security_ops *ops = gensec_security->ops;
	TALLOC_CTX *frame = NULL;
	struct tevent_req *subreq = NULL;
	bool ok;

	if (ops->update_send == NULL) {

		if (ev == NULL) {
			frame = talloc_stackframe();

			ev = samba_tevent_context_init(frame);
			if (ev == NULL) {
				status = NT_STATUS_NO_MEMORY;
				goto fail;
			}

			/*
			 * TODO: remove this hack once the backends
			 * are fixed.
			 */
			tevent_loop_allow_nesting(ev);
		}

		status = ops->update(gensec_security, out_mem_ctx,
				     ev, in, out);
		TALLOC_FREE(frame);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		/*
		 * Because callers using the
		 * gensec_start_mech_by_auth_type() never call
		 * gensec_want_feature(), it isn't sensible for them
		 * to have to call gensec_have_feature() manually, and
		 * these are not points of negotiation, but are
		 * asserted by the client
		 */
		switch (gensec_security->dcerpc_auth_level) {
		case DCERPC_AUTH_LEVEL_INTEGRITY:
			if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
				DEBUG(0,("Did not manage to negotiate mandetory feature "
					 "SIGN for dcerpc auth_level %u\n",
					 gensec_security->dcerpc_auth_level));
				return NT_STATUS_ACCESS_DENIED;
			}
			break;
		case DCERPC_AUTH_LEVEL_PRIVACY:
			if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
				DEBUG(0,("Did not manage to negotiate mandetory feature "
					 "SIGN for dcerpc auth_level %u\n",
					 gensec_security->dcerpc_auth_level));
				return NT_STATUS_ACCESS_DENIED;
			}
			if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
				DEBUG(0,("Did not manage to negotiate mandetory feature "
					 "SEAL for dcerpc auth_level %u\n",
					 gensec_security->dcerpc_auth_level));
				return NT_STATUS_ACCESS_DENIED;
			}
			break;
		default:
			break;
		}

		return NT_STATUS_OK;
	}

	frame = talloc_stackframe();

	if (ev == NULL) {
		ev = samba_tevent_context_init(frame);
		if (ev == NULL) {
			status = NT_STATUS_NO_MEMORY;
			goto fail;
		}

		/*
		 * TODO: remove this hack once the backends
		 * are fixed.
		 */
		tevent_loop_allow_nesting(ev);
	}

	subreq = ops->update_send(frame, ev, gensec_security, in);
	if (subreq == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto fail;
	}
	ok = tevent_req_poll_ntstatus(subreq, ev, &status);
	if (!ok) {
		goto fail;
	}
	status = ops->update_recv(subreq, out_mem_ctx, out);
 fail:
	TALLOC_FREE(frame);
	return status;
}
Beispiel #9
0
/*
  main program
*/
int main(int argc, const char *argv[])
{
	struct ctdb_context *ctdb;
	int interactive = 0;

	struct poptOption popt_options[] = {
		POPT_AUTOHELP
		POPT_CTDB_CMDLINE
		{ "interactive", 'i', POPT_ARG_NONE, &interactive, 0, "don't fork", NULL },
		{ "public-addresses", 0, POPT_ARG_STRING, &options.public_address_list, 0, "public address list file", "filename" },
		{ "public-interface", 0, POPT_ARG_STRING, &options.public_interface, 0, "public interface", "interface"},
		{ "event-script-dir", 0, POPT_ARG_STRING, &options.event_script_dir, 0, "event script directory", "dirname" },
		{ "logging", 0, POPT_ARG_STRING, &options.logging, 0, "logging method to be used", NULL },
		{ "nlist", 0, POPT_ARG_STRING, &options.nlist, 0, "node list file", "filename" },
		{ "notification-script", 0, POPT_ARG_STRING, &options.notification_script, 0, "notification script", "filename" },
		{ "listen", 0, POPT_ARG_STRING, &options.myaddress, 0, "address to listen on", "address" },
		{ "transport", 0, POPT_ARG_STRING, &options.transport, 0, "protocol transport", NULL },
		{ "dbdir", 0, POPT_ARG_STRING, &options.db_dir, 0, "directory for the tdb files", NULL },
		{ "dbdir-persistent", 0, POPT_ARG_STRING, &options.db_dir_persistent, 0, "directory for persistent tdb files", NULL },
		{ "dbdir-state", 0, POPT_ARG_STRING, &options.db_dir_state, 0, "directory for internal state tdb files", NULL },
		{ "reclock", 0, POPT_ARG_STRING, &options.recovery_lock, 0, "recovery lock", "lock" },
		{ "pidfile", 0, POPT_ARG_STRING, &ctdbd_pidfile, 0, "location of PID file", "filename" },
		{ "valgrinding", 0, POPT_ARG_NONE, &options.valgrinding, 0, "disable setscheduler SCHED_FIFO call, use mmap for tdbs", NULL },
		{ "nosetsched", 0, POPT_ARG_NONE, &options.nosetsched, 0, "disable setscheduler SCHED_FIFO call, use mmap for tdbs", NULL },
		{ "start-as-disabled", 0, POPT_ARG_NONE, &options.start_as_disabled, 0, "Node starts in disabled state", NULL },
		{ "start-as-stopped", 0, POPT_ARG_NONE, &options.start_as_stopped, 0, "Node starts in stopped state", NULL },
		{ "no-lmaster", 0, POPT_ARG_NONE, &options.no_lmaster, 0, "disable lmaster role on this node", NULL },
		{ "no-recmaster", 0, POPT_ARG_NONE, &options.no_recmaster, 0, "disable recmaster role on this node", NULL },
		{ "script-log-level", 0, POPT_ARG_INT, &options.script_log_level, 0, "log level of event script output", NULL },
		{ "nopublicipcheck", 0, POPT_ARG_NONE, &options.no_publicipcheck, 0, "don't check we have/don't have the correct public ip addresses", NULL },
		{ "max-persistent-check-errors", 0, POPT_ARG_INT,
		  &options.max_persistent_check_errors, 0,
		  "max allowed persistent check errors (default 0)", NULL },
		{ "sloppy-start", 0, POPT_ARG_NONE, &fast_start, 0, "Do not perform full recovery on start", NULL },
		POPT_TABLEEND
	};
	int opt, ret;
	const char **extra_argv;
	int extra_argc = 0;
	poptContext pc;
	struct tevent_context *ev;

	pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		default:
			fprintf(stderr, "Invalid option %s: %s\n", 
				poptBadOption(pc, 0), poptStrerror(opt));
			exit(1);
		}
	}

	/* setup the remaining options for the main program to use */
	extra_argv = poptGetArgs(pc);
	if (extra_argv) {
		extra_argv++;
		while (extra_argv[extra_argc]) extra_argc++;
	}

	talloc_enable_null_tracking();

	fault_setup();

	ev = tevent_context_init(NULL);
	if (ev == NULL) {
		DEBUG(DEBUG_ALERT,("tevent_context_init() failed\n"));
		exit(1);
	}
	tevent_loop_allow_nesting(ev);

	ctdb = ctdb_cmdline_init(ev);

	ctdb->start_as_disabled = options.start_as_disabled;
	ctdb->start_as_stopped  = options.start_as_stopped;

	script_log_level = options.script_log_level;

	if (!ctdb_logging_init(ctdb, options.logging)) {
		exit(1);
	}

	DEBUG(DEBUG_NOTICE,("CTDB starting on node\n"));

	gettimeofday(&ctdb->ctdbd_start_time, NULL);
	gettimeofday(&ctdb->last_recovery_started, NULL);
	gettimeofday(&ctdb->last_recovery_finished, NULL);
	ctdb->recovery_mode    = CTDB_RECOVERY_NORMAL;
	ctdb->recovery_master  = (uint32_t)-1;
	ctdb->upcalls          = &ctdb_upcalls;

	if (options.recovery_lock == NULL) {
		DEBUG(DEBUG_WARNING, ("Recovery lock not set\n"));
	}
	ctdb->recovery_lock = options.recovery_lock;

	TALLOC_FREE(ctdb->idr);
	ret = reqid_init(ctdb, 0, &ctdb->idr);;
	if (ret != 0) {
		DEBUG(DEBUG_ALERT, ("reqid_init failed (%s)\n", strerror(ret)));
		exit(1);
	}

	ctdb_tunables_set_defaults(ctdb);

	ret = ctdb_set_transport(ctdb, options.transport);
	if (ret == -1) {
		DEBUG(DEBUG_ALERT,("ctdb_set_transport failed - %s\n", ctdb_errstr(ctdb)));
		exit(1);
	}

	/* tell ctdb what address to listen on */
	if (options.myaddress) {
		ret = ctdb_set_address(ctdb, options.myaddress);
		if (ret == -1) {
			DEBUG(DEBUG_ALERT,("ctdb_set_address failed - %s\n", ctdb_errstr(ctdb)));
			exit(1);
		}
	}

	/* set ctdbd capabilities */
	ctdb->capabilities = CTDB_CAP_DEFAULT;
	if (options.no_lmaster != 0) {
		ctdb->capabilities &= ~CTDB_CAP_LMASTER;
	}
	if (options.no_recmaster != 0) {
		ctdb->capabilities &= ~CTDB_CAP_RECMASTER;
	}

	/* Initialise this node's PNN to the unknown value.  This will
	 * be set to the correct value by either ctdb_add_node() as
	 * part of loading the nodes file or by
	 * ctdb_tcp_listen_automatic() when the transport is
	 * initialised.  At some point we should de-optimise this and
	 * pull it out into ctdb_start_daemon() so it is done clearly
	 * and only in one place.
	 */
	ctdb->pnn = -1;

	/* Default value for CTDB_BASE - don't override */
	setenv("CTDB_BASE", CTDB_ETCDIR, 0);

	/* tell ctdb what nodes are available */
	if (options.nlist != NULL) {
		ctdb->nodes_file = options.nlist;
	} else {
		ctdb->nodes_file =
			talloc_asprintf(ctdb, "%s/nodes", getenv("CTDB_BASE"));
		if (ctdb->nodes_file == NULL) {
			DEBUG(DEBUG_ALERT,(__location__ " Out of memory\n"));
			exit(1);
		}
	}
	ctdb_load_nodes_file(ctdb);

	ctdb->db_directory = options.db_dir;
	mkdir_p_or_die(ctdb->db_directory, 0700);

	ctdb->db_directory_persistent = options.db_dir_persistent;
	mkdir_p_or_die(ctdb->db_directory_persistent, 0700);

	ctdb->db_directory_state = options.db_dir_state;
	mkdir_p_or_die(ctdb->db_directory_state, 0700);

	if (options.public_interface) {
		ctdb->default_public_interface = talloc_strdup(ctdb, options.public_interface);
		CTDB_NO_MEMORY(ctdb, ctdb->default_public_interface);
	}

	if (options.event_script_dir != NULL) {
		ctdb->event_script_dir = options.event_script_dir;
	} else {
		ctdb->event_script_dir = talloc_asprintf(ctdb, "%s/events.d",
							 getenv("CTDB_BASE"));
		if (ctdb->event_script_dir == NULL) {
			DEBUG(DEBUG_ALERT,(__location__ " Out of memory\n"));
			exit(1);
		}
	}

	if (options.notification_script != NULL) {
		ret = ctdb_set_notification_script(ctdb, options.notification_script);
		if (ret == -1) {
			DEBUG(DEBUG_ALERT,("Unable to setup notification script\n"));
			exit(1);
		}
	}

	ctdb->valgrinding = (options.valgrinding == 1);
	ctdb->do_setsched = (options.nosetsched != 1);
	if (ctdb->valgrinding) {
		ctdb->do_setsched = false;
	}

	ctdb->public_addresses_file = options.public_address_list;
	ctdb->do_checkpublicip = (options.no_publicipcheck == 0);

	if (options.max_persistent_check_errors < 0) {
		ctdb->max_persistent_check_errors = 0xFFFFFFFFFFFFFFFFLL;
	} else {
		ctdb->max_persistent_check_errors = (uint64_t)options.max_persistent_check_errors;
	}

	/* start the protocol running (as a child) */
	return ctdb_start_daemon(ctdb, interactive?false:true);
}
Beispiel #10
0
/**
   \details Initialize the EMSMDBP context and open connections to
   Samba databases.

   \param lp_ctx pointer to the loadparm_context
   \param username account name for current session
   \param ldb_ctx pointer to the openchange dispatcher ldb database
   
   \return Allocated emsmdbp_context pointer on success, otherwise
   NULL
 */
_PUBLIC_ struct emsmdbp_context *emsmdbp_init(struct loadparm_context *lp_ctx,
					      const char *username,
					      void *ldb_ctx)
{
	TALLOC_CTX		*mem_ctx;
	struct emsmdbp_context	*emsmdbp_ctx;
	struct tevent_context	*ev;
	enum mapistore_error	ret;

	/* Sanity Checks */
	if (!lp_ctx) return NULL;

	mem_ctx  = talloc_named(NULL, 0, "emsmdbp_init");

	emsmdbp_ctx = talloc_zero(mem_ctx, struct emsmdbp_context);
	if (!emsmdbp_ctx) {
		talloc_free(mem_ctx);
		return NULL;
	}

	emsmdbp_ctx->mem_ctx = mem_ctx;

	ev = tevent_context_init(mem_ctx);
	if (!ev) {
		talloc_free(mem_ctx);
		return NULL;
	}
	tevent_loop_allow_nesting(ev); 

	/* Save a pointer to the loadparm context */
	emsmdbp_ctx->lp_ctx = lp_ctx;

	/* return an opaque context pointer on samDB database */
	emsmdbp_ctx->samdb_ctx = samdb_connect(mem_ctx, ev, lp_ctx, system_session(lp_ctx), 0);
	if (!emsmdbp_ctx->samdb_ctx) {
		talloc_free(mem_ctx);
		DEBUG(0, ("[%s:%d]: Connection to \"sam.ldb\" failed\n", __FUNCTION__, __LINE__));
		return NULL;
	}

	/* Reference global OpenChange dispatcher database pointer within current context */
	emsmdbp_ctx->oc_ctx = ldb_ctx;

	/* Initialize the mapistore context */		
	emsmdbp_ctx->mstore_ctx = mapistore_init(mem_ctx, lp_ctx, NULL);
	if (!emsmdbp_ctx->mstore_ctx) {
		DEBUG(0, ("[%s:%d]: MAPISTORE initialization failed\n", __FUNCTION__, __LINE__));

		talloc_free(mem_ctx);
		return NULL;
	}

	ret = mapistore_set_connection_info(emsmdbp_ctx->mstore_ctx, emsmdbp_ctx->samdb_ctx, emsmdbp_ctx->oc_ctx, username);
	if (ret != MAPISTORE_SUCCESS) {
		DEBUG(0, ("[%s:%d]: MAPISTORE connection info initialization failed\n", __FUNCTION__, __LINE__));
		talloc_free(mem_ctx);
		return NULL;
	}
	talloc_set_destructor((void *)emsmdbp_ctx->mstore_ctx, (int (*)(void *))emsmdbp_mapi_store_destructor);

	/* Initialize MAPI handles context */
	emsmdbp_ctx->handles_ctx = mapi_handles_init(mem_ctx);
	if (!emsmdbp_ctx->handles_ctx) {
		DEBUG(0, ("[%s:%d]: MAPI handles context initialization failed\n", __FUNCTION__, __LINE__));
		talloc_free(mem_ctx);
		return NULL;
	}
	talloc_set_destructor((void *)emsmdbp_ctx->handles_ctx, (int (*)(void *))emsmdbp_mapi_handles_destructor);

	return emsmdbp_ctx;
}