Index: config.mk.in
===================================================================
--- config.mk.in	(revision 1425)
+++ config.mk.in	(working copy)
@@ -29,7 +29,7 @@
 sambaprefix=@sambaprefix@
 
 DSOOPT=-shared -fPIC
-CFLAGS=@CFLAGS@ -I. -O3 -Wall -Wmissing-prototypes -Wstrict-prototypes -g3 -Wp,-D_FORTIFY_SOURCE=2	\
+CFLAGS=@CFLAGS@ -I. -Wall -Wmissing-prototypes -Wstrict-prototypes -g3 -Wp,-D_FORTIFY_SOURCE=2	\
 	-fstrict-aliasing -Wstrict-aliasing=3	   		       	   				\
 	   -DDEFAULT_LDIF=\"$(datadir)/setup/profiles\"							\
 	   -DMAPISTORE_BACKEND_INSTALLDIR=\"$(libdir)/mapistore_backends\"				\
Index: libmapi/conf/mapi-codes
===================================================================
--- libmapi/conf/mapi-codes	(revision 1425)
+++ libmapi/conf/mapi-codes	(working copy)
@@ -55,7 +55,7 @@
 0x80040200  MAPI_E_END_OF_SESSION
 0x80040201  MAPI_E_UNKNOWN_ENTRYID
 0x80040202  MAPI_E_MISSING_REQUIRED_COLUMN
-0x80040203  MAPI_W_NO_SERVICE
+0x00040203  MAPI_W_NO_SERVICE
 0x80040301  MAPI_E_BAD_VALUE
 0x80040302  MAPI_E_INVALID_TYPE
 0x80040303  MAPI_E_TYPE_NO_SUPPORT
@@ -63,18 +63,18 @@
 0x80040305  MAPI_E_TOO_BIG
 0x80040306  MAPI_E_DECLINE_COPY
 0x80040307  MAPI_E_UNEXPECTED_ID
-0x80040380  MAPI_W_ERRORS_RETURNED
+0x00040380  MAPI_W_ERRORS_RETURNED
 0x80040400  MAPI_E_UNABLE_TO_COMPLETE
 0x80040401  MAPI_E_TIMEOUT
 0x80040402  MAPI_E_TABLE_EMPTY
 0x80040403  MAPI_E_TABLE_TOO_BIG
 0x80040405  MAPI_E_INVALID_BOOKMARK
-0x80040481  MAPI_W_POSITION_CHANGED
-0x80040482  MAPI_W_APPROX_COUNT
+0x00040481  MAPI_W_POSITION_CHANGED
+0x00040482  MAPI_W_APPROX_COUNT
 0x80040500  MAPI_E_WAIT
 0x80040501  MAPI_E_CANCEL
 0x80040502  MAPI_E_NOT_ME
-0x80040580  MAPI_W_CANCEL_MESSAGE
+0x00040580  MAPI_W_CANCEL_MESSAGE
 0x80040600  MAPI_E_CORRUPT_STORE
 0x80040601  MAPI_E_NOT_IN_QUEUE
 0x80040602  MAPI_E_NO_SUPPRESS
@@ -87,7 +87,7 @@
 0x8004060A  MAPI_E_HAS_MESAGES
 0x8004060B  MAPI_E_FOLDER_CYCLE
 0x8004060D  MAPI_E_LOCKID_LIMIT
-0x80040680  MAPI_W_PARTIAL_COMPLETION
+0x00040680  MAPI_W_PARTIAL_COMPLETION
 0x80040700  MAPI_E_AMBIGUOUS_RECIP
 0x80040800  SYNC_E_OBJECT_DELETED
 0x80040801  SYNC_E_IGNORE
@@ -95,8 +95,8 @@
 0x80040803  SYNC_E_NO_PARENT
 0x80040804  SYNC_E_CYCLE_DETECTED
 0x80040805  SYNC_E_UNSYNCHRONIZED
