2 OpenChange Server implementation
4 EMSMDBP: EMSMDB Provider implementation
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/>.
25 \brief EMSMDB Provider implementation
28 #include "mapiproxy/dcesrv_mapiproxy.h"
29 #include "mapiproxy/libmapiproxy.h"
30 #include "dcesrv_exchange_emsmdb.h"
33 \details Initialize the EMSMDBP context and open connections to
36 \param lp_ctx pointer to the loadparm_context
38 \return Allocated emsmdbp_context pointer on success, otherwise
41 _PUBLIC_ struct emsmdbp_context *emsmdbp_init(struct loadparm_context *lp_ctx)
44 struct emsmdbp_context *emsmdbp_ctx;
45 struct tevent_context *ev;
46 char *configuration = NULL;
51 if (!lp_ctx) return NULL;
53 mem_ctx = talloc_named(NULL, 0, "emsmdbp_init");
55 emsmdbp_ctx = talloc_zero(mem_ctx, struct emsmdbp_context);
61 emsmdbp_ctx->mem_ctx = mem_ctx;
63 ev = tevent_context_init(mem_ctx);
69 /* Save a pointer to the loadparm context */
70 emsmdbp_ctx->lp_ctx = lp_ctx;
72 /* Return an opaque context pointer on the configuration database */
73 configuration = private_path(mem_ctx, lp_ctx, "configuration.ldb");
74 emsmdbp_ctx->conf_ctx = ldb_init(mem_ctx, ev);
75 if (!emsmdbp_ctx->conf_ctx) {
76 talloc_free(configuration);
81 ret = ldb_connect(emsmdbp_ctx->conf_ctx, configuration, LDB_FLG_RDONLY, NULL);
82 talloc_free(configuration);
83 if (ret != LDB_SUCCESS) {
84 DEBUG(0, ("[%s:%d]: Connection to \"configuration.ldb\" failed\n", __FUNCTION__, __LINE__));
89 /* Return an opaque pointer on the users database */
90 users = private_path(mem_ctx, lp_ctx, "users.ldb");
91 emsmdbp_ctx->users_ctx = ldb_init(mem_ctx, ev);
92 if (!emsmdbp_ctx->users_ctx) {
98 ret = ldb_connect(emsmdbp_ctx->users_ctx, users, LDB_FLG_RDONLY, NULL);
100 if (ret != LDB_SUCCESS) {
101 DEBUG(0, ("[%s:%d]: Connection to \"users.ldb\" failed\n", __FUNCTION__, __LINE__));
102 talloc_free(mem_ctx);
110 _PUBLIC_ bool emsmdbp_destructor(void *data)
112 struct emsmdbp_context *emsmdbp_ctx = (struct emsmdbp_context *)data;
115 talloc_free(emsmdbp_ctx->mem_ctx);
116 DEBUG(0, ("[%s:%d]: emsmdbp_ctx found and released\n", __FUNCTION__, __LINE__));
125 \details Check if the authenticated user belongs to the Exchange
126 organization and is enabled
128 \param dce_call pointer to the session context
129 \param emsmdbp_ctx pointer to the EMSMDBP context
131 \return true on success, otherwise false
133 _PUBLIC_ bool emsmdbp_verify_user(struct dcesrv_call_state *dce_call,
134 struct emsmdbp_context *emsmdbp_ctx)
137 const char *username = NULL;
138 int msExchUserAccountControl;
139 struct ldb_result *res = NULL;
141 const char * const recipient_attrs[] = { "msExchUserAccountControl", NULL };
143 username = dce_call->context->conn->auth_state.session_info->server_info->account_name;
145 ldb_filter = talloc_asprintf(emsmdbp_ctx->mem_ctx, "CN=%s", username);
146 ret = ldb_search(emsmdbp_ctx->users_ctx, emsmdbp_ctx->mem_ctx, &res,
147 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
148 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
149 talloc_free(ldb_filter);
151 /* If the search failed */
152 if (ret != LDB_SUCCESS || !res->count) {
156 /* If msExchUserAccountControl attribute is not found */
157 if (!res->msgs[0]->num_elements) {
161 /* If the attribute exists check its value */
162 msExchUserAccountControl = ldb_msg_find_attr_as_int(res->msgs[0], "msExchUserAccountControl", 2);
163 if (msExchUserAccountControl == 2) {
172 \details Check if the user record which legacyExchangeDN points to
173 belongs to the Exchange organization and is enabled
175 \param dce_call pointer to the session context
176 \param emsmdbp_ctx pointer to the EMSMDBP context
177 \param legacyExchangeDN pointer to the userDN to lookup
178 \param msg pointer on pointer to the LDB message matching the record
180 \note Users can set msg to NULL if they do not intend to retrieve
183 \return true on success, otherwise false
185 _PUBLIC_ bool emsmdbp_verify_userdn(struct dcesrv_call_state *dce_call,
186 struct emsmdbp_context *emsmdbp_ctx,
187 const char *legacyExchangeDN,
188 struct ldb_message **msg)
191 int msExchUserAccountControl;
192 struct ldb_result *res = NULL;
194 const char * const recipient_attrs[] = { "*", NULL };
197 if (!legacyExchangeDN) return false;
199 ldb_filter = talloc_asprintf(emsmdbp_ctx->mem_ctx, "(legacyExchangeDN=%s)", legacyExchangeDN);
200 ret = ldb_search(emsmdbp_ctx->users_ctx, emsmdbp_ctx->mem_ctx, &res,
201 ldb_get_default_basedn(emsmdbp_ctx->users_ctx),
202 LDB_SCOPE_SUBTREE, recipient_attrs, ldb_filter);
203 talloc_free(ldb_filter);
205 /* If the search failed */
206 if (ret != LDB_SUCCESS || !res->count) {
210 /* Checks msExchUserAccountControl value */
211 msExchUserAccountControl = ldb_msg_find_attr_as_int(res->msgs[0], "msExchUserAccountControl", 2);
212 if (msExchUserAccountControl == 2) {