[
uuid("1544f5e0-613c-11d1-93df-00c04fd7bd09"),
+ endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]","ncacn_ip_tcp:[]"),
pointer_default(unique),
version(1.0),
helpstring("Exchange 2003 Directory Request For Response")
] interface exchange_ds_rfr
{
+
+#include "mapitags_enum.h"
+#include "mapicodes_enum.h"
+
/*****************/
/* Function 0x00 */
- void RfrGetNewDSA();
-
+ MAPISTATUS RfrGetNewDSA(
+ [in] uint32 ulFlags,
+ [in,string,charset(DOS)] uint8 *pUserDN,
+ [in,out,unique,string,charset(DOS)] uint8 **ppszUnused,
+ [in,out,unique,string,charset(DOS)] uint8 **ppszServer
+ );
+
/*****************/
/* Function 0x01 */
- void RfrGetFQDNFromLegacyDN();
+ MAPISTATUS RfrGetFQDNFromLegacyDN(
+ [in] uint32 ulFlags,
+ [in,range(10,1024)] uint32 cbMailboxServerDN,
+ [in,string,charset(DOS),size_is(cbMailboxServerDN)] uint8 *szMailboxServerDN,
+ [out,ref,string,charset(DOS)] uint8 **ppszServerFQDN
+ );
}
[
] interface exchange_nsp
{
-#include "mapitags_enum.h"
-#include "mapicodes_enum.h"
-
/*****************/
/* Function 0x00 */
#include <libmapi/mapicode.h>
#include <libmapi/proto_private.h>
#include <gen_ndr/ndr_exchange.h>
+#include <gen_ndr/ndr_exchange_c.h>
#include <core/error.h>
#include <param.h>
#include <credentials.h>
return status;
}
-enum MAPISTATUS Logon(struct mapi_provider *provider, enum PROVIDER_ID provider_id)
+
+/**
+ \details Returns the name of an NSPI server
+
+ \param server the Exchange server address (IP or FQDN)
+ \param userDN optional user mailbox DN
+
+ \return a valid string on success, otherwise NULL
+ */
+_PUBLIC_ const char *RfrGetNewDSA(const char *server, const char *userDN)
{
NTSTATUS status;
TALLOC_CTX *mem_ctx;
- struct dcerpc_pipe *pipe;
struct mapi_profile *profile;
+ struct RfrGetNewDSA r;
+ struct dcerpc_pipe *pipe;
char *binding;
+ const char *ppszServer = NULL;
+
+ /* Sanity Checks */
+ if (!global_mapi_ctx) return server;
+ if (!global_mapi_ctx->session) return server;
+
+ mem_ctx = (TALLOC_CTX *)global_mapi_ctx->session;
+ profile = global_mapi_ctx->session->profile;
+ binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", server, ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
+ status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_ds_rfr, global_mapi_ctx->lp_ctx);
+ talloc_free(binding);
+
+ r.in.ulFlags = 0x0;
+ r.in.pUserDN = userDN ? userDN : "";
+ r.in.ppszUnused = NULL;
+ r.in.ppszServer = &ppszServer;
+
+ status = dcerpc_RfrGetNewDSA(pipe, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) return server;
+
+ return (ppszServer ? ppszServer : server);
+}
+
+
+/**
+ \details Returns the FQDN of the NSPI server corresponding to a DN
+
+ \param pointer on pointer on the server FQDN returned
+
+ \return MAPI_E_SUCCESS on success, otherwise a MAPI error and
+ serverFQDN content set to NULL.
+ */
+_PUBLIC_ enum MAPISTATUS RfrGetFQDNFromLegacyDN(const char **serverFQDN)
+{
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ struct mapi_profile *profile;
+ struct RfrGetFQDNFromLegacyDN r;
+ struct dcerpc_pipe *pipe;
+ char *binding;
+ const char *ppszServerFQDN;
+
+ /* Sanity Checks */
MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
MAPI_RETVAL_IF(!global_mapi_ctx->session, MAPI_E_NOT_INITIALIZED, NULL);
- mem_ctx = (TALLOC_CTX *)provider;
+ mem_ctx = (TALLOC_CTX *)global_mapi_ctx->session;
profile = global_mapi_ctx->session->profile;
+ *serverFQDN = NULL;
+
+ binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", profile->server, ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
+ status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_ds_rfr, global_mapi_ctx->lp_ctx);
+ talloc_free(binding);
+
+ r.in.ulFlags = 0x0;
+ r.in.cbMailboxServerDN = strlen(profile->homemdb) + 1;
+ r.in.szMailboxServerDN = profile->homemdb;
+ r.out.ppszServerFQDN = &ppszServerFQDN;
+
+ status = dcerpc_RfrGetFQDNFromLegacyDN(pipe, mem_ctx, &r);
+ MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
- if (global_mapi_ctx->dumpdata == false) {
- binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s", profile->server);
+ if (ppszServerFQDN) {
+ *serverFQDN = ppszServerFQDN;
} else {
- binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s[print]", profile->server);
+ *serverFQDN = NULL;
}
+ return MAPI_E_SUCCESS;
+}
+
+enum MAPISTATUS Logon(struct mapi_provider *provider, enum PROVIDER_ID provider_id)
+{
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ struct dcerpc_pipe *pipe;
+ struct mapi_profile *profile;
+ char *binding;
+
+ MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ MAPI_RETVAL_IF(!global_mapi_ctx->session, MAPI_E_NOT_INITIALIZED, NULL);
+
+ mem_ctx = (TALLOC_CTX *)provider;
+ profile = global_mapi_ctx->session->profile;
+
switch(provider_id) {
case PROVIDER_ID_EMSMDB:
+ binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", profile->server, ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_emsmdb, global_mapi_ctx->lp_ctx);
talloc_free(binding);
MAPI_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), MAPI_E_NETWORK_ERROR, NULL);
MAPI_RETVAL_IF(!provider->ctx, MAPI_E_LOGON_FAILED, NULL);
break;
case PROVIDER_ID_NSPI:
+ /* Call RfrGetNewDSA prior any NSPI call */
+ binding = talloc_asprintf(mem_ctx, "ncacn_ip_tcp:%s%s", RfrGetNewDSA(profile->server, profile->mailbox),
+ ((global_mapi_ctx->dumpdata == true) ? "[print]" : "[]"));
status = provider_rpc_connection(mem_ctx, &pipe, binding, profile->credentials, &ndr_table_exchange_nsp, global_mapi_ctx->lp_ctx);
talloc_free(binding);
MAPI_RETVAL_IF(NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_REFUSED), MAPI_E_NETWORK_ERROR, NULL);
MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ MAPI_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
/* allocate session if it doesn't already exist */
if (!*session || !global_mapi_ctx->session) {
status = dcerpc_server_exchange_nsp_init();
NT_STATUS_NOT_OK_RETURN(status);
+ status = dcerpc_server_exchange_ds_rfr_init();
+ NT_STATUS_NOT_OK_RETURN(status);
+
/* Step2. Register Exchange ndr tables */
status = ndr_table_register(&ndr_table_exchange_emsmdb);
NT_STATUS_NOT_OK_RETURN(status);
status = ndr_table_register(&ndr_table_exchange_nsp);
NT_STATUS_NOT_OK_RETURN(status);
+ status = ndr_table_register(&ndr_table_exchange_ds_rfr);
+ NT_STATUS_NOT_OK_RETURN(status);
+
/* Step3. Finally register mapiproxy endpoint */
status = dcerpc_server_mapiproxy_init();
NT_STATUS_NOT_OK_RETURN(status);
void dcesrv_ec_store_admin3_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin3_dummy *);
void dcesrv_ec_store_admin2_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin2_dummy *);
void dcesrv_ec_store_admin1_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct ec_store_admin1_dummy *);
-void dcesrv_RfrGetNewDSA(struct dcesrv_call_state *, TALLOC_CTX *,struct RfrGetNewDSA *);
-void dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *, TALLOC_CTX *,struct RfrGetFQDNFromLegacyDN *);
+enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *, TALLOC_CTX *,struct RfrGetNewDSA *);
+enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *, TALLOC_CTX *,struct RfrGetFQDNFromLegacyDN *);
void dcesrv_sysatt_cluster_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct sysatt_cluster_dummy *);
void dcesrv_sysatt_dummy(struct dcesrv_call_state *, TALLOC_CTX *,struct sysatt_dummy *);
void dcesrv_MtaBind(struct dcesrv_call_state *, TALLOC_CTX *,struct MtaBind *);
/*
RfrGetNewDSA
*/
-void dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct RfrGetNewDSA *r)
+enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct RfrGetNewDSA *r)
{
- DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
/*
RfrGetFQDNFromLegacyDN
*/
-void dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct RfrGetFQDNFromLegacyDN *r)
+enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct RfrGetFQDNFromLegacyDN *r)
{
- DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
/*
/*
RfrGetNewDSA
*/
-void dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct RfrGetNewDSA *r)
+enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct RfrGetNewDSA *r)
{
- DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
/*
RfrGetFQDNFromLegacyDN
*/
-void dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct RfrGetFQDNFromLegacyDN *r)
+enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct RfrGetFQDNFromLegacyDN *r)
{
- DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
+ DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
}
/*
struct ec_store_admin2_dummy *r);
void dcesrv_ec_store_admin1_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct ec_store_admin1_dummy *r);
-void dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct RfrGetNewDSA *r);
-void dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct RfrGetFQDNFromLegacyDN *r);
+enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct RfrGetNewDSA *r);
+enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+ struct RfrGetFQDNFromLegacyDN *r);
void dcesrv_sysatt_cluster_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct sysatt_cluster_dummy *r);
void dcesrv_sysatt_dummy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
}
if (opt_dumpdata == true) {
- printf("dumpdata is true\n");
global_mapi_ctx->dumpdata = true;
}
MAPIUninitialize();
}
+static void mapiprofile_get_fqdn(const char *profdb,
+ const char *profname,
+ const char *password,
+ bool opt_dumpdata)
+{
+ enum MAPISTATUS retval;
+ struct mapi_session *session;
+ const char *serverFQDN;
+
+ if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
+ mapi_errstr("MAPIInitialize", GetLastError());
+ exit (1);
+ }
+
+ if (opt_dumpdata == true) {
+ global_mapi_ctx->dumpdata = true;
+ }
+
+ if (!profname) {
+ if ((retval = GetDefaultProfile(&profname)) != MAPI_E_SUCCESS) {
+ mapi_errstr("GetDefaultProfile", GetLastError());
+ exit (1);
+ }
+ }
+
+ retval = MapiLogonProvider(&session, profname, password, PROVIDER_ID_NSPI);
+ if (retval != MAPI_E_SUCCESS) {
+ mapi_errstr("MapiLogonProvider", GetLastError());
+ exit (1);
+ }
+
+ retval = RfrGetFQDNFromLegacyDN(&serverFQDN);
+ if (retval != MAPI_E_SUCCESS) {
+ mapi_errstr("RfrGetFQDNFromLegacyDN", GetLastError());
+ exit (1);
+ }
+
+ printf("%s is at %s\n", global_mapi_ctx->session->profile->homemdb, serverFQDN);
+
+ MAPIUninitialize();
+}
+
static void mapiprofile_list(const char *profdb)
{
enum MAPISTATUS retval;
struct SRowSet proftable;
uint32_t count = 0;
- if ((retval = MAPIInitialize(profdb))) {
+ if ((retval = MAPIInitialize(profdb)) != MAPI_E_SUCCESS) {
mapi_errstr("MAPIInitialize", GetLastError());
exit (1);
}
bool newdb = false;
bool setdflt = false;
bool getdflt = false;
+ bool getfqdn = false;
bool opt_dumpdata = false;
const char *ldif = NULL;
const char *address = NULL;
OPT_DOMAIN, OPT_USERNAME, OPT_LCID, OPT_PASSWORD, OPT_CREATE_PROFILE,
OPT_DELETE_PROFILE, OPT_LIST_PROFILE, OPT_DUMP_PROFILE,
OPT_DUMP_ATTR, OPT_PROFILE_NEWDB, OPT_PROFILE_LDIF, OPT_LIST_LANGS,
- OPT_PROFILE_SET_DFLT, OPT_PROFILE_GET_DFLT, OPT_PATTERN,
+ OPT_PROFILE_SET_DFLT, OPT_PROFILE_GET_DFLT, OPT_PATTERN, OPT_GETFQDN,
OPT_NOPASS, OPT_DUMPDATA};
struct poptOption long_options[] = {
{"dump", 'd', POPT_ARG_NONE, NULL, OPT_DUMP_PROFILE, "dump a profile entry"},
{"attr", 'a', POPT_ARG_STRING, NULL, OPT_DUMP_ATTR, "print an attribute value"},
{"dump-data", 0, POPT_ARG_NONE, NULL, OPT_DUMPDATA, "dump the hex data"},
+ {"getfqdn", 0, POPT_ARG_NONE, NULL, OPT_GETFQDN, "returns the DNS FQDN of the NSPI server matching the legacyDN"},
{ NULL }
};
switch(opt) {
case OPT_DUMPDATA:
opt_dumpdata = true;
+ break;
case OPT_PROFILE_LDIF:
ldif = poptGetOptArg(pc);
break;
case OPT_DUMP_ATTR:
attribute = poptGetOptArg(pc);
break;
+ case OPT_GETFQDN:
+ getfqdn = true;
+ break;
}
}
getenv("HOME"));
}
- if ((list == false) && (newdb == false) && (listlangs == false)
+ if ((list == false) && (getfqdn == false) && (newdb == false) && (listlangs == false)
&& (getdflt == false) && (dump == false) &&
(!attribute) && (!profname || !profdb)) {
poptPrintUsage(pc, stderr, 0);
lcid, workstation, domain, nopass, opt_dumpdata);
}
+ if (getfqdn == true) {
+ mapiprofile_get_fqdn(profdb, profname, password, opt_dumpdata);
+ }
+
if (listlangs == true) {
lcid_print_languages();
}