-0x80040820  SYNC_W_PROGRESS
-0x80040821  SYNC_W_CLIENT_CHANGE_NEWER
+0x00040820  SYNC_W_PROGRESS
+0x00040821  SYNC_W_CLIENT_CHANGE_NEWER
 0x80040900  MAPI_E_NAMED_PROP_QUOTA_EXCEEDED
 0x80070005  MAPI_E_NO_ACCESS
 0x8007000E  MAPI_E_NOT_ENOUGH_MEMORY
Index: mapiproxy/servers/default/nspi/emsabp.c
===================================================================
--- mapiproxy/servers/default/nspi/emsabp.c	(revision 1425)
+++ mapiproxy/servers/default/nspi/emsabp.c	(working copy)
@@ -28,6 +28,7 @@
 
 #include "mapiproxy/dcesrv_mapiproxy.h"
 #include "dcesrv_exchange_nsp.h"
+#include <ldb_wrap.h>
 
 /**
    \details Initialize the EMSABP context and open connections to
@@ -44,9 +45,6 @@
 	TALLOC_CTX		*mem_ctx;
 	struct emsabp_context	*emsabp_ctx;
 	struct tevent_context	*ev;
-	char			*configuration = NULL;
-	char			*users = NULL;
-	int			ret;
 
 	/* Sanity checks */
 	if (!lp_ctx) return NULL;
@@ -71,34 +69,20 @@
 	emsabp_ctx->lp_ctx = lp_ctx;
 
 	/* Return an opaque context pointer on the configuration database */
-	configuration = private_path(mem_ctx, lp_ctx, "configuration.ldb");
-	emsabp_ctx->conf_ctx = ldb_init(mem_ctx, ev);
+	emsabp_ctx->conf_ctx = ldb_wrap_connect(mem_ctx, ev, lp_ctx, "configuration.ldb", 
+						NULL, NULL, 
+						LDB_FLG_RDONLY, NULL);
 	if (!emsabp_ctx->conf_ctx) {
-		talloc_free(configuration);
-		talloc_free(mem_ctx);
-		return NULL;
-	}
-
-	ret = ldb_connect(emsabp_ctx->conf_ctx, configuration, LDB_FLG_RDONLY, NULL);
-	talloc_free(configuration);
-	if (ret != LDB_SUCCESS) {
 		DEBUG(0, ("[%s:%d]: Connection to \"configuration.ldb\" failed\n", __FUNCTION__, __LINE__));
 		talloc_free(mem_ctx);
 		return NULL;
 	}
 
 	/* Return an opaque context pointer to the users database */
-	users = private_path(mem_ctx, lp_ctx, "users.ldb");
-	emsabp_ctx->users_ctx = ldb_init(mem_ctx, ev);
+	emsabp_ctx->users_ctx = ldb_wrap_connect(mem_ctx, ev, lp_ctx, "users.ldb", 
+						 NULL, NULL, 
+						 LDB_FLG_RDONLY, NULL);
 	if (!emsabp_ctx->users_ctx) {
-		talloc_free(users);
-		talloc_free(mem_ctx);
-		return NULL;
-	}
-
-	ret = ldb_connect(emsabp_ctx->users_ctx, users, LDB_FLG_RDONLY, NULL);
-	talloc_free(users);
-	if (ret != LDB_SUCCESS) {
 		DEBUG(0, ("[%s:%d]: Connection to \"users.ldb\" failed\n", __FUNCTION__, __LINE__));
 		talloc_free(mem_ctx);
 		return NULL;
@@ -213,54 +197,50 @@
 	struct loadparm_context	*lp_ctx;
 	struct GUID		*guid = (struct GUID *) NULL;
 	const char		*netbiosname = NULL;
-	const char		*guid_str = NULL;
-	enum ldb_scope		scope = LDB_SCOPE_SUBTREE;
+	const struct ldb_val	*ldb_value = NULL;
 	struct ldb_result	*res = NULL;
-	char			*dn = NULL;
 	struct ldb_dn		*ldb_dn = NULL;
 	const char * const	recipient_attrs[] = { "*", NULL };
-	const char		*firstorgdn = NULL;
+	const char		*server_entry = NULL;
 
 	lp_ctx = emsabp_ctx->lp_ctx;
 
 	netbiosname = lp_netbios_name(lp_ctx);
 	if (!netbiosname) return NULL;
 
-	/* Step 1. Find the Exchange Organization */
+	/* Step 1. Find server record in CN=Servers,CN=Default-First-Site-Name,CN=Sites,<CONFIG_DN> sub-tree */
 	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
 			 ldb_get_default_basedn(emsabp_ctx->conf_ctx),
-			 scope, recipient_attrs, "(objectClass=msExchOrganizationContainer)");
+			 LDB_SCOPE_SUBTREE, recipient_attrs, 
+			 "(&(objectClass=server)(cn=%s))", netbiosname);
 
 	if (ret != LDB_SUCCESS || !res->count) {
 		return NULL;
 	}
 
