2 OpenChange Exchange Administration library.
4 Based on the work by Andrew Tridgell, 2004
6 Original source code available in SAMBA_4_0:
7 source/torture/rpc/testjoin.c
9 Copyright (C) Julien Kerihuel 2007-2008.
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 3 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <libmapiadmin/libmapiadmin.h>
30 #include <credentials.h>
31 #include <ldb_errors.h>
35 #include <core/error.h>
36 #include <gen_ndr/ndr_samr.h>
37 #include <gen_ndr/ndr_samr_c.h>
43 User management functions for mapiadmin
47 * open connection so SAMR + Join Domain
48 * common code needed when adding or removing users
50 static enum MAPISTATUS mapiadmin_samr_connect(struct mapiadmin_ctx *mapiadmin_ctx,
54 struct tevent_context *ev;
55 struct mapi_profile *profile;
56 struct samr_Connect c;
57 struct samr_OpenDomain o;
58 struct samr_LookupDomain l;
59 struct policy_handle handle;
60 struct policy_handle domain_handle;
61 struct lsa_String name;
63 MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
64 MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL);
65 MAPI_RETVAL_IF(!mapiadmin_ctx->session, MAPI_E_NOT_INITIALIZED, NULL);
66 MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile, MAPI_E_NOT_INITIALIZED, NULL);
67 MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile->credentials, MAPI_E_NOT_INITIALIZED, NULL);
68 MAPI_RETVAL_IF(!mapiadmin_ctx->username, MAPI_E_NOT_INITIALIZED, NULL);
70 profile = mapiadmin_ctx->session->profile;
72 mapiadmin_ctx->user_ctx = talloc_zero(mem_ctx, struct test_join);
73 MAPI_RETVAL_IF(!mapiadmin_ctx->user_ctx, MAPI_E_NOT_ENOUGH_RESOURCES ,NULL);
75 DEBUG(3, ("Connecting to SAMR\n"));
77 ev = tevent_context_init(mem_ctx);
79 status = dcerpc_pipe_connect(mapiadmin_ctx->user_ctx,
80 &mapiadmin_ctx->user_ctx->p,
81 mapiadmin_ctx->dc_binding ?
82 mapiadmin_ctx->dc_binding :
83 mapiadmin_ctx->binding,
85 profile->credentials, ev, global_mapi_ctx->lp_ctx);
87 MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, NULL);
89 profile = mapiadmin_ctx->session->profile;
91 c.in.system_name = NULL;
92 c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
93 c.out.connect_handle = &handle;
95 status = dcerpc_samr_Connect(mapiadmin_ctx->user_ctx->p,
96 mapiadmin_ctx->user_ctx, &c);
97 if (!NT_STATUS_IS_OK(status)) {
98 const char *errstr = nt_errstr(status);
99 if (NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) {
100 errstr = dcerpc_errstr(mapiadmin_ctx->user_ctx, mapiadmin_ctx->user_ctx->p->last_fault_code);
102 DEBUG(3, ("samr_Connect failed - %s\n", errstr));
103 return MAPI_E_CALL_FAILED;
106 DEBUG(3, ("Opening domain %s\n", profile->domain));
108 name.string = profile->domain;
109 l.in.connect_handle = &handle;
110 l.in.domain_name = &name;
112 l.out.sid = talloc(mem_ctx, struct dom_sid2 *);
113 talloc_steal(mapiadmin_ctx->user_ctx, l.out.sid);
115 status = dcerpc_samr_LookupDomain(mapiadmin_ctx->user_ctx->p,
116 mapiadmin_ctx->user_ctx, &l);
117 if (!NT_STATUS_IS_OK(status)) {
118 DEBUG(3, ("LookupDomain failed - %s\n", nt_errstr(status)));
119 return MAPI_E_CALL_FAILED;
122 mapiadmin_ctx->user_ctx->dom_sid = *l.out.sid;
123 mapiadmin_ctx->user_ctx->dom_netbios_name = talloc_strdup(mapiadmin_ctx->user_ctx, profile->domain);
124 if (!mapiadmin_ctx->user_ctx->dom_netbios_name) return MAPI_E_CALL_FAILED;
126 o.in.connect_handle = &handle;
127 o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
128 o.in.sid = *l.out.sid;
129 o.out.domain_handle = &domain_handle;
131 status = dcerpc_samr_OpenDomain(mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->user_ctx, &o);
132 if (!NT_STATUS_IS_OK(status)) {
133 DEBUG(3, ("OpenDomain failed - %s\n", nt_errstr(status)));
134 return MAPI_E_CALL_FAILED;
137 mapiadmin_ctx->handle = talloc_memdup(mem_ctx, &domain_handle, sizeof (struct policy_handle));
140 return MAPI_E_SUCCESS;
144 struct tce_async_context {
148 static int tce_search_callback(struct ldb_request *req, struct ldb_reply *ares)
150 struct tce_async_context *actx = talloc_get_type(req->context, struct tce_async_context);
153 switch (ares->type) {
155 case LDB_REPLY_ENTRY:
156 if (ldb_msg_find_element(ares->message, "msExchMailboxGuid") != NULL) {
157 DEBUG(3, ("[%s:%d]: msExchMailboxGuid found!\n", __FUNCTION__, __LINE__));
160 return ldb_request_done(req, LDB_SUCCESS);
167 DEBUG(3, ("[%s:%d]: unknown Reply Type ignore it\n", __FUNCTION__, __LINE__));
169 return LDB_ERR_OTHER;
172 if (talloc_free(ares) == -1) {
173 DEBUG(3, ("[%s:%d]: talloc_free failed\n", __FUNCTION__, __LINE__));
174 return LDB_ERR_OPERATIONS_ERROR;
181 * Extend user attributes to be Exchange user
183 _PUBLIC_ enum MAPISTATUS mapiadmin_user_extend(struct mapiadmin_ctx *mapiadmin_ctx)
186 enum MAPISTATUS retval;
187 struct tevent_context *ev = NULL;
188 struct mapi_profile *profile;
189 struct ldb_context *remote_ldb;
190 struct ldb_request *req;
191 struct ldb_message *msg;
192 struct ldb_result *res;
193 struct ldb_control **controls;
194 const char *control_strings[2] = { "notification:0", NULL };
195 struct tce_async_context *tce_ctx;
196 const struct dom_sid *dom_sid;
197 char *remote_ldb_url;
198 const char * const dom_attrs[] = { "*", NULL };
202 const char *exch_attrs[7];
206 const char *UserAccountControl;
207 struct ldb_dn *account_dn;
210 MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
211 MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL);
212 MAPI_RETVAL_IF(!mapiadmin_ctx->session, MAPI_E_NOT_INITIALIZED, NULL);
213 MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile, MAPI_E_NOT_INITIALIZED, NULL);
214 MAPI_RETVAL_IF(!mapiadmin_ctx->session->profile->credentials, MAPI_E_NOT_INITIALIZED, NULL);
215 MAPI_RETVAL_IF(!mapiadmin_ctx->user_ctx, MAPI_E_NOT_INITIALIZED, NULL);
217 profile = mapiadmin_ctx->session->profile;
218 dom_sid = mapiadmin_ctx->user_ctx->user_sid;
220 /* initialize memory context */
221 mem_ctx = talloc_named(NULL, 0, "mapiadmin_user_extend");
223 /* open LDAP connection */
224 ev = tevent_context_init(talloc_autofree_context());
225 remote_ldb_url = talloc_asprintf(mem_ctx, "ldap://%s", profile->server);
226 MAPI_RETVAL_IF(!remote_ldb_url, MAPI_E_CORRUPT_DATA, mem_ctx);
227 remote_ldb = ldb_wrap_connect(mem_ctx, ev, global_mapi_ctx->lp_ctx, remote_ldb_url,
228 NULL, mapiadmin_ctx->session->profile->credentials, 0);
229 MAPI_RETVAL_IF(!remote_ldb, MAPI_E_NETWORK_ERROR, mem_ctx);
231 /* Search the user_dn */
232 account_dn = samdb_search_dn(remote_ldb, mem_ctx, NULL,
233 "(&(objectSid=%s)(objectClass=user))",
234 ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
236 ret = ldb_search(remote_ldb, mem_ctx, &res, account_dn, LDB_SCOPE_SUBTREE, dom_attrs, "(objectSid=%s)",
237 ldap_encode_ndr_dom_sid(mem_ctx, dom_sid));
238 MAPI_RETVAL_IF(ret != LDB_SUCCESS, MAPI_E_NOT_FOUND, mem_ctx);
239 MAPI_RETVAL_IF(res->count != 1, MAPI_E_NOT_FOUND, mem_ctx);
241 /* Prepare a new message for modify */
242 msg = ldb_msg_new(mem_ctx);
243 MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
245 msg->dn = res->msgs[0]->dn;
247 /* message: givenName */
248 exch_attrs[0] = talloc_strdup(mem_ctx, mapiadmin_ctx->username);
249 ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "givenName", exch_attrs[0]);
250 MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
252 /* message: userAccountControl */
253 exch_attrs[1] = talloc_asprintf(mem_ctx, "513");
254 ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "userAccountControl",
256 MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
257 msg->elements[1].flags = LDB_FLAG_MOD_REPLACE;
260 retval = GetProfileAttr(profile, "ProxyAddress", &count, &values);
261 MAPI_RETVAL_IF(retval, retval, mem_ctx);
263 for (i = 0; i < count; i++) {
264 if (values[i] && !strncasecmp("smtp", values[i], 4)) {
265 realm = strchr(values[i], '@');
269 MAPI_RETVAL_IF(!realm, MAPI_E_NOT_FOUND, mem_ctx);
271 exch_attrs[2] = talloc_asprintf(mem_ctx, "%s@%s", mapiadmin_ctx->username, realm);
272 ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "mail", exch_attrs[2]);
273 MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
275 /* message: mailNickname */
276 exch_attrs[3] = talloc_strdup(mem_ctx, mapiadmin_ctx->username);
277 ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg, "mailNickname", exch_attrs[3]);
278 MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
280 /* message: mDBUseDefaults */
281 exch_attrs[4] = talloc_asprintf(mem_ctx, "TRUE");
282 ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg,
283 "mDBUseDefaults", exch_attrs[4]);
284 MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
286 /* message: legacyExchangeDN */
287 org = talloc_strndup(mem_ctx, profile->mailbox,
288 strlen(profile->mailbox) - strlen(profile->username));
289 exch_attrs[5] = talloc_asprintf(mem_ctx, "%s%s", org, mapiadmin_ctx->username);
291 ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg,
292 "legacyExchangeDN", exch_attrs[5]);
293 MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
295 /* message: msExchHomeServerName */
296 exch_attrs[6] = talloc_strdup(mem_ctx, profile->homemdb);
297 ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg,
298 "msExchHomeServerName", exch_attrs[6]);
299 MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
301 /* Prior we call ldb_modify, set up async ldb request on
304 req = talloc_zero(mem_ctx, struct ldb_request);
305 tce_ctx = talloc_zero(mem_ctx, struct tce_async_context);
306 controls = ldb_parse_control_strings(remote_ldb, mem_ctx, control_strings);
308 ret = ldb_build_search_req(&req, remote_ldb, mem_ctx,
317 DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_build_search_req", ldb_strerror(ret)));
318 MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx);
320 ldb_set_timeout(mem_ctx, req, 60);
322 ret = ldb_request(remote_ldb, req);
323 DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_request", ldb_strerror(ret)));
324 MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx);
326 ret = ldb_modify(remote_ldb, msg);
327 DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_modify", ldb_strerror(ret)));
328 MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CORRUPT_DATA, mem_ctx);
331 ret = ldb_wait(req->handle, LDB_WAIT_ALL);
332 DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_wait", ldb_strerror(ret)));
333 MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CALL_FAILED, mem_ctx);
334 MAPI_RETVAL_IF(!tce_ctx->found, MAPI_E_CALL_FAILED, mem_ctx);
336 /* When successful replace UserAccountControl attr in the user
340 msg = ldb_msg_new(mem_ctx);
341 MAPI_RETVAL_IF(!msg, MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
342 msg->dn = res->msgs[0]->dn;
344 UserAccountControl = talloc_asprintf(mem_ctx, "66048");
345 ret = samdb_msg_add_string(remote_ldb, mem_ctx, msg,
346 "UserAccountControl", UserAccountControl);
347 MAPI_RETVAL_IF((ret == -1), MAPI_E_NOT_ENOUGH_RESOURCES, mem_ctx);
348 msg->elements[0].flags = LDB_FLAG_MOD_REPLACE;
350 ret = ldb_modify(remote_ldb, msg);
351 DEBUG(3, (MAPIADMIN_DEBUG_STR, "ldb_modify", ldb_strerror(ret)));
352 MAPI_RETVAL_IF((ret != LDB_SUCCESS), MAPI_E_CORRUPT_DATA, mem_ctx);
354 /* reset errno before leaving */
356 talloc_free(mem_ctx);
357 return MAPI_E_SUCCESS;
361 * Add a user to Active Directory
363 _PUBLIC_ enum MAPISTATUS mapiadmin_user_add(struct mapiadmin_ctx *mapiadmin_ctx)
367 enum MAPISTATUS retval;
368 struct mapi_profile *profile;
369 struct samr_CreateUser2 r;
370 struct samr_GetUserPwInfo pwp;
371 struct samr_SetUserInfo s;
372 union samr_UserInfo u;
373 uint32_t access_granted;
375 DATA_BLOB session_key;
376 struct lsa_String name;
377 int policy_min_pw_len = 0;
379 mem_ctx = talloc_named(NULL, 0, "mapiadmin_user_add");
381 retval = mapiadmin_samr_connect(mapiadmin_ctx, mem_ctx);
382 MAPI_RETVAL_IF(retval, retval, mem_ctx);
384 DEBUG(3, ("Creating account %s\n", mapiadmin_ctx->username));
385 profile = mapiadmin_ctx->session->profile;
388 name.string = mapiadmin_ctx->username;
389 r.in.domain_handle = mapiadmin_ctx->handle;
390 r.in.account_name = &name;
391 r.in.acct_flags = ACB_NORMAL;
392 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
393 r.out.user_handle = &mapiadmin_ctx->user_ctx->user_handle;
394 r.out.access_granted = &access_granted;
397 status = dcerpc_samr_CreateUser2(mapiadmin_ctx->user_ctx->p,
398 mapiadmin_ctx->user_ctx, &r);
400 if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
401 mapiadmin_user_del(mapiadmin_ctx);
402 if (NT_STATUS_IS_OK(status)) {
405 MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx);
409 if (!NT_STATUS_IS_OK(status)) {
410 DEBUG(3, ("CreateUser2 failed - %s\n", nt_errstr(status)));
411 MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx);
414 mapiadmin_ctx->user_ctx->user_sid = dom_sid_add_rid(mapiadmin_ctx->user_ctx, mapiadmin_ctx->user_ctx->dom_sid, rid);
416 pwp.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle;
417 pwp.out.info = talloc_zero(mem_ctx, struct samr_PwInfo);
419 status = dcerpc_samr_GetUserPwInfo(mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->user_ctx, &pwp);
420 if (NT_STATUS_IS_OK(status)) {
421 policy_min_pw_len = pwp.out.info->min_password_length;
423 DEBUG(3, ("GetUserPwInfo failed - %s\n", nt_errstr(status)));
424 MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx);
427 if (!mapiadmin_ctx->password) {
428 mapiadmin_ctx->password = generate_random_str(mapiadmin_ctx->user_ctx, MAX(8, policy_min_pw_len));
431 DEBUG(3, ("Setting account password '%s'\n", mapiadmin_ctx->password));
434 s.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle;
438 encode_pw_buffer(u.info24.password.data, mapiadmin_ctx->password, STR_UNICODE);
439 u.info24.password_expired = 0;
441 status = dcerpc_fetch_session_key(mapiadmin_ctx->user_ctx->p, &session_key);
442 if (!NT_STATUS_IS_OK(status)) {
443 DEBUG(3, ("SetUserInfo level %d - no session key - %s\n",
444 s.in.level, nt_errstr(status)));
445 mapiadmin_user_del(mapiadmin_ctx);
446 MAPI_RETVAL_IF(1,MAPI_E_CALL_FAILED,mem_ctx);
449 arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
451 status = dcerpc_samr_SetUserInfo(mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->user_ctx, &s);
452 if (!NT_STATUS_IS_OK(status)) {
453 DEBUG(3, ("SetUserInfo failed - %s\n", nt_errstr(status)));
454 if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
455 MAPI_RETVAL_IF(1, MAPI_E_BAD_VALUE, mem_ctx);
457 MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED, mem_ctx);
462 s.in.user_handle = &mapiadmin_ctx->user_ctx->user_handle;
466 u.info21.acct_flags = ACB_NORMAL | ACB_PWNOEXP;
467 u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;
469 u.info21.comment.string = talloc_asprintf(mapiadmin_ctx->user_ctx,
470 mapiadmin_ctx->comment ?
471 mapiadmin_ctx->comment :
472 "Created by OpenChange: %s",
473 timestring(mapiadmin_ctx->user_ctx, time(NULL)));
475 u.info21.full_name.string = talloc_asprintf(mapiadmin_ctx->user_ctx,
476 mapiadmin_ctx->fullname ?
477 mapiadmin_ctx->fullname :
478 "Account for OpenChange: %s",
479 timestring(mapiadmin_ctx->user_ctx, time(NULL)));
481 u.info21.description.string = talloc_asprintf(mapiadmin_ctx->user_ctx,
482 mapiadmin_ctx->description ?
483 mapiadmin_ctx->description :
484 "OpenChange account created by host %s: %s",
485 lp_netbios_name(global_mapi_ctx->lp_ctx),
486 timestring(mapiadmin_ctx->user_ctx, time(NULL)));
488 DEBUG(3, ("Resetting ACB flags, force pw change time\n"));
490 status = dcerpc_samr_SetUserInfo(mapiadmin_ctx->user_ctx->p, mapiadmin_ctx->user_ctx, &s);
491 if (!NT_STATUS_IS_OK(status)) {
492 DEBUG(3, ("SetUserInfo failed - %s\n", nt_errstr(status)));
493 MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED, mem_ctx);
495 retval = mapiadmin_user_extend(mapiadmin_ctx);
496 if (retval != MAPI_E_SUCCESS) {
497 DEBUG(3, ("mapiadmin_user_extend: 0x%x\n", GetLastError()));
498 mapiadmin_user_del(mapiadmin_ctx);
499 MAPI_RETVAL_IF(1, MAPI_E_CALL_FAILED,mem_ctx);
502 talloc_free(mem_ctx);
503 return MAPI_E_SUCCESS;
507 * Delete a user from Active Directory
509 _PUBLIC_ enum MAPISTATUS mapiadmin_user_del(struct mapiadmin_ctx *mapiadmin_ctx)
512 enum MAPISTATUS retval;
514 struct samr_DeleteUser d;
515 struct policy_handle user_handle;
517 struct samr_LookupNames n;
518 struct lsa_String sname;
519 struct samr_OpenUser r;
521 MAPI_RETVAL_IF(!mapiadmin_ctx, MAPI_E_NOT_INITIALIZED, NULL);
522 MAPI_RETVAL_IF(!mapiadmin_ctx->username, MAPI_E_NOT_INITIALIZED, NULL);
524 mem_ctx = talloc_named(NULL, 0, "mapiadmin_user_del");
526 /* Initiate SAMR connection if not already done */
527 if (!mapiadmin_ctx->user_ctx) {
528 retval = mapiadmin_samr_connect(mapiadmin_ctx, mem_ctx);
529 MAPI_RETVAL_IF(retval, GetLastError(), mem_ctx);
532 sname.string = mapiadmin_ctx->username;
534 n.in.domain_handle = mapiadmin_ctx->handle;
538 n.out.rids = talloc_zero(mem_ctx, struct samr_Ids);
539 n.out.types = talloc_zero(mem_ctx, struct samr_Ids);
541 status = dcerpc_samr_LookupNames(mapiadmin_ctx->user_ctx->p, mem_ctx, &n);
542 if (NT_STATUS_IS_OK(status)) {
543 rid = n.out.rids->ids[0];
545 talloc_free(mem_ctx);
546 return MAPI_E_NOT_FOUND;
549 r.in.domain_handle = mapiadmin_ctx->handle;
550 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
552 r.out.user_handle = &user_handle;
554 status = dcerpc_samr_OpenUser(mapiadmin_ctx->user_ctx->p, mem_ctx, &r);
555 if (!NT_STATUS_IS_OK(status)) {
556 DEBUG(3, ("OpenUser(%s) failed - %s\n", mapiadmin_ctx->username, nt_errstr(status)));
557 MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_NOT_FOUND, mem_ctx);
560 d.in.user_handle = &user_handle;
561 d.out.user_handle = &user_handle;
562 status = dcerpc_samr_DeleteUser(mapiadmin_ctx->user_ctx->p, mem_ctx, &d);
563 MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
565 talloc_free(mem_ctx);
566 return MAPI_E_SUCCESS;
569 _PUBLIC_ enum MAPISTATUS mapiadmin_user_mod(struct mapiadmin_ctx *mapiadmin)
571 return MAPI_E_NO_SUPPORT;