From 44366158cc6182d3d61eaaf6b28788fc666befd6 Mon Sep 17 00:00:00 2001 From: Julien Kerihuel Date: Sun, 11 Jan 2009 22:51:37 +0000 Subject: [PATCH] - Preliminary implementation of NspiGetProps NSPI server function - Makes sure emsabp_tdb_traverse_MId uses the correct dbuf size - Use correct ldb context (users or conf) depending on where MId is located (on-memory or on-disk) - Add PR_EMS_AB_NETWORK_ADDRESS mapping to emsabp_property *** Outlook is now able to create MAPI profile using OpenChange Server ONLY! *** --- .../default/nspi/dcesrv_exchange_nsp.c | 59 +++++++++++++++++-- mapiproxy/servers/default/nspi/emsabp.c | 13 +++- .../servers/default/nspi/emsabp_property.c | 1 + mapiproxy/servers/default/nspi/emsabp_tdb.c | 9 ++- 4 files changed, 71 insertions(+), 11 deletions(-) diff --git a/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c b/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c index 79768b99..2944493c 100644 --- a/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c +++ b/mapiproxy/servers/default/nspi/dcesrv_exchange_nsp.c @@ -339,10 +339,6 @@ static enum MAPISTATUS dcesrv_NspiGetMatches(struct dcesrv_call_state *dce_call, *r->out.ppOutMIds = ppOutMIds; - for (i = 0; i < r->out.ppOutMIds[0]->cValues; i++) { - DEBUG(0, ("[%s:%d]: 0x%x\n", __FUNCTION__, __LINE__, r->out.ppOutMIds[0]->aulPropTag[i])); - } - /* Step 2. Retrieve requested properties for these MIds */ r->out.ppRows = talloc_zero(mem_ctx, struct SRowSet *); r->out.ppRows[0] = talloc_zero(mem_ctx, struct SRowSet); @@ -473,8 +469,59 @@ static enum MAPISTATUS dcesrv_NspiGetProps(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct NspiGetProps *r) { - DEBUG(3, ("exchange_nsp: NspiGetProps (0x9) not implemented\n")); - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + enum MAPISTATUS retval; + struct dcesrv_handle *h; + struct emsabp_context *emsabp_ctx; + uint32_t MId; + char *dn; + + DEBUG(3, ("exchange_nsp: NspiGetProps (0x9)\n")); + + /* Step 0. Ensure incoming user is authenticated */ + if (!NTLM_AUTH_IS_OK(dce_call)) { + DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); + return MAPI_E_LOGON_FAILED; + } + + h = dcesrv_handle_fetch(dce_call->context, r->in.handle, DCESRV_HANDLE_ANY); + emsabp_ctx = (struct emsabp_context *) h->data; + + MId = r->in.pStat->CurrentRec; + + /* 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; + } + + 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(mem_ctx, struct SRow); + r->out.ppRows[0]->ulAdrEntryPad = 0; + r->out.ppRows[0]->cValues = r->in.pPropTags->cValues; + r->out.ppRows[0]->lpProps = talloc_array(mem_ctx, struct SPropValue, r->in.pPropTags->cValues); + + retval = emsabp_fetch_attrs(mem_ctx, emsabp_ctx, r->out.ppRows[0], MId, r->in.pPropTags); + if (retval != MAPI_E_SUCCESS) { + talloc_free(r->out.ppRows[0]->lpProps); + talloc_free(r->out.ppRows[0]); + talloc_free(r->out.ppRows[0]); + r->out.result = MAPI_W_ERRORS_RETURNED; + goto failure; + } + + r->out.result = MAPI_E_SUCCESS; + + return MAPI_E_SUCCESS; } diff --git a/mapiproxy/servers/default/nspi/emsabp.c b/mapiproxy/servers/default/nspi/emsabp.c index 10c87c31..f84751d3 100644 --- a/mapiproxy/servers/default/nspi/emsabp.c +++ b/mapiproxy/servers/default/nspi/emsabp.c @@ -602,6 +602,7 @@ _PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs(TALLOC_CTX *mem_ctx, struct emsabp_c struct SPropTagArray *pPropTags) { enum MAPISTATUS retval; + void *ldb_ctx; char *dn; const char * const recipient_attrs[] = { "*", NULL }; struct ldb_result *res = NULL; @@ -611,15 +612,21 @@ _PUBLIC_ enum MAPISTATUS emsabp_fetch_attrs(TALLOC_CTX *mem_ctx, struct emsabp_c void *data; int i; - /* Step 0. Retrieve the dn associated to the MId */ + /* Step 0. Try to Retrieve the dn associated to the MId first from temp TDB (users) */ + ldb_ctx = emsabp_ctx->users_ctx; retval = emsabp_tdb_fetch_dn_from_MId(mem_ctx, emsabp_ctx->ttdb_ctx, MId, &dn); + if (retval) { + /* If it fails try to retrieve it from the on-disk TDB database (conf) */ + 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); /* Step 1. Fetch the LDB record */ - ldb_dn = ldb_dn_new(mem_ctx, emsabp_ctx->users_ctx, dn); + ldb_dn = ldb_dn_new(mem_ctx, ldb_ctx, dn); OPENCHANGE_RETVAL_IF(!ldb_dn_validate(ldb_dn), MAPI_E_CORRUPT_STORE, NULL); - ret = ldb_search(emsabp_ctx->users_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, LDB_SCOPE_BASE, + ret = ldb_search(ldb_ctx, emsabp_ctx->mem_ctx, &res, ldb_dn, LDB_SCOPE_BASE, recipient_attrs, NULL); OPENCHANGE_RETVAL_IF(ret != LDB_SUCCESS || !res->count || res->count != 1, MAPI_E_CORRUPT_STORE, NULL); diff --git a/mapiproxy/servers/default/nspi/emsabp_property.c b/mapiproxy/servers/default/nspi/emsabp_property.c index b283471e..3824c30c 100644 --- a/mapiproxy/servers/default/nspi/emsabp_property.c +++ b/mapiproxy/servers/default/nspi/emsabp_property.c @@ -41,6 +41,7 @@ static const struct emsabp_property emsabp_property[] = { { 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 }, { 0, NULL, false, NULL } }; diff --git a/mapiproxy/servers/default/nspi/emsabp_tdb.c b/mapiproxy/servers/default/nspi/emsabp_tdb.c index c22b43c7..acbfc77a 100644 --- a/mapiproxy/servers/default/nspi/emsabp_tdb.c +++ b/mapiproxy/servers/default/nspi/emsabp_tdb.c @@ -210,10 +210,15 @@ static int emsabp_tdb_traverse_MId(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA dbuf, void *state) { + TALLOC_CTX *mem_ctx; uint32_t value; + char *value_str = NULL; uint32_t *MId = (uint32_t *)state; - value = strtol((const char *)dbuf.dptr, NULL, 16); + mem_ctx = talloc_init("emsabp_tdb_traverse_MId"); + value_str = talloc_strndup(mem_ctx, (char *)dbuf.dptr, dbuf.dsize); + value = strtol((const char *)value_str, NULL, 16); + talloc_free(mem_ctx); if (value == *MId) return 1; return 0; @@ -286,7 +291,7 @@ _PUBLIC_ enum MAPISTATUS emsabp_tdb_fetch_dn_from_MId(TALLOC_CTX *mem_ctx, emsabp_MId->MId = MId; ret = tdb_traverse(tdb_ctx, emsabp_tdb_traverse_MId_DN, (void *)emsabp_MId); - if (ret == 1) { + if (ret > -1 && emsabp_MId->dn) { *dn = talloc_strdup(mem_ctx, emsabp_MId->dn); talloc_free(emsabp_MId); return MAPI_E_SUCCESS; -- 2.34.1