-	firstorgdn = ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL);
-	if (!firstorgdn) {
+	server_entry = ldb_msg_find_attr_as_string(res->msgs[0], "distinguishedName", NULL);
+	if (!server_entry) {
 		return NULL;
 	}
 
-	/* Step 2. Find the OpenChange Server object */
-	dn = talloc_asprintf(emsabp_ctx->mem_ctx, "CN=Servers,CN=First Administrative Group,CN=Administrative Groups,%s",
-			     firstorgdn);
-	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->conf_ctx, dn);
-	talloc_free(dn);
+	/* Step 2. Fetch "NTDS Settings" info for the server */
+	ldb_dn = ldb_dn_new(emsabp_ctx->mem_ctx, emsabp_ctx->conf_ctx, server_entry);
 	if (!ldb_dn_validate(ldb_dn)) {
 		return NULL;
 	}
 
 	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, 
-			 scope, recipient_attrs, "(cn=%s)", netbiosname);
+			 LDB_SCOPE_ONELEVEL, recipient_attrs, "(cn=NTDS Settings)");
 	if (ret != LDB_SUCCESS || !res->count) {
 		return NULL;
 	}
 
 	/* Step 3. Retrieve the objectGUID GUID */
-	guid_str = ldb_msg_find_attr_as_string(res->msgs[0], "objectGUID", NULL);
-	if (!guid_str) return NULL;
+	ldb_value = ldb_msg_find_ldb_val(res->msgs[0], "objectGUID");
+	if (!ldb_value)	return NULL;
 
 	guid = talloc_zero(emsabp_ctx->mem_ctx, struct GUID);
-	GUID_from_string(guid_str, guid);
+	GUID_from_data_blob(ldb_value, guid);
 	
 	return guid;
 }
