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_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 /* Step 0. Ensure incoming user is authenticated */
54 if (!NTLM_AUTH_IS_OK(dce_call
)) {
55 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
57 r
->out
.ppszUnused
= NULL
;
58 r
->out
.ppszServer
= NULL
;
59 r
->out
.result
= MAPI_E_LOGON_FAILED
;
60 return MAPI_E_LOGON_FAILED
;
63 /* Step 1. We don't have load-balancing support yet, just return Samba FQDN name */
64 netbiosname
= lp_netbios_name(dce_call
->conn
->dce_ctx
->lp_ctx
);
65 realm
= lp_realm(dce_call
->conn
->dce_ctx
->lp_ctx
);
66 if (!netbiosname
|| !realm
) {
67 r
->out
.ppszUnused
= NULL
;
68 r
->out
.ppszServer
= NULL
;
69 r
->out
.result
= MAPI_E_NO_SUPPORT
;
70 return MAPI_E_NO_SUPPORT
;
73 fqdn
= talloc_asprintf(mem_ctx
, "%s.%s", netbiosname
, realm
);
74 r
->out
.ppszUnused
= NULL
;
75 r
->out
.ppszServer
= talloc_array(mem_ctx
, const char *, 2);
76 r
->out
.ppszServer
[0] = strlower_talloc(mem_ctx
, fqdn
);
77 r
->out
.ppszServer
[1] = NULL
;
78 r
->out
.result
= MAPI_E_SUCCESS
;
80 return MAPI_E_SUCCESS
;
85 \details exchange_ds_rrf RfrGetFQDNFromLegacyDN (0x1) function
87 \param dce_call pointer to the session context
88 \param mem_ctx pointer to the memory context
89 \param r pointer to the RfrGetFQDNFromLegacyDN request data
91 \return MAPI_E_SUCCESS on success
93 static enum MAPISTATUS
dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state
*dce_call
,
95 struct RfrGetFQDNFromLegacyDN
*r
)
98 const char *netbiosname
;
101 DEBUG(3, ("exchange_ds_rfr: RfrGetFQDNFromLegacyDN (0x1)\n"));
103 if (!NTLM_AUTH_IS_OK(dce_call
)) {
104 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
107 r
->out
.ppszServerFQDN
= talloc_array(mem_ctx
, const char *, 2);
108 r
->out
.ppszServerFQDN
[0] = NULL
;
109 r
->out
.result
= MAPI_E_LOGON_FAILED
;
110 return MAPI_E_LOGON_FAILED
;
113 netbiosname
= lp_netbios_name(dce_call
->conn
->dce_ctx
->lp_ctx
);
114 realm
= lp_realm(dce_call
->conn
->dce_ctx
->lp_ctx
);
115 if (!netbiosname
|| !realm
) {
119 fqdn
= talloc_asprintf(mem_ctx
, "%s.%s", netbiosname
, realm
);
120 r
->out
.ppszServerFQDN
= talloc_array(mem_ctx
, const char *, 2);
121 r
->out
.ppszServerFQDN
[0] = strlower_talloc(mem_ctx
, fqdn
);
123 r
->out
.result
= MAPI_E_SUCCESS
;
125 return MAPI_E_SUCCESS
;
130 \details Dispatch incoming RFR call to the correct OpenChange server function
132 \param dce_call pointer to the session context
133 \param mem_ctx pointer to the memory context
134 \param r generic pointer on RFR data
135 \param mapiproxy pointer to the mapiproxy structure controlling
140 static NTSTATUS
dcesrv_exchange_ds_rfr_dispatch(struct dcesrv_call_state
*dce_call
,
142 void *r
, struct mapiproxy
*mapiproxy
)
144 enum MAPISTATUS retval
;
145 const struct ndr_interface_table
*table
;
148 table
= (const struct ndr_interface_table
*) dce_call
->context
->iface
->private_data
;
149 opnum
= dce_call
->pkt
.u
.request
.opnum
;
152 if (!table
) return NT_STATUS_UNSUCCESSFUL
;
153 if (table
->name
&& strcmp(table
->name
, NDR_EXCHANGE_DS_RFR_NAME
)) return NT_STATUS_UNSUCCESSFUL
;
156 case NDR_RFRGETNEWDSA
:
157 retval
= dcesrv_RfrGetNewDSA(dce_call
, mem_ctx
, (struct RfrGetNewDSA
*)r
);
159 case NDR_RFRGETFQDNFROMLEGACYDN
:
160 retval
= dcesrv_RfrGetFQDNFromLegacyDN(dce_call
, mem_ctx
, (struct RfrGetFQDNFromLegacyDN
*)r
);
170 \details Initialize the RFR OpenChange server
172 \param dce_ctx pointer to the server context
174 \return NT_STATUS_OK on success
176 static NTSTATUS
dcesrv_exchange_ds_rfr_init(struct dcesrv_context
*dce_ctx
)
183 \details Terminate the RFR connection
185 \param server_id reference to the server identifier structure
186 \param context_id the connection context identifier
188 \return NT_STATUS_OK on success
190 static NTSTATUS
dcesrv_exchange_ds_rfr_unbind(struct server_id server_id
,
198 \details Entry point for the default OpenChange RFR server
200 \return NT_STATUS_OK on success, otherwise NTSTATUS error
202 NTSTATUS
samba_init_module(void)
204 struct mapiproxy_module server
;
207 /* Fill in our name */
208 server
.name
= "exchange_ds_rfr";
209 server
.status
= MAPIPROXY_DEFAULT
;
210 server
.description
= "OpenChange RFR server";
211 server
.endpoint
= "exchange_ds_rfr";
213 /* Fill in all the operations */
214 server
.init
= dcesrv_exchange_ds_rfr_init
;
215 server
.unbind
= dcesrv_exchange_ds_rfr_unbind
;
216 server
.dispatch
= dcesrv_exchange_ds_rfr_dispatch
;
219 server
.ndr_pull
= NULL
;
221 /* Register ourselves with the MAPIPROXY server subsystem */
222 ret
= mapiproxy_server_register(&server
);
223 if (!NT_STATUS_IS_OK(ret
)) {
224 DEBUG(0, ("Failed to register the 'exchange_ds_rfr' default mapiproxy server!\n"));