287f18ab3cd57698adefe92cb3a29f8760b549c8
[jelmer/openchange.git] / mapiproxy / servers / default / rfr / dcesrv_exchange_ds_rfr.c
1 /*
2    MAPI Proxy - Exchange RFR Server
3
4    OpenChange Project
5
6    Copyright (C) Julien Kerihuel 2009
7
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.
12    
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.
17    
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/>.
20  */
21
22 /**
23    \file dcesrv_exchange_ds_rfr.c
24
25    \brief OpenChange RFR Server implementation
26  */
27
28 #include "mapiproxy/dcesrv_mapiproxy.h"
29 #include "dcesrv_exchange_ds_rfr.h"
30
31 /**
32    \details exchange_ds_rfr RfrGetNewDSA (0x0) function
33
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
37
38    \note We incorrectly assume input pUserDN is correct and available,
39    but it is OK for now.
40
41    \return MAPI_E_SUCCESS on success
42  */
43 static enum MAPISTATUS dcesrv_RfrGetNewDSA(struct dcesrv_call_state *dce_call,
44                                            TALLOC_CTX *mem_ctx,
45                                            struct RfrGetNewDSA *r)
46 {
47         const char              *netbiosname = NULL;
48         const char              *realm = NULL;
49         char                    *fqdn = NULL;
50
51         DEBUG(5, ("exchange_ds_rfr: RfrGetNewDSA (0x0)\n"));
52
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"));
57 //
58 //              r->out.ppszUnused = NULL;
59 //              r->out.ppszServer = NULL;
60 //              r->out.result = MAPI_E_LOGON_FAILED;
61 //              return MAPI_E_LOGON_FAILED;
62 //      }
63
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;                       
72         }
73
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;
80
81         return MAPI_E_SUCCESS;
82 }
83
84
85 /**
86    \details exchange_ds_rrf RfrGetFQDNFromLegacyDN (0x1) function
87
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
91
92    \return MAPI_E_SUCCESS on success
93  */
94 static enum MAPISTATUS dcesrv_RfrGetFQDNFromLegacyDN(struct dcesrv_call_state *dce_call,
95                                                      TALLOC_CTX *mem_ctx,
96                                                      struct RfrGetFQDNFromLegacyDN *r)
97 {
98         char            *fqdn;
99         const char      *netbiosname;
100         const char      *realm;
101
102         DEBUG(3, ("exchange_ds_rfr: RfrGetFQDNFromLegacyDN (0x1)\n"));
103
104 //      if (!dcesrv_call_authenticated(dce_call)) {
105 //              DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
106
107 //      failure:
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;
112 //      }
113
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) {
117 //              goto failure;
118 //      }
119
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);
123         talloc_free(fqdn);
124         r->out.result = MAPI_E_SUCCESS;
125
126         return MAPI_E_SUCCESS;
127 }
128
129
130 /**
131    \details Dispatch incoming RFR call to the correct OpenChange server function
132
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
137    mapiproxy behavior
138
139    \return NT_STATUS_OK
140  */
141 static NTSTATUS dcesrv_exchange_ds_rfr_dispatch(struct dcesrv_call_state *dce_call,
142                                                 TALLOC_CTX *mem_ctx,
143                                                 void *r, struct mapiproxy *mapiproxy)
144 {
145         enum MAPISTATUS                         retval;
146         const struct ndr_interface_table        *table;
147         uint16_t                                opnum;
148
149         table = (const struct ndr_interface_table *) dce_call->context->iface->private_data;
150         opnum = dce_call->pkt.u.request.opnum;
151
152         /* Sanity checks */
153         if (!table) return NT_STATUS_UNSUCCESSFUL;
154         if (table->name && strcmp(table->name, NDR_EXCHANGE_DS_RFR_NAME)) return NT_STATUS_UNSUCCESSFUL;
155
156         switch (opnum) {
157         case NDR_RFRGETNEWDSA:
158                 retval = dcesrv_RfrGetNewDSA(dce_call, mem_ctx, (struct RfrGetNewDSA *)r);
159                 break;
160         case NDR_RFRGETFQDNFROMLEGACYDN:
161                 retval = dcesrv_RfrGetFQDNFromLegacyDN(dce_call, mem_ctx, (struct RfrGetFQDNFromLegacyDN *)r);
162                 break;
163         }
164
165
166         return NT_STATUS_OK;
167 }
168
169
170 /**
171    \details Initialize the RFR OpenChange server
172
173    \param dce_ctx pointer to the server context
174
175    \return NT_STATUS_OK on success
176  */
177 static NTSTATUS dcesrv_exchange_ds_rfr_init(struct dcesrv_context *dce_ctx)
178 {
179         return NT_STATUS_OK;
180 }
181
182
183 /**
184    \details Terminate the RFR connection
185
186    \param server_id reference to the server identifier structure
187    \param context_id the connection context identifier
188
189    \return NT_STATUS_OK on success
190  */
191 static NTSTATUS dcesrv_exchange_ds_rfr_unbind(struct server_id server_id, 
192                                               uint32_t context_id)
193 {
194         return NT_STATUS_OK;
195 }
196
197
198 /**
199    \details Entry point for the default OpenChange RFR server
200
201    \return NT_STATUS_OK on success, otherwise NTSTATUS error
202  */
203 NTSTATUS samba_init_module(void)
204 {
205         struct mapiproxy_module server;
206         NTSTATUS                ret;
207
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";
213
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;
218         server.push = NULL;
219         server.pull = NULL;
220         server.ndr_pull = NULL;
221
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"));
226                 return ret;
227         }
228
229         return ret;
230 }