@@ -374,8 +354,9 @@
 						     uint32_t DisplayType, struct ldb_message *msg, 
 						     struct PermanentEntryID *permEntryID)
 {
-	struct GUID	*guid = (struct GUID *) NULL;
-	const char	*guid_str;
+	const char		*dn_str;
+	struct GUID		*guid = (struct GUID *) NULL;
+	const struct ldb_val	*ldb_value = NULL;
 
 	/* Sanity checks */
 	OPENCHANGE_RETVAL_IF(!permEntryID, MAPI_E_NOT_ENOUGH_RESOURCES, NULL);
@@ -391,12 +372,13 @@
 
 	if (!msg) {
 		permEntryID->dn = talloc_strdup(emsabp_ctx->mem_ctx, "/");
-	} else {
-		guid_str = ldb_msg_find_attr_as_string(msg, "objectGUID", NULL);
-		OPENCHANGE_RETVAL_IF(!guid_str, MAPI_E_CORRUPT_STORE, NULL);
+	} else if (DisplayType == DT_CONTAINER) {
+		ldb_value = ldb_msg_find_ldb_val(msg, "objectGUID");
+		OPENCHANGE_RETVAL_IF(!ldb_value, MAPI_E_CORRUPT_STORE, NULL);
+
 		guid = talloc_zero(emsabp_ctx->mem_ctx, struct GUID);
-		GUID_from_string(guid_str, guid);
-		permEntryID->dn = talloc_asprintf(emsabp_ctx->mem_ctx, EMSABP_DN, 
+		GUID_from_data_blob(ldb_value, guid);
+		permEntryID->dn = talloc_asprintf(emsabp_ctx->mem_ctx, EMSABP_DN,
 						  guid->time_low, guid->time_mid,
 						  guid->time_hi_and_version,
 						  guid->clock_seq[0],
@@ -405,6 +387,10 @@
 						  guid->node[2], guid->node[3],
 						  guid->node[4], guid->node[5]);
 		talloc_free(guid);
+	} else {
+		dn_str = ldb_msg_find_attr_as_string(msg, "legacyExchangeDN", NULL);
+		OPENCHANGE_RETVAL_IF(!dn_str, MAPI_E_CORRUPT_STORE, NULL);
+		permEntryID->dn = talloc_strdup(emsabp_ctx->mem_ctx, dn_str);
 	}
 
 	return MAPI_E_SUCCESS;
@@ -471,25 +457,28 @@
    \return Valid generic pointer on success, otherwise NULL
  */
 _PUBLIC_ void *emsabp_query(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx,
-			    struct ldb_message *msg, uint32_t ulPropTag, uint32_t MId)
+			    struct ldb_message *msg, uint32_t ulPropTag, uint32_t MId, uint32_t dwFlags)
 {
 	enum MAPISTATUS			retval;
-	void				*data = (void *) NULL;
-	const char			*attribute;
-	const char			*ref_attribute;
-	const char			*ldb_string = NULL;
+	void					*data = (void *) NULL;
+	const char				*attribute;
+	const char				*ref_attribute;
+	const char				*ldb_string = NULL;
+	char 					*temp_str;
 	struct Binary_r			*bin;
-	struct StringArray_r		*mvszA;
+	struct StringArray_r	*mvszA;
 	struct EphemeralEntryID		ephEntryID;
+	struct PermanentEntryID		permEntryID;
 	struct ldb_message		*msg2 = NULL;
 	struct ldb_message_element	*ldb_element;
-	int				ret;
+	int					ret;
 	const char			*dn = NULL;
 	uint32_t			i;
 
 	/* Step 1. Fill attributes not in AD but created using EMSABP databases */
 	switch (ulPropTag) {
 	case PR_ADDRTYPE:
+	case PR_ADDRTYPE_UNICODE:
 		data = (void *) talloc_strdup(mem_ctx, EMSABP_ADDRTYPE);
 		return data;
 	case PR_OBJECT_TYPE:
@@ -502,9 +491,28 @@
 		return data;
 	case PR_ENTRYID:
 		bin = talloc(mem_ctx, struct Binary_r);
-		retval = emsabp_set_EphemeralEntryID(emsabp_ctx, DT_MAILUSER, MId, &ephEntryID);
-		retval = emsabp_EphemeralEntryID_to_Binary_r(mem_ctx, &ephEntryID, bin);
+		if (dwFlags & fEphID) {
+			retval = emsabp_set_EphemeralEntryID(emsabp_ctx, DT_MAILUSER, MId, &ephEntryID);
+			retval = emsabp_EphemeralEntryID_to_Binary_r(mem_ctx, &ephEntryID, bin);
+		} else {
+			retval = emsabp_set_PermanentEntryID(emsabp_ctx, DT_MAILUSER, msg, &permEntryID);
+			retval = emsabp_PermanentEntryID_to_Binary_r(mem_ctx, &permEntryID, bin);
+		}
 		return bin;
+	case PR_SEARCH_KEY:
+		// get email address attr, i.e. legacyExchangeDN
+		ldb_string = ldb_msg_find_attr_as_string(msg, emsabp_property_get_attribute(PR_EMAIL_ADDRESS), NULL);
+		if (!ldb_string)
+			return NULL;
+		temp_str = talloc_strdup_upper(mem_ctx, ldb_string);
+		if (!temp_str)
+			return NULL;
+		// make binary for PR_SEARCH_KEY
+		bin = talloc(mem_ctx, struct Binary_r);
+		bin->lpb = (uint8_t*)talloc_asprintf(mem_ctx, "%s:%s", EMSABP_ADDRTYPE, temp_str);
+		bin->cb = strlen((const char*)bin->lpb) + 1;
+		talloc_free(temp_str);
+		return bin;
 	case PR_INSTANCE_KEY:
 		bin = talloc_zero(mem_ctx, struct Binary_r);
 		bin->cb = 4;
@@ -547,6 +555,7 @@
 		data = talloc_strdup(mem_ctx, ldb_string);
 		break;
 	case PT_MV_STRING8:
+	case PT_MV_UNICODE:
 		ldb_element = ldb_msg_find_element(msg2, attribute);
 		if (!ldb_element) return NULL;
 
@@ -589,7 +598,7 @@
  */
 _PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs(TALLOC_CTX *mem_ctx, struct emsabp_context *emsabp_ctx,
 					    struct SRow *aRow, uint32_t MId, 
-					    struct SPropTagArray *pPropTags)
+					    uint32_t dwFlags, struct SPropTagArray *pPropTags)
 {
 	enum MAPISTATUS		retval;
 	void			*ldb_ctx;
@@ -610,7 +619,7 @@
 		retval = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->tdb_ctx, MId, &dn);
 		ldb_ctx = emsabp_ctx->conf_ctx;
 	}
-	OPENCHANGE_RETVAL_IF(retval, MAPI_E_CORRUPT_STORE, NULL);
+	OPENCHANGE_RETVAL_IF(retval, MAPI_E_INVALID_BOOKMARK, NULL);
 
 	/* Step 1. Fetch the LDB record */
 	ldb_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn);
