2 MAPI Proxy - Exchange RFR Server
6 Copyright (C) Julien Kerihuel 2009
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 \file dcesrv_exchange_ds_rfr.c
25 \brief OpenChange RFR Server implementation
28 #include "mapiproxy/dcesrv_mapiproxy.h"
29 #include "dcesrv_exchange_ds_rfr.h"
32 \details exchange_ds_rfr RfrGetNewDSA (0x0) function
34 \param dce_call pointer to the session context
35 \param mem_ctx pointer to the memory context
36 \param r pointer to the RfrGetNewDSA request data
38 \note We incorrectly assume input pUserDN is correct and available,
41 \return MAPI_E_SUCCESS on success
43 static enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call,
45 struct RfrGetNewDSA *r)
47 const char *netbiosname = NULL;
48 const char *realm = NULL;
51 DEBUG(5, ("exchange_ds_rfr: RfrGetNewDSA (0x0)\n"));
53 /* HACK: Disable authentication */
54 /* Step 0. Ensure incoming user is authenticated */
55 // if (!dcesrv_call_authenticated(dce_call)) {
56 // DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
58 // r->out.ppszUnused = NULL;
59 // r->out.ppszServer = NULL;
60 // r->out.result = MAPI_E_LOGON_FAILED;
61 // return MAPI_E_LOGON_FAILED;
64 /* Step 1. We don't have load-balancing support yet, just return Samba FQDN name */
65 netbiosname = lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx);
66 realm = lpcfg_realm(dce_call->conn->dce_ctx->lp_ctx);
67 if (!netbiosname || !realm) {
68 r->out.ppszUnused = NULL;
69 r->out.ppszServer = NULL;
70 r->out.result = MAPI_E_NO_SUPPORT;
71 return MAPI_E_NO_SUPPORT;
74 fqdn = talloc_asprintf(mem_ctx, "%s.%s", netbiosname, realm);
75 r->out.ppszUnused = NULL;
76 r->out.ppszServer = talloc_array(mem_ctx, const char *, 2);
77 r->out.ppszServer[0] = strlower_talloc(mem_ctx, fqdn);
78 r->out.ppszServer[1] = NULL;
79 r->out.result = MAPI_E_SUCCESS;
81 return MAPI_E_SUCCESS;
86 \details exchange_ds_rrf RfrGetFQDNFromLegacyDN (0x1) function
88 \param dce_call pointer to the session context
89 \param mem_ctx pointer to the memory context
90 \param r pointer to the RfrGetFQDNFromLegacyDN request data
92 \return MAPI_E_SUCCESS on success
94 static enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call,
96 struct RfrGetFQDNFromLegacyDN *r)
99 const char *netbiosname;
102 DEBUG(3, ("exchange_ds_rfr: RfrGetFQDNFromLegacyDN (0x1)\n"));
104 // if (!dcesrv_call_authenticated(dce_call)) {
105 // DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
108 // r->out.ppszServerFQDN = talloc_array(mem_ctx, const char *, 2);
109 // r->out.ppszServerFQDN[0] = NULL;
110 // r->out.result = MAPI_E_LOGON_FAILED;
111 // return MAPI_E_LOGON_FAILED;
114 // netbiosname = lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx);
115 // realm = lpcfg_realm(dce_call->conn->dce_ctx->lp_ctx);
116 // if (!netbiosname || !realm) {
120 fqdn = talloc_asprintf(mem_ctx, "%s.%s", netbiosname, realm);
121 r->out.ppszServerFQDN = talloc_array(mem_ctx, const char *, 2);
122 r->out.ppszServerFQDN[0] = strlower_talloc(mem_ctx, fqdn);
124 r->out.result = MAPI_E_SUCCESS;
126 return MAPI_E_SUCCESS;
131 \details Dispatch incoming RFR call to the correct OpenChange server function
133 \param dce_call pointer to the session context
134 \param mem_ctx pointer to the memory context
135 \param r generic pointer on RFR data
136 \param mapiproxy pointer to the mapiproxy structure controlling
141 static NTSTATUS dcesrv_exchange_ds_rfr_dispatch(struct dcesrv_call_state *dce_call,
143 void *r, struct mapiproxy *mapiproxy)
145 enum MAPISTATUS retval;
146 const struct ndr_interface_table *table;
149 table = (const struct ndr_interface_table *) dce_call->context->iface->private_data;
150 opnum = dce_call->pkt.u.request.opnum;
153 if (!table) return NT_STATUS_UNSUCCESSFUL;
154 if (table->name && strcmp(table->name, NDR_EXCHANGE_DS_RFR_NAME)) return NT_STATUS_UNSUCCESSFUL;
157 case NDR_RFRGETNEWDSA:
158 retval = dcesrv_RfrGetNewDSA(dce_call, mem_ctx, (struct RfrGetNewDSA *)r);
160 case NDR_RFRGETFQDNFROMLEGACYDN:
161 retval = dcesrv_RfrGetFQDNFromLegacyDN(dce_call, mem_ctx, (struct RfrGetFQDNFromLegacyDN *)r);
171 \details Initialize the RFR OpenChange server
173 \param dce_ctx pointer to the server context
175 \return NT_STATUS_OK on success
177 static NTSTATUS dcesrv_exchange_ds_rfr_init(struct dcesrv_context *dce_ctx)
184 \details Terminate the RFR connection
186 \param server_id reference to the server identifier structure
187 \param context_id the connection context identifier
189 \return NT_STATUS_OK on success
191 static NTSTATUS dcesrv_exchange_ds_rfr_unbind(struct server_id server_id,
199 \details Entry point for the default OpenChange RFR server
201 \return NT_STATUS_OK on success, otherwise NTSTATUS error
203 NTSTATUS samba_init_module(void)
205 struct mapiproxy_module server;
208 /* Fill in our name */
209 server.name = "exchange_ds_rfr";
210 server.status = MAPIPROXY_DEFAULT;
211 server.description = "OpenChange RFR server";
212 server.endpoint = "exchange_ds_rfr";
214 /* Fill in all the operations */
215 server.init = dcesrv_exchange_ds_rfr_init;
216 server.unbind = dcesrv_exchange_ds_rfr_unbind;
217 server.dispatch = dcesrv_exchange_ds_rfr_dispatch;
220 server.ndr_pull = NULL;
222 /* Register ourselves with the MAPIPROXY server subsystem */
223 ret = mapiproxy_server_register(&server);
224 if (!NT_STATUS_IS_OK(ret)) {
225 DEBUG(0, ("Failed to register the 'exchange_ds_rfr' default mapiproxy server!\n"));