@@ -627,7 +636,7 @@
 
 	for (i = 0; i < aRow->cValues; i++) {
 		ulPropTag = pPropTags->aulPropTag[i];
-		data = emsabp_query(mem_ctx, emsabp_ctx, res->msgs[0], ulPropTag, MId);
+		data = emsabp_query(mem_ctx, emsabp_ctx, res->msgs[0], ulPropTag, MId, dwFlags);
 		if (!data) {
 			ulPropTag &= 0xFFFF0000;
 			ulPropTag += PT_ERROR;
@@ -1089,7 +1098,7 @@
    \return MAPI_E_SUCCESS on success, otherwise MAPI error
  */
 _PUBLIC_ enum MAPISTATUS emsabp_search_legacyExchangeDN(struct emsabp_context *emsabp_ctx, const char *legacyDN,
-							struct ldb_message **ldb_res)
+							struct ldb_message **ldb_res, bool *pbInConfigPartition)
 {
 	const char * const	recipient_attrs[] = { "*", NULL };
 	int			ret;
@@ -1098,12 +1107,20 @@
 	/* Sanity Checks */
 	OPENCHANGE_RETVAL_IF(!legacyDN, MAPI_E_INVALID_PARAMETER, NULL);
 	OPENCHANGE_RETVAL_IF(!ldb_res, MAPI_E_INVALID_PARAMETER, NULL);
+	OPENCHANGE_RETVAL_IF(!pbInConfigPartition, MAPI_E_INVALID_PARAMETER, NULL);
 
+	*pbInConfigPartition = true;
 	ret = ldb_search(emsabp_ctx->conf_ctx, emsabp_ctx->mem_ctx, &res,
-			 ldb_get_default_basedn(emsabp_ctx->conf_ctx), 
+			 ldb_get_default_basedn(emsabp_ctx->conf_ctx),
 			 LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)",
 			 legacyDN);
-
+	if (ret != LDB_SUCCESS || res->count == 0) {
+		*pbInConfigPartition = false;
+		ret = ldb_search(emsabp_ctx->users_ctx, emsabp_ctx->mem_ctx, &res,
+				 ldb_get_default_basedn(emsabp_ctx->users_ctx),
+				 LDB_SCOPE_SUBTREE, recipient_attrs, "(legacyExchangeDN=%s)",
+				 legacyDN);
+	}
 	OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count, MAPI_E_NOT_FOUND, NULL);
 
 	*ldb_res = res->msgs[0];
Index: mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c
===================================================================
--- mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c	(revision 1425)
+++ mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c	(working copy)
@@ -263,7 +263,7 @@
 	r->out.ppRows[0]->cRows = r->in.Count;
 	r->out.ppRows[0]->aRow = talloc_array(mem_ctx, struct SRow, r->in.Count);
 	for (i = 0; i < r->in.Count; i++) {
-		retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(r->out.ppRows[0]->aRow[i]), r->in.lpETable[i], pPropTags);
+		retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(r->out.ppRows[0]->aRow[i]), r->in.lpETable[i], r->in.dwFlags, pPropTags);
 		if (retval != MAPI_E_SUCCESS) {
 			goto failure;
 		}
@@ -351,7 +351,7 @@
 
 	for (i = 0; i < ppOutMIds->cValues; i++) {
 		retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, &(r->out.ppRows[0]->aRow[i]), 
-					    ppOutMIds->aulPropTag[i], r->in.pPropTags);
+					    ppOutMIds->aulPropTag[i], fEphID, r->in.pPropTags);
 		if (retval) goto failure;
 	}
 
@@ -402,6 +402,7 @@
 	uint32_t		i;
 	uint32_t		MId;
 	const char		*dn;
+	bool 			bUseConfPartition;
 
 	DEBUG(3, ("exchange_nsp: NspiDNToMId (0x7)\n"));
 
@@ -424,15 +425,16 @@
 
 	for (i = 0; i < r->in.pNames->Count; i++) {
 		/* Step 1. Check if the input legacyDN exists */
-		retval = emsabp_search_legacyExchangeDN(emsabp_ctx, r->in.pNames->Strings[i], &msg);
+		retval = emsabp_search_legacyExchangeDN(emsabp_ctx, r->in.pNames->Strings[i], &msg, &bUseConfPartition);
 		if (retval != MAPI_E_SUCCESS) {
 			r->out.ppMIds[0]->aulPropTag[i] = 0;
 		} else {
+			TDB_CONTEXT *tdb_ctx = (bUseConfPartition ? emsabp_ctx->tdb_ctx : emsabp_ctx->ttdb_ctx);
 			dn = ldb_msg_find_attr_as_string(msg, "distinguishedName", NULL);
-			retval = emsabp_tdb_fetch_MId(emsabp_ctx->tdb_ctx, dn, &MId);
+			retval = emsabp_tdb_fetch_MId(tdb_ctx, dn, &MId);
 			if (retval) {
-				retval = emsabp_tdb_insert(emsabp_ctx->tdb_ctx, dn);
-				retval = emsabp_tdb_fetch_MId(emsabp_ctx->tdb_ctx, dn, &MId);
+				retval = emsabp_tdb_insert(tdb_ctx, dn);
+				retval = emsabp_tdb_fetch_MId(tdb_ctx, dn, &MId);
 			}
 			r->out.ppMIds[0]->aulPropTag[i] = MId;
 		}
@@ -479,7 +481,7 @@
 	struct dcesrv_handle	*h;
 	struct emsabp_context	*emsabp_ctx;
 	uint32_t		MId;
-	char			*dn;
+	int 			i;
 
 	DEBUG(3, ("exchange_nsp: NspiGetProps (0x9)\n"));
 
@@ -498,35 +500,56 @@
 	/* Step 1. Sanity Checks (MS-NSPI Server Processing Rules) */
 	if (r->in.pStat->ContainerID && (emsabp_tdb_lookup_MId(emsabp_ctx->tdb_ctx, r->in.pStat->ContainerID) == false)) {
 		retval = MAPI_E_INVALID_BOOKMARK;
-		goto failure;
+		r->out.result = retval;
+		return retval;
 	}
 
-	retval = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->tdb_ctx, MId, &dn);
-	if (retval != MAPI_E_SUCCESS) {
-	failure:
-		r->out.ppRows = talloc_array(mem_ctx, struct SRow *, 2);
-		r->out.ppRows[0] = NULL;
-		r->out.result = MAPI_E_INVALID_BOOKMARK;
-		return r->out.result;
-	}
 
 	/* Step 2. Fetch properties */
 	r->out.ppRows = talloc_array(mem_ctx, struct SRow *, 2);
 	r->out.ppRows[0] = talloc_zero(r->out.ppRows, struct SRow);
 	r->out.ppRows[0]->ulAdrEntryPad = 0;
-	r->out.ppRows[0]->cValues = r->in.pPropTags->cValues;
-	r->out.ppRows[0]->lpProps = talloc_array(r->out.ppRows[0], struct SPropValue, r->in.pPropTags->cValues);
 
-	retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, r->out.ppRows[0], MId, r->in.pPropTags);
+	retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, r->out.ppRows[0], MId, r->in.dwFlags, r->in.pPropTags);
 	if (retval != MAPI_E_SUCCESS) {
-		talloc_free(r->out.ppRows);
-		r->out.result = MAPI_W_ERRORS_RETURNED;
-		goto failure;
+		// if Mid is not found, we should proceed as though no attributes are found
+		if (retval == MAPI_E_INVALID_BOOKMARK) {
+			// set all requested prop values to error
+			uint32_t 	ulPropTag;
+			struct SRow *aRow;
+			aRow = r->out.ppRows[0];
+			aRow->ulAdrEntryPad = 0x0;
+			aRow->cValues = r->in.pPropTags->cValues;
+			aRow->lpProps = talloc_array(mem_ctx, struct SPropValue, aRow->cValues);
+			for (i = 0; i < aRow->cValues; i++) {
+				ulPropTag = r->in.pPropTags->aulPropTag[i];
+				ulPropTag = (ulPropTag & 0xFFFF0000) | PT_ERROR;
+
+				aRow->lpProps[i].ulPropTag = ulPropTag;
+				aRow->lpProps[i].dwAlignPad = 0x0;
+				set_SPropValue(&(aRow->lpProps[i]), NULL);
+			}
+			retval = MAPI_W_ERRORS_RETURNED;
+		} else {
+			talloc_free(r->out.ppRows);
+			r->out.ppRows = NULL;
+		}
+		r->out.result = retval;
+		return r->out.result;
 	}
 
-	r->out.result = MAPI_E_SUCCESS;
+	// Step 3. Properties are fetched. Make proper return value.
+	//         We should return ErrorsReturned if at least one property is not found.
+	for (i = 0; i < r->out.ppRows[0]->cValues; i++) {
+		if ((r->out.ppRows[0]->lpProps[i].ulPropTag & 0xFFFF) == PT_ERROR) {
+			retval = MAPI_W_ERRORS_RETURNED;
+			break;
+		}
+	}
 
-	return MAPI_E_SUCCESS;
+	r->out.result = retval;
+
+	return retval;
 }
 
 
Index: mapiproxy/servers/default/nspi/emsabp_property.c
===================================================================
--- mapiproxy/servers/default/nspi/emsabp_property.c	(revision 1425)
+++ mapiproxy/servers/default/nspi/emsabp_property.c	(working copy)
@@ -39,10 +39,11 @@
 	{ PR_COMPANY_NAME,			"company",		false,	NULL			},
 	{ PR_DISPLAY_NAME,			"displayName",		false,	NULL			},
 	{ PR_EMAIL_ADDRESS,			"legacyExchangeDN",	false,	NULL			},
-	{ PR_EMS_AB_HOME_MDB,			"homeMDB",		true,	"legacyExchangeDN"	},
-	{ PR_EMS_AB_PROXY_ADDRESSES,		"proxyAddresses",	false,	NULL			},
-	{ PR_EMS_AB_NETWORK_ADDRESS,		"networkAddress",	false,	NULL			},
-	{ PR_TITLE,				"personalTitle",	false,	NULL			},
+	{ PR_EMS_AB_HOME_MDB,					"homeMDB",		true,	"legacyExchangeDN"	},
+	{ PR_EMS_AB_PROXY_ADDRESSES,			"proxyAddresses",	false,	NULL			},
+	{ PR_EMS_AB_PROXY_ADDRESSES_UNICODE,	"proxyAddresses",	false,	NULL			},
+	{ PR_EMS_AB_NETWORK_ADDRESS,			"networkAddress",	false,	NULL			},
+	{ PR_TITLE,								"personalTitle",	false,	NULL			},
 	{ 0,					NULL,			false,	NULL			}
 };
 
Index: mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h
===================================================================
--- mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h	(revision 1425)
+++ mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.h	(working copy)
@@ -123,13 +123,13 @@
 enum MAPISTATUS		emsabp_PermanentEntryID_to_Binary_r(TALLOC_CTX *, struct PermanentEntryID *, struct Binary_r *);
 enum MAPISTATUS		emsabp_get_HierarchyTable(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct SRowSet **);
 enum MAPISTATUS		emsabp_get_CreationTemplatesTable(TALLOC_CTX *, struct emsabp_context *, uint32_t, struct SRowSet **);
-void			*emsabp_query(TALLOC_CTX *, struct emsabp_context *, struct ldb_message *, uint32_t, uint32_t);
-enum MAPISTATUS		emsabp_fetch_attrs(TALLOC_CTX *, struct emsabp_context *, struct SRow *, uint32_t, struct SPropTagArray *);
+void			*emsabp_query(TALLOC_CTX *, struct emsabp_context *, struct ldb_message *, uint32_t, uint32_t, uint32_t dwFlags);
+enum MAPISTATUS		emsabp_fetch_attrs(TALLOC_CTX *, struct emsabp_context *, struct SRow *, uint32_t MId, uint32_t dwFlags, struct SPropTagArray *);
 enum MAPISTATUS		emsabp_table_fetch_attrs(TALLOC_CTX *, struct emsabp_context *, struct SRow *, uint32_t, struct PermanentEntryID *, 
 						 struct PermanentEntryID *, struct ldb_message *, bool);
 enum MAPISTATUS		emsabp_search(TALLOC_CTX *, struct emsabp_context *, struct SPropTagArray *, struct Restriction_r *, struct STAT *, uint32_t);
 enum MAPISTATUS		emsabp_search_dn(struct emsabp_context *, const char *, struct ldb_message **);
-enum MAPISTATUS		emsabp_search_legacyExchangeDN(struct emsabp_context *, const char *, struct ldb_message **);
+enum MAPISTATUS		emsabp_search_legacyExchangeDN(struct emsabp_context *, const char *, struct ldb_message **, bool *pbInConfigPartition);
 
 /* definitions from emsabp_tdb.c */
 TDB_CONTEXT		*emsabp_tdb_init(TALLOC_CTX *, struct loadparm_context *);
