docs: insert function name "wins_dns_proxy" into dns proxy parameter
[Samba/wip.git] / source3 / passdb / pdb_samba_dsdb.c
blob3fc266c4e264c9f58888b8338e56c9d6d79bba77
1 /*
2 Unix SMB/CIFS implementation.
3 pdb glue module for direct access to the dsdb via LDB APIs
4 Copyright (C) Volker Lendecke 2009-2011
5 Copyright (C) Andrew Bartlett 2010-2012
6 Copyright (C) Matthias Dieter Wallnöfer 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/>.
22 /* This module, is a port of Volker's pdb_ads to ldb and DSDB APIs */
24 #include "includes.h"
25 #include "source3/include/passdb.h"
26 #include "source4/dsdb/samdb/samdb.h"
27 #include "ldb_errors.h"
28 #include "libcli/security/dom_sid.h"
29 #include "source4/winbind/idmap.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "libds/common/flag_mapping.h"
32 #include "source4/lib/events/events.h"
33 #include "source4/auth/session.h"
34 #include "source4/auth/system_session_proto.h"
35 #include "lib/param/param.h"
36 #include "source4/dsdb/common/util.h"
37 #include "source3/include/secrets.h"
39 struct pdb_samba_dsdb_state {
40 struct tevent_context *ev;
41 struct ldb_context *ldb;
42 struct idmap_context *idmap_ctx;
43 struct loadparm_context *lp_ctx;
46 static NTSTATUS pdb_samba_dsdb_getsampwsid(struct pdb_methods *m,
47 struct samu *sam_acct,
48 const struct dom_sid *sid);
49 static NTSTATUS pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state *state,
50 const char *filter,
51 TALLOC_CTX *mem_ctx,
52 struct ldb_message **pmsg);
53 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
54 struct unixid *id);
56 static bool pdb_samba_dsdb_pull_time(struct ldb_message *msg, const char *attr,
57 time_t *ptime)
59 uint64_t tmp;
60 if (! ldb_msg_find_element(msg, attr)) {
61 return false;
63 tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
64 *ptime = nt_time_to_unix(tmp);
65 return true;
68 static struct pdb_domain_info *pdb_samba_dsdb_get_domain_info(
69 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
71 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
72 m->private_data, struct pdb_samba_dsdb_state);
73 struct pdb_domain_info *info;
74 struct dom_sid *domain_sid;
75 struct ldb_dn *forest_dn, *domain_dn;
76 struct ldb_result *dom_res = NULL;
77 const char *dom_attrs[] = {
78 "objectSid",
79 "objectGUID",
80 "fSMORoleOwner",
81 NULL
83 char *p;
84 int ret;
86 info = talloc(mem_ctx, struct pdb_domain_info);
87 if (info == NULL) {
88 return NULL;
91 domain_dn = ldb_get_default_basedn(state->ldb);
93 ret = ldb_search(state->ldb, info, &dom_res,
94 domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
95 if (ret != LDB_SUCCESS) {
96 goto fail;
98 if (dom_res->count != 1) {
99 goto fail;
102 info->guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
104 domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
105 if (!domain_sid) {
106 goto fail;
108 info->sid = *domain_sid;
110 TALLOC_FREE(dom_res);
112 info->name = talloc_strdup(info, lpcfg_sam_name(state->lp_ctx));
113 info->dns_domain = ldb_dn_canonical_string(info, domain_dn);
115 if (!info->dns_domain) {
116 goto fail;
118 p = strchr(info->dns_domain, '/');
119 if (p) {
120 *p = '\0';
123 forest_dn = ldb_get_root_basedn(state->ldb);
124 if (!forest_dn) {
125 goto fail;
128 info->dns_forest = ldb_dn_canonical_string(info, forest_dn);
129 if (!info->dns_forest) {
130 goto fail;
132 p = strchr(info->dns_forest, '/');
133 if (p) {
134 *p = '\0';
137 return info;
139 fail:
140 TALLOC_FREE(dom_res);
141 TALLOC_FREE(info);
142 return NULL;
145 static struct ldb_message *pdb_samba_dsdb_get_samu_private(
146 struct pdb_methods *m, struct samu *sam)
148 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
149 m->private_data, struct pdb_samba_dsdb_state);
150 struct ldb_message *msg;
151 char *sidstr, *filter;
152 NTSTATUS status;
154 msg = (struct ldb_message *)
155 pdb_get_backend_private_data(sam, m);
157 if (msg != NULL) {
158 return talloc_get_type_abort(msg, struct ldb_message);
161 sidstr = dom_sid_string(talloc_tos(), pdb_get_user_sid(sam));
162 if (sidstr == NULL) {
163 return NULL;
166 filter = talloc_asprintf(
167 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
168 TALLOC_FREE(sidstr);
169 if (filter == NULL) {
170 return NULL;
173 status = pdb_samba_dsdb_getsamupriv(state, filter, sam, &msg);
174 TALLOC_FREE(filter);
175 if (!NT_STATUS_IS_OK(status)) {
176 return NULL;
179 return msg;
182 static NTSTATUS pdb_samba_dsdb_init_sam_from_priv(struct pdb_methods *m,
183 struct samu *sam,
184 struct ldb_message *msg)
186 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
187 m->private_data, struct pdb_samba_dsdb_state);
188 TALLOC_CTX *frame = talloc_stackframe();
189 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
190 const char *str;
191 time_t tmp_time;
192 struct dom_sid *sid, group_sid;
193 uint64_t n;
194 const DATA_BLOB *blob;
196 str = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
197 if (str == NULL) {
198 DEBUG(10, ("no samAccountName\n"));
199 goto fail;
201 pdb_set_username(sam, str, PDB_SET);
203 if (pdb_samba_dsdb_pull_time(msg, "lastLogon", &tmp_time)) {
204 pdb_set_logon_time(sam, tmp_time, PDB_SET);
206 if (pdb_samba_dsdb_pull_time(msg, "lastLogoff", &tmp_time)) {
207 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
209 if (pdb_samba_dsdb_pull_time(msg, "pwdLastSet", &tmp_time)) {
210 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
212 if (pdb_samba_dsdb_pull_time(msg, "accountExpires", &tmp_time)) {
213 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
216 str = ldb_msg_find_attr_as_string(msg, "displayName",
217 NULL);
218 if (str != NULL) {
219 pdb_set_fullname(sam, str, PDB_SET);
222 str = ldb_msg_find_attr_as_string(msg, "homeDirectory",
223 NULL);
224 if (str != NULL) {
225 pdb_set_homedir(sam, str, PDB_SET);
228 str = ldb_msg_find_attr_as_string(msg, "homeDrive", NULL);
229 if (str != NULL) {
230 pdb_set_dir_drive(sam, str, PDB_SET);
233 str = ldb_msg_find_attr_as_string(msg, "scriptPath", NULL);
234 if (str != NULL) {
235 pdb_set_logon_script(sam, str, PDB_SET);
238 str = ldb_msg_find_attr_as_string(msg, "profilePath",
239 NULL);
240 if (str != NULL) {
241 pdb_set_profile_path(sam, str, PDB_SET);
244 str = ldb_msg_find_attr_as_string(msg, "comment",
245 NULL);
246 if (str != NULL) {
247 pdb_set_comment(sam, str, PDB_SET);
250 str = ldb_msg_find_attr_as_string(msg, "description",
251 NULL);
252 if (str != NULL) {
253 pdb_set_acct_desc(sam, str, PDB_SET);
256 str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
257 NULL);
258 if (str != NULL) {
259 pdb_set_workstations(sam, str, PDB_SET);
262 str = ldb_msg_find_attr_as_string(msg, "userParameters",
263 NULL);
264 if (str != NULL) {
265 pdb_set_munged_dial(sam, str, PDB_SET);
268 sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
269 if (!sid) {
270 DEBUG(10, ("Could not pull SID\n"));
271 goto fail;
273 pdb_set_user_sid(sam, sid, PDB_SET);
275 n = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
276 if (n == 0) {
277 DEBUG(10, ("Could not pull userAccountControl\n"));
278 goto fail;
280 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
282 blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
283 if (blob) {
284 if (blob->length != NT_HASH_LEN) {
285 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
286 (int)blob->length, NT_HASH_LEN));
287 goto fail;
289 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
292 blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
293 if (blob) {
294 if (blob->length != LM_HASH_LEN) {
295 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
296 (int)blob->length, LM_HASH_LEN));
297 goto fail;
299 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
302 n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
303 if (n == 0) {
304 DEBUG(10, ("Could not pull primaryGroupID\n"));
305 goto fail;
307 sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
308 pdb_set_group_sid(sam, &group_sid, PDB_SET);
310 status = NT_STATUS_OK;
311 fail:
312 TALLOC_FREE(frame);
313 return status;
316 static bool pdb_samba_dsdb_add_time(struct ldb_message *msg,
317 const char *attrib, time_t t)
319 uint64_t nt_time;
321 unix_to_nt_time(&nt_time, t);
323 return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
326 static int pdb_samba_dsdb_replace_by_sam(struct pdb_samba_dsdb_state *state,
327 bool (*need_update)(const struct samu *,
328 enum pdb_elements),
329 struct ldb_dn *dn,
330 struct samu *sam)
332 TALLOC_CTX *frame = talloc_stackframe();
333 int ret = LDB_SUCCESS;
334 const char *pw;
335 struct ldb_message *msg;
336 struct ldb_request *req;
337 uint32_t dsdb_flags = 0;
338 /* TODO: All fields :-) */
340 msg = ldb_msg_new(frame);
341 if (!msg) {
342 return false;
345 msg->dn = dn;
347 /* build modify request */
348 ret = ldb_build_mod_req(&req, state->ldb, frame, msg, NULL, NULL,
349 ldb_op_default_callback,
350 NULL);
351 if (ret != LDB_SUCCESS) {
352 talloc_free(frame);
353 return ret;
356 /* If we set a plaintext password, the system will
357 * force the pwdLastSet to now() */
358 if (need_update(sam, PDB_PASSLASTSET)) {
359 dsdb_flags = DSDB_PASSWORD_BYPASS_LAST_SET;
361 ret |= pdb_samba_dsdb_add_time(msg, "pwdLastSet",
362 pdb_get_pass_last_set_time(sam));
365 pw = pdb_get_plaintext_passwd(sam);
366 if (need_update(sam, PDB_PLAINTEXT_PW)) {
367 struct ldb_val pw_utf16;
368 if (pw == NULL) {
369 talloc_free(frame);
370 return LDB_ERR_OPERATIONS_ERROR;
373 if (!convert_string_talloc(msg,
374 CH_UNIX, CH_UTF16,
375 pw, strlen(pw),
376 (void *)&pw_utf16.data,
377 &pw_utf16.length)) {
378 return LDB_ERR_OPERATIONS_ERROR;
380 ret |= ldb_msg_add_value(msg, "clearTextPassword", &pw_utf16, NULL);
381 } else {
382 bool changed_lm_pw = false;
383 bool changed_nt_pw = false;
384 bool changed_history = false;
385 if (need_update(sam, PDB_LMPASSWD)) {
386 struct ldb_val val;
387 val.data = discard_const_p(uint8_t, pdb_get_lanman_passwd(sam));
388 if (!val.data) {
389 samdb_msg_add_delete(state->ldb, msg, msg,
390 "dBCSPwd");
391 } else {
392 val.length = LM_HASH_LEN;
393 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
395 changed_lm_pw = true;
397 if (need_update(sam, PDB_NTPASSWD)) {
398 struct ldb_val val;
399 val.data = discard_const_p(uint8_t, pdb_get_nt_passwd(sam));
400 if (!val.data) {
401 samdb_msg_add_delete(state->ldb, msg, msg,
402 "unicodePwd");
403 } else {
404 val.length = NT_HASH_LEN;
405 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
407 changed_nt_pw = true;
410 /* Try to ensure we don't get out of sync */
411 if (changed_lm_pw && !changed_nt_pw) {
412 samdb_msg_add_delete(state->ldb, msg, msg,
413 "unicodePwd");
414 } else if (changed_nt_pw && !changed_lm_pw) {
415 samdb_msg_add_delete(state->ldb, msg, msg,
416 "dBCSPwd");
418 if (changed_lm_pw || changed_nt_pw) {
419 samdb_msg_add_delete(state->ldb, msg, msg,
420 "supplementalCredentials");
424 if (need_update(sam, PDB_PWHISTORY)) {
425 uint32_t current_hist_len;
426 const uint8_t *history = pdb_get_pw_history(sam, &current_hist_len);
428 bool invalid_history = false;
429 struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
430 current_hist_len);
431 if (!history) {
432 invalid_history = true;
433 } else {
434 unsigned int i;
435 static const uint8_t zeros[16];
436 /* Parse the history into the correct format */
437 for (i = 0; i < current_hist_len; i++) {
438 if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
439 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
440 invalid_history = true;
441 break;
443 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
444 memcpy(history_hashes[i].hash,
445 &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
446 sizeof(history_hashes[i].hash));
449 if (invalid_history) {
450 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
451 "ntPwdHistory");
453 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
454 "lmPwdHistory");
455 } else {
456 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
457 "ntPwdHistory",
458 history_hashes,
459 current_hist_len);
461 changed_history = true;
463 if (changed_lm_pw || changed_nt_pw || changed_history) {
464 /* These attributes can only be modified directly by using a special control */
465 dsdb_flags = DSDB_BYPASS_PASSWORD_HASH;
469 /* PDB_USERSID is only allowed on ADD, handled in caller */
470 if (need_update(sam, PDB_GROUPSID)) {
471 const struct dom_sid *sid = pdb_get_group_sid(sam);
472 uint32_t rid;
473 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
474 if (!NT_STATUS_IS_OK(status)) {
475 talloc_free(frame);
476 return LDB_ERR_OPERATIONS_ERROR;
478 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
479 talloc_free(frame);
480 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
482 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
484 if (need_update(sam, PDB_FULLNAME)) {
485 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
488 if (need_update(sam, PDB_SMBHOME)) {
489 ret |= ldb_msg_add_string(msg, "homeDirectory",
490 pdb_get_homedir(sam));
493 if (need_update(sam, PDB_PROFILE)) {
494 ret |= ldb_msg_add_string(msg, "profilePath",
495 pdb_get_profile_path(sam));
498 if (need_update(sam, PDB_DRIVE)) {
499 ret |= ldb_msg_add_string(msg, "homeDrive",
500 pdb_get_dir_drive(sam));
503 if (need_update(sam, PDB_LOGONSCRIPT)) {
504 ret |= ldb_msg_add_string(msg, "scriptPath",
505 pdb_get_logon_script(sam));
508 if (need_update(sam, PDB_KICKOFFTIME)) {
509 ret |= pdb_samba_dsdb_add_time(msg, "accountExpires",
510 pdb_get_kickoff_time(sam));
513 if (need_update(sam, PDB_LOGONTIME)) {
514 ret |= pdb_samba_dsdb_add_time(msg, "lastLogon",
515 pdb_get_logon_time(sam));
518 if (need_update(sam, PDB_LOGOFFTIME)) {
519 ret |= pdb_samba_dsdb_add_time(msg, "lastLogoff",
520 pdb_get_logoff_time(sam));
523 if (need_update(sam, PDB_USERNAME)) {
524 ret |= ldb_msg_add_string(msg, "samAccountName",
525 pdb_get_username(sam));
528 if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
529 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
530 ret |= ldb_msg_add_value(msg, "logonHours",
531 &hours, NULL);
534 if (need_update(sam, PDB_ACCTCTRL)) {
535 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
536 "userAccountControl", pdb_get_acct_ctrl(sam));
539 if (need_update(sam, PDB_COMMENT)) {
540 ret |= ldb_msg_add_string(msg, "comment",
541 pdb_get_comment(sam));
544 if (need_update(sam, PDB_ACCTDESC)) {
545 ret |= ldb_msg_add_string(msg, "description",
546 pdb_get_acct_desc(sam));
549 if (need_update(sam, PDB_WORKSTATIONS)) {
550 ret |= ldb_msg_add_string(msg, "userWorkstations",
551 pdb_get_workstations(sam));
554 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
555 if (need_update(sam, PDB_MUNGEDDIAL)) {
556 ret |= ldb_msg_add_string(msg, "userParameters",
557 pdb_get_munged_dial(sam));
560 if (need_update(sam, PDB_COUNTRY_CODE)) {
561 ret |= ldb_msg_add_fmt(msg, "countryCode",
562 "%i", (int)pdb_get_country_code(sam));
565 if (need_update(sam, PDB_CODE_PAGE)) {
566 ret |= ldb_msg_add_fmt(msg, "codePage",
567 "%i", (int)pdb_get_code_page(sam));
570 /* Not yet handled here or not meaningful for modifies on a Samba_Dsdb backend:
571 PDB_BAD_PASSWORD_TIME,
572 PDB_CANCHANGETIME, - these are calculated per policy, not stored
573 PDB_DOMAIN,
574 PDB_NTUSERNAME, - this makes no sense, and never really did
575 PDB_LOGONDIVS,
576 PDB_USERSID, - Handled in pdb_samba_dsdb_add_sam_account()
577 PDB_FIELDS_PRESENT,
578 PDB_BAD_PASSWORD_COUNT,
579 PDB_LOGON_COUNT,
580 PDB_UNKNOWN6,
581 PDB_BACKEND_PRIVATE_DATA,
584 if (ret != LDB_SUCCESS) {
585 talloc_free(frame);
586 return LDB_ERR_OPERATIONS_ERROR;
589 if (msg->num_elements == 0) {
590 talloc_free(frame);
591 /* Nothing to do, just return success */
592 return LDB_SUCCESS;
595 ret = dsdb_replace(state->ldb, msg, dsdb_flags);
597 if (ret != LDB_SUCCESS) {
598 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
599 ldb_dn_get_linearized(msg->dn),
600 ldb_errstring(state->ldb)));
603 talloc_free(frame);
604 return ret;
607 static NTSTATUS pdb_samba_dsdb_getsamupriv(struct pdb_samba_dsdb_state *state,
608 const char *filter,
609 TALLOC_CTX *mem_ctx,
610 struct ldb_message **msg)
612 const char * attrs[] = {
613 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
614 "sAMAccountName", "displayName", "homeDirectory",
615 "homeDrive", "scriptPath", "profilePath", "description",
616 "userWorkstations", "comment", "userParameters", "objectSid",
617 "primaryGroupID", "userAccountControl", "logonHours",
618 "badPwdCount", "logonCount", "countryCode", "codePage",
619 "unicodePwd", "dBCSPwd", NULL };
621 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
622 if (rc != LDB_SUCCESS) {
623 DEBUG(10, ("ldap_search failed %s\n",
624 ldb_errstring(state->ldb)));
625 return NT_STATUS_LDAP(rc);
628 return NT_STATUS_OK;
631 static NTSTATUS pdb_samba_dsdb_getsampwfilter(struct pdb_methods *m,
632 struct pdb_samba_dsdb_state *state,
633 struct samu *sam_acct,
634 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
636 struct ldb_message *priv;
637 NTSTATUS status;
638 va_list ap;
639 char *expression = NULL;
640 TALLOC_CTX *tmp_ctx = talloc_new(state);
641 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
643 va_start(ap, exp_fmt);
644 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
645 va_end(ap);
647 if (!expression) {
648 talloc_free(tmp_ctx);
649 return NT_STATUS_NO_MEMORY;
652 status = pdb_samba_dsdb_getsamupriv(state, expression, sam_acct, &priv);
653 talloc_free(tmp_ctx);
654 if (!NT_STATUS_IS_OK(status)) {
655 DEBUG(10, ("pdb_samba_dsdb_getsamupriv failed: %s\n",
656 nt_errstr(status)));
657 return status;
660 status = pdb_samba_dsdb_init_sam_from_priv(m, sam_acct, priv);
661 if (!NT_STATUS_IS_OK(status)) {
662 DEBUG(10, ("pdb_samba_dsdb_init_sam_from_priv failed: %s\n",
663 nt_errstr(status)));
664 TALLOC_FREE(priv);
665 return status;
668 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
669 return NT_STATUS_OK;
672 static NTSTATUS pdb_samba_dsdb_getsampwnam(struct pdb_methods *m,
673 struct samu *sam_acct,
674 const char *username)
676 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
677 m->private_data, struct pdb_samba_dsdb_state);
679 return pdb_samba_dsdb_getsampwfilter(m, state, sam_acct,
680 "(&(samaccountname=%s)(objectclass=user))",
681 username);
684 static NTSTATUS pdb_samba_dsdb_getsampwsid(struct pdb_methods *m,
685 struct samu *sam_acct,
686 const struct dom_sid *sid)
688 NTSTATUS status;
689 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
690 m->private_data, struct pdb_samba_dsdb_state);
691 char *sidstr;
693 sidstr = dom_sid_string(talloc_tos(), sid);
694 NT_STATUS_HAVE_NO_MEMORY(sidstr);
696 status = pdb_samba_dsdb_getsampwfilter(m, state, sam_acct,
697 "(&(objectsid=%s)(objectclass=user))",
698 sidstr);
699 talloc_free(sidstr);
700 return status;
703 static NTSTATUS pdb_samba_dsdb_create_user(struct pdb_methods *m,
704 TALLOC_CTX *mem_ctx,
705 const char *name, uint32 acct_flags,
706 uint32 *rid)
708 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
709 m->private_data, struct pdb_samba_dsdb_state);
710 struct dom_sid *sid;
711 struct ldb_dn *dn;
712 NTSTATUS status;
713 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
714 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
716 /* Internally this uses transactions to ensure all the steps
717 * happen or fail as one */
718 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
719 &sid, &dn);
720 if (!NT_STATUS_IS_OK(status)) {
721 talloc_free(tmp_ctx);
722 return status;
724 sid_peek_rid(sid, rid);
725 talloc_free(tmp_ctx);
726 return NT_STATUS_OK;
729 static NTSTATUS pdb_samba_dsdb_delete_user(struct pdb_methods *m,
730 TALLOC_CTX *mem_ctx,
731 struct samu *sam)
733 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
734 m->private_data, struct pdb_samba_dsdb_state);
735 struct ldb_dn *dn;
736 int rc;
737 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
738 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
740 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
741 if (!dn || !ldb_dn_validate(dn)) {
742 talloc_free(tmp_ctx);
743 return NT_STATUS_NO_MEMORY;
745 rc = ldb_delete(state->ldb, dn);
747 if (rc != LDB_SUCCESS) {
748 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
749 ldb_errstring(state->ldb)));
750 talloc_free(tmp_ctx);
751 return NT_STATUS_LDAP(rc);
753 talloc_free(tmp_ctx);
754 return NT_STATUS_OK;
757 /* This interface takes a fully populated struct samu and places it in
758 * the database. This is not implemented at this time as we need to
759 * be careful around the creation of arbitary SIDs (ie, we must ensrue
760 * they are not left in a RID pool */
761 static NTSTATUS pdb_samba_dsdb_add_sam_account(struct pdb_methods *m,
762 struct samu *sampass)
764 int ret;
765 NTSTATUS status;
766 struct ldb_dn *dn;
767 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
768 m->private_data, struct pdb_samba_dsdb_state);
769 uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
770 const char *username = pdb_get_username(sampass);
771 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
772 TALLOC_CTX *tframe = talloc_stackframe();
774 acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
776 ret = ldb_transaction_start(state->ldb);
777 if (ret != LDB_SUCCESS) {
778 talloc_free(tframe);
779 return NT_STATUS_LOCK_NOT_GRANTED;
782 status = dsdb_add_user(state->ldb, talloc_tos(), username,
783 acb_flags, user_sid, NULL, &dn);
784 if (!NT_STATUS_IS_OK(status)) {
785 ldb_transaction_cancel(state->ldb);
786 talloc_free(tframe);
787 return status;
790 ret = pdb_samba_dsdb_replace_by_sam(state, pdb_element_is_set_or_changed,
791 dn, sampass);
792 if (ret != LDB_SUCCESS) {
793 ldb_transaction_cancel(state->ldb);
794 talloc_free(tframe);
795 return dsdb_ldb_err_to_ntstatus(ret);
798 ret = ldb_transaction_commit(state->ldb);
799 if (ret != LDB_SUCCESS) {
800 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
801 ldb_dn_get_linearized(dn),
802 ldb_errstring(state->ldb)));
803 talloc_free(tframe);
804 return NT_STATUS_INTERNAL_DB_CORRUPTION;
806 talloc_free(tframe);
807 return NT_STATUS_OK;
811 * Update the Samba_Dsdb LDB with the changes from a struct samu.
813 * This takes care not to update elements that have not been changed
814 * by the caller
816 static NTSTATUS pdb_samba_dsdb_update_sam_account(struct pdb_methods *m,
817 struct samu *sam)
819 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
820 m->private_data, struct pdb_samba_dsdb_state);
821 struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
822 m, sam);
823 int ret;
825 ret = pdb_samba_dsdb_replace_by_sam(state, pdb_element_is_changed, msg->dn,
826 sam);
827 return dsdb_ldb_err_to_ntstatus(ret);
830 static NTSTATUS pdb_samba_dsdb_delete_sam_account(struct pdb_methods *m,
831 struct samu *username)
833 NTSTATUS status;
834 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
835 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
836 status = pdb_samba_dsdb_delete_user(m, tmp_ctx, username);
837 talloc_free(tmp_ctx);
838 return status;
841 static NTSTATUS pdb_samba_dsdb_rename_sam_account(struct pdb_methods *m,
842 struct samu *oldname,
843 const char *newname)
845 return NT_STATUS_NOT_IMPLEMENTED;
848 /* This is not implemented, as this module is exptected to be used
849 * with auth_samba_dsdb, and this is responible for login counters etc
852 static NTSTATUS pdb_samba_dsdb_update_login_attempts(struct pdb_methods *m,
853 struct samu *sam_acct,
854 bool success)
856 return NT_STATUS_NOT_IMPLEMENTED;
859 static NTSTATUS pdb_samba_dsdb_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
860 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
862 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
863 m->private_data, struct pdb_samba_dsdb_state);
864 const char *attrs[] = { "objectSid", "description", "samAccountName", "groupType",
865 NULL };
866 struct ldb_message *msg;
867 va_list ap;
868 char *expression = NULL;
869 struct dom_sid *sid;
870 const char *str;
871 int rc;
872 struct id_map id_map;
873 struct id_map *id_maps[2];
874 TALLOC_CTX *tmp_ctx = talloc_stackframe();
875 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
877 va_start(ap, exp_fmt);
878 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
879 va_end(ap);
881 if (!expression) {
882 talloc_free(tmp_ctx);
883 return NT_STATUS_NO_MEMORY;
886 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
887 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
888 talloc_free(tmp_ctx);
889 return NT_STATUS_NO_SUCH_GROUP;
890 } else if (rc != LDB_SUCCESS) {
891 talloc_free(tmp_ctx);
892 DEBUG(10, ("dsdb_search_one failed %s\n",
893 ldb_errstring(state->ldb)));
894 return NT_STATUS_LDAP(rc);
897 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
898 if (!sid) {
899 talloc_free(tmp_ctx);
900 DEBUG(10, ("Could not pull SID\n"));
901 return NT_STATUS_INTERNAL_DB_CORRUPTION;
904 map->sid = *sid;
906 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
907 NTSTATUS status;
908 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
909 switch (grouptype) {
910 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
911 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
912 map->sid_name_use = SID_NAME_ALIAS;
913 break;
914 case GTYPE_SECURITY_GLOBAL_GROUP:
915 map->sid_name_use = SID_NAME_DOM_GRP;
916 break;
917 default:
918 talloc_free(tmp_ctx);
919 DEBUG(10, ("Could not pull groupType\n"));
920 return NT_STATUS_INTERNAL_DB_CORRUPTION;
923 map->sid_name_use = SID_NAME_DOM_GRP;
925 ZERO_STRUCT(id_map);
926 id_map.sid = sid;
927 id_maps[0] = &id_map;
928 id_maps[1] = NULL;
930 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
931 talloc_free(tmp_ctx);
932 if (!NT_STATUS_IS_OK(status)) {
933 talloc_free(tmp_ctx);
934 return status;
936 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
937 map->gid = id_map.xid.id;
938 } else {
939 DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
940 talloc_free(tmp_ctx);
941 return NT_STATUS_INTERNAL_DB_CORRUPTION;
943 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
944 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
945 talloc_free(tmp_ctx);
946 return NT_STATUS_INTERNAL_DB_CORRUPTION;
949 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
950 NULL);
951 if (str == NULL) {
952 talloc_free(tmp_ctx);
953 return NT_STATUS_INTERNAL_DB_CORRUPTION;
955 map->nt_name = talloc_strdup(map, str);
956 if (!map->nt_name) {
957 talloc_free(tmp_ctx);
958 return NT_STATUS_NO_MEMORY;
961 str = ldb_msg_find_attr_as_string(msg, "description",
962 NULL);
963 if (str != NULL) {
964 map->comment = talloc_strdup(map, str);
965 } else {
966 map->comment = talloc_strdup(map, "");
968 if (!map->comment) {
969 talloc_free(tmp_ctx);
970 return NT_STATUS_NO_MEMORY;
973 talloc_free(tmp_ctx);
974 return NT_STATUS_OK;
977 static NTSTATUS pdb_samba_dsdb_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
978 struct dom_sid sid)
980 char *filter;
981 NTSTATUS status;
983 filter = talloc_asprintf(talloc_tos(),
984 "(&(objectsid=%s)(objectclass=group))",
985 sid_string_talloc(talloc_tos(), &sid));
986 if (filter == NULL) {
987 return NT_STATUS_NO_MEMORY;
990 status = pdb_samba_dsdb_getgrfilter(m, map, filter);
991 TALLOC_FREE(filter);
992 return status;
995 static NTSTATUS pdb_samba_dsdb_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
996 gid_t gid)
998 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
999 m->private_data, struct pdb_samba_dsdb_state);
1000 NTSTATUS status;
1001 struct id_map id_map;
1002 struct id_map *id_maps[2];
1003 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1004 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1006 id_map.xid.id = gid;
1007 id_map.xid.type = ID_TYPE_GID;
1008 id_maps[0] = &id_map;
1009 id_maps[1] = NULL;
1011 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1012 if (!NT_STATUS_IS_OK(status)) {
1013 return status;
1015 status = pdb_samba_dsdb_getgrsid(m, map, *id_map.sid);
1016 talloc_free(tmp_ctx);
1017 return status;
1020 static NTSTATUS pdb_samba_dsdb_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
1021 const char *name)
1023 char *filter;
1024 NTSTATUS status;
1026 filter = talloc_asprintf(talloc_tos(),
1027 "(&(samaccountname=%s)(objectclass=group))",
1028 name);
1029 if (filter == NULL) {
1030 return NT_STATUS_NO_MEMORY;
1033 status = pdb_samba_dsdb_getgrfilter(m, map, filter);
1034 TALLOC_FREE(filter);
1035 return status;
1038 static NTSTATUS pdb_samba_dsdb_create_dom_group(struct pdb_methods *m,
1039 TALLOC_CTX *mem_ctx, const char *name,
1040 uint32 *rid)
1042 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1043 m->private_data, struct pdb_samba_dsdb_state);
1044 NTSTATUS status;
1045 struct dom_sid *sid;
1046 struct ldb_dn *dn;
1047 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1048 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1050 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1051 if (!NT_STATUS_IS_OK(status)) {
1052 talloc_free(tmp_ctx);
1053 return status;
1056 sid_peek_rid(sid, rid);
1057 talloc_free(tmp_ctx);
1058 return NT_STATUS_OK;
1061 static NTSTATUS pdb_samba_dsdb_delete_dom_group(struct pdb_methods *m,
1062 TALLOC_CTX *mem_ctx, uint32 rid)
1064 const char *attrs[] = { NULL };
1065 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1066 m->private_data, struct pdb_samba_dsdb_state);
1067 struct dom_sid sid;
1068 struct ldb_message *msg;
1069 struct ldb_dn *dn;
1070 int rc;
1071 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1072 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1074 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1076 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1077 DEBUG(0, ("Unable to start transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1078 return NT_STATUS_INTERNAL_ERROR;
1081 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1082 if (!dn || !ldb_dn_validate(dn)) {
1083 talloc_free(tmp_ctx);
1084 ldb_transaction_cancel(state->ldb);
1085 return NT_STATUS_NO_MEMORY;
1087 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1088 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1089 talloc_free(tmp_ctx);
1090 ldb_transaction_cancel(state->ldb);
1091 return NT_STATUS_NO_SUCH_GROUP;
1093 rc = ldb_delete(state->ldb, dn);
1094 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1095 talloc_free(tmp_ctx);
1096 ldb_transaction_cancel(state->ldb);
1097 return NT_STATUS_NO_SUCH_GROUP;
1098 } else if (rc != LDB_SUCCESS) {
1099 DEBUG(10, ("ldb_delete failed %s\n",
1100 ldb_errstring(state->ldb)));
1101 ldb_transaction_cancel(state->ldb);
1102 return NT_STATUS_LDAP(rc);
1105 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1106 DEBUG(0, ("Unable to commit transaction in pdb_samba_dsdb_delete_dom_group()\n"));
1107 return NT_STATUS_INTERNAL_ERROR;
1109 return NT_STATUS_OK;
1112 static NTSTATUS pdb_samba_dsdb_add_group_mapping_entry(struct pdb_methods *m,
1113 GROUP_MAP *map)
1115 return NT_STATUS_NOT_IMPLEMENTED;
1118 static NTSTATUS pdb_samba_dsdb_update_group_mapping_entry(struct pdb_methods *m,
1119 GROUP_MAP *map)
1121 return NT_STATUS_NOT_IMPLEMENTED;
1124 static NTSTATUS pdb_samba_dsdb_delete_group_mapping_entry(struct pdb_methods *m,
1125 struct dom_sid sid)
1127 return NT_STATUS_NOT_IMPLEMENTED;
1130 static NTSTATUS pdb_samba_dsdb_enum_group_mapping(struct pdb_methods *m,
1131 const struct dom_sid *sid,
1132 enum lsa_SidType sid_name_use,
1133 GROUP_MAP ***pp_rmap,
1134 size_t *p_num_entries,
1135 bool unix_only)
1137 return NT_STATUS_NOT_IMPLEMENTED;
1140 static NTSTATUS pdb_samba_dsdb_enum_group_members(struct pdb_methods *m,
1141 TALLOC_CTX *mem_ctx,
1142 const struct dom_sid *group,
1143 uint32_t **pmembers,
1144 size_t *pnum_members)
1146 unsigned int i, num_sids, num_members;
1147 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1148 m->private_data, struct pdb_samba_dsdb_state);
1149 struct dom_sid *members_as_sids;
1150 struct dom_sid *dom_sid;
1151 uint32_t *members;
1152 struct ldb_dn *dn;
1153 NTSTATUS status;
1155 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1156 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1158 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1159 if (!dn || !ldb_dn_validate(dn)) {
1160 return NT_STATUS_NO_MEMORY;
1163 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1164 if (!NT_STATUS_IS_OK(status)) {
1165 talloc_free(tmp_ctx);
1166 return status;
1168 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1169 if (!NT_STATUS_IS_OK(status)) {
1170 talloc_free(tmp_ctx);
1171 return status;
1174 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1175 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1176 num_members = 0;
1178 for (i = 0; i < num_sids; i++) {
1179 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1180 continue;
1182 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1183 NULL, &members[num_members]);
1184 if (!NT_STATUS_IS_OK(status)) {
1185 talloc_free(tmp_ctx);
1186 return status;
1188 num_members++;
1190 *pnum_members = num_members;
1191 return NT_STATUS_OK;
1194 /* Just convert the primary group SID into a group */
1195 static NTSTATUS fake_enum_group_memberships(struct pdb_samba_dsdb_state *state,
1196 TALLOC_CTX *mem_ctx,
1197 struct samu *user,
1198 struct dom_sid **pp_sids,
1199 gid_t **pp_gids,
1200 uint32_t *p_num_groups)
1202 NTSTATUS status;
1203 size_t num_groups = 0;
1204 struct dom_sid *group_sids = NULL;
1205 gid_t *gids = NULL;
1206 TALLOC_CTX *tmp_ctx;
1208 tmp_ctx = talloc_new(mem_ctx);
1209 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1211 if (user->group_sid) {
1212 struct id_map *id_maps[2];
1213 struct id_map id_map;
1215 num_groups = 1;
1217 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1218 if (group_sids == NULL) {
1219 talloc_free(tmp_ctx);
1220 return NT_STATUS_NO_MEMORY;
1222 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1223 if (gids == NULL) {
1224 talloc_free(tmp_ctx);
1225 return NT_STATUS_NO_MEMORY;
1228 group_sids[0] = *user->group_sid;
1230 ZERO_STRUCT(id_map);
1231 id_map.sid = &group_sids[0];
1232 id_maps[0] = &id_map;
1233 id_maps[1] = NULL;
1235 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1236 if (!NT_STATUS_IS_OK(status)) {
1237 talloc_free(tmp_ctx);
1238 return status;
1240 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1241 gids[0] = id_map.xid.id;
1242 } else {
1243 DEBUG(1, (__location__
1244 "Group %s, of which %s is a member, could not be converted to a GID\n",
1245 dom_sid_string(tmp_ctx, &group_sids[0]),
1246 dom_sid_string(tmp_ctx, &user->user_sid)));
1247 talloc_free(tmp_ctx);
1248 /* We must error out, otherwise a user might
1249 * avoid a DENY acl based on a group they
1250 * missed out on */
1251 return NT_STATUS_NO_SUCH_GROUP;
1255 *pp_sids = talloc_steal(mem_ctx, group_sids);
1256 *pp_gids = talloc_steal(mem_ctx, gids);
1257 *p_num_groups = num_groups;
1258 talloc_free(tmp_ctx);
1259 return NT_STATUS_OK;
1262 static NTSTATUS pdb_samba_dsdb_enum_group_memberships(struct pdb_methods *m,
1263 TALLOC_CTX *mem_ctx,
1264 struct samu *user,
1265 struct dom_sid **pp_sids,
1266 gid_t **pp_gids,
1267 uint32_t *p_num_groups)
1269 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1270 m->private_data, struct pdb_samba_dsdb_state);
1271 struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
1272 m, user);
1273 const char *attrs[] = { "tokenGroups", NULL};
1274 struct ldb_message *tokengroups_msg;
1275 struct ldb_message_element *tokengroups;
1276 int i, rc;
1277 NTSTATUS status;
1278 unsigned int count = 0;
1279 size_t num_groups;
1280 struct dom_sid *group_sids;
1281 gid_t *gids;
1282 TALLOC_CTX *tmp_ctx;
1284 if (msg == NULL) {
1285 /* Fake up some things here */
1286 return fake_enum_group_memberships(state,
1287 mem_ctx,
1288 user, pp_sids,
1289 pp_gids, p_num_groups);
1292 tmp_ctx = talloc_new(mem_ctx);
1293 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1295 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1297 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1298 talloc_free(tmp_ctx);
1299 return NT_STATUS_NO_SUCH_USER;
1300 } else if (rc != LDB_SUCCESS) {
1301 DEBUG(10, ("dsdb_search_one failed %s\n",
1302 ldb_errstring(state->ldb)));
1303 talloc_free(tmp_ctx);
1304 return NT_STATUS_LDAP(rc);
1307 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1309 if (tokengroups) {
1310 count = tokengroups->num_values;
1313 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1314 if (group_sids == NULL) {
1315 talloc_free(tmp_ctx);
1316 return NT_STATUS_NO_MEMORY;
1318 gids = talloc_array(tmp_ctx, gid_t, count);
1319 if (gids == NULL) {
1320 talloc_free(tmp_ctx);
1321 return NT_STATUS_NO_MEMORY;
1323 num_groups = 0;
1325 for (i=0; i<count; i++) {
1326 struct id_map *id_maps[2];
1327 struct id_map id_map;
1328 struct ldb_val *v = &tokengroups->values[i];
1329 enum ndr_err_code ndr_err
1330 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1331 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1332 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1333 talloc_free(tmp_ctx);
1334 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1337 ZERO_STRUCT(id_map);
1338 id_map.sid = &group_sids[num_groups];
1339 id_maps[0] = &id_map;
1340 id_maps[1] = NULL;
1342 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1343 if (!NT_STATUS_IS_OK(status)) {
1344 talloc_free(tmp_ctx);
1345 return status;
1347 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1348 gids[num_groups] = id_map.xid.id;
1349 } else {
1350 DEBUG(1, (__location__
1351 "Group %s, of which %s is a member, could not be converted to a GID\n",
1352 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1353 ldb_dn_get_linearized(msg->dn)));
1354 talloc_free(tmp_ctx);
1355 /* We must error out, otherwise a user might
1356 * avoid a DENY acl based on a group they
1357 * missed out on */
1358 return NT_STATUS_NO_SUCH_GROUP;
1361 num_groups += 1;
1362 if (num_groups == count) {
1363 break;
1367 *pp_sids = talloc_steal(mem_ctx, group_sids);
1368 *pp_gids = talloc_steal(mem_ctx, gids);
1369 *p_num_groups = num_groups;
1370 talloc_free(tmp_ctx);
1371 return NT_STATUS_OK;
1374 static NTSTATUS pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods *m,
1375 TALLOC_CTX *mem_ctx,
1376 struct samu *user)
1378 return NT_STATUS_NOT_IMPLEMENTED;
1381 static NTSTATUS pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods *m,
1382 TALLOC_CTX *mem_ctx,
1383 const struct dom_sid *groupsid,
1384 const struct dom_sid *membersid,
1385 int mod_op)
1387 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1388 m->private_data, struct pdb_samba_dsdb_state);
1389 struct ldb_message *msg;
1390 int ret;
1391 struct ldb_message_element *el;
1392 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1393 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1394 msg = ldb_msg_new(tmp_ctx);
1395 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1397 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1398 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1399 talloc_free(tmp_ctx);
1400 return NT_STATUS_NO_MEMORY;
1402 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1403 if (ret != LDB_SUCCESS) {
1404 talloc_free(tmp_ctx);
1405 return NT_STATUS_NO_MEMORY;
1407 el = ldb_msg_find_element(msg, "member");
1408 el->flags = mod_op;
1410 /* No need for transactions here, the ldb auto-transaction
1411 * code will handle things for the single operation */
1412 ret = ldb_modify(state->ldb, msg);
1413 talloc_free(tmp_ctx);
1414 if (ret != LDB_SUCCESS) {
1415 DEBUG(10, ("ldb_modify failed: %s\n",
1416 ldb_errstring(state->ldb)));
1417 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1418 return NT_STATUS_MEMBER_IN_GROUP;
1420 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1421 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1423 return NT_STATUS_LDAP(ret);
1426 return NT_STATUS_OK;
1429 static NTSTATUS pdb_samba_dsdb_mod_groupmem(struct pdb_methods *m,
1430 TALLOC_CTX *mem_ctx,
1431 uint32 grouprid, uint32 memberrid,
1432 int mod_op)
1434 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1435 m->private_data, struct pdb_samba_dsdb_state);
1436 const struct dom_sid *dom_sid, *groupsid, *membersid;
1437 NTSTATUS status;
1438 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1439 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1441 dom_sid = samdb_domain_sid(state->ldb);
1443 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1444 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1445 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1446 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1447 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1448 talloc_free(tmp_ctx);
1449 return status;
1452 static NTSTATUS pdb_samba_dsdb_add_groupmem(struct pdb_methods *m,
1453 TALLOC_CTX *mem_ctx,
1454 uint32 group_rid, uint32 member_rid)
1456 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1457 LDB_FLAG_MOD_ADD);
1460 static NTSTATUS pdb_samba_dsdb_del_groupmem(struct pdb_methods *m,
1461 TALLOC_CTX *mem_ctx,
1462 uint32 group_rid, uint32 member_rid)
1464 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1465 LDB_FLAG_MOD_DELETE);
1468 static NTSTATUS pdb_samba_dsdb_create_alias(struct pdb_methods *m,
1469 const char *name, uint32 *rid)
1471 TALLOC_CTX *frame = talloc_stackframe();
1472 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1473 m->private_data, struct pdb_samba_dsdb_state);
1474 struct dom_sid *sid;
1476 struct ldb_dn *dn;
1477 NTSTATUS status;
1479 /* Internally this uses transactions to ensure all the steps
1480 * happen or fail as one */
1481 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1482 if (!NT_STATUS_IS_OK(status)) {
1483 TALLOC_FREE(frame);
1486 sid_peek_rid(sid, rid);
1487 TALLOC_FREE(frame);
1488 return NT_STATUS_OK;
1491 static NTSTATUS pdb_samba_dsdb_delete_alias(struct pdb_methods *m,
1492 const struct dom_sid *sid)
1494 const char *attrs[] = { NULL };
1495 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1496 m->private_data, struct pdb_samba_dsdb_state);
1497 struct ldb_message *msg;
1498 struct ldb_dn *dn;
1499 int rc;
1500 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1501 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1503 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1504 if (!dn || !ldb_dn_validate(dn)) {
1505 talloc_free(tmp_ctx);
1506 return NT_STATUS_NO_MEMORY;
1509 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1510 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1511 return NT_STATUS_INTERNAL_ERROR;
1514 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1515 "(|(grouptype=%d)(grouptype=%d)))",
1516 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1517 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1518 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1519 talloc_free(tmp_ctx);
1520 ldb_transaction_cancel(state->ldb);
1521 return NT_STATUS_NO_SUCH_ALIAS;
1523 rc = ldb_delete(state->ldb, dn);
1524 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1525 talloc_free(tmp_ctx);
1526 ldb_transaction_cancel(state->ldb);
1527 return NT_STATUS_NO_SUCH_ALIAS;
1528 } else if (rc != LDB_SUCCESS) {
1529 DEBUG(10, ("ldb_delete failed %s\n",
1530 ldb_errstring(state->ldb)));
1531 ldb_transaction_cancel(state->ldb);
1532 return NT_STATUS_LDAP(rc);
1535 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1536 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1537 ldb_errstring(state->ldb)));
1538 return NT_STATUS_INTERNAL_ERROR;
1541 return NT_STATUS_OK;
1544 #if 0
1545 static NTSTATUS pdb_samba_dsdb_set_aliasinfo(struct pdb_methods *m,
1546 const struct dom_sid *sid,
1547 struct acct_info *info)
1549 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1550 m->private_data, struct pdb_samba_dsdb_state);
1551 struct tldap_context *ld;
1552 const char *attrs[3] = { "objectSid", "description",
1553 "samAccountName" };
1554 struct ldb_message **msg;
1555 char *sidstr, *dn;
1556 int rc;
1557 struct tldap_mod *mods;
1558 int num_mods;
1559 bool ok;
1561 ld = pdb_samba_dsdb_ld(state);
1562 if (ld == NULL) {
1563 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1566 sidstr = sid_binstring(talloc_tos(), sid);
1567 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1569 rc = pdb_samba_dsdb_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1570 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1571 &msg, "(&(objectSid=%s)(objectclass=group)"
1572 "(|(grouptype=%d)(grouptype=%d)))",
1573 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1574 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1575 TALLOC_FREE(sidstr)
1576 if (rc != LDB_SUCCESS) {
1577 DEBUG(10, ("ldap_search failed %s\n",
1578 ldb_errstring(state->ldb)));
1579 return NT_STATUS_LDAP(rc);
1581 switch talloc_array_length(msg) {
1582 case 0:
1583 return NT_STATUS_NO_SUCH_ALIAS;
1584 case 1:
1585 break;
1586 default:
1587 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1590 if (!tldap_entry_dn(msg[0], &dn)) {
1591 TALLOC_FREE(msg);
1592 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1595 mods = NULL;
1596 num_mods = 0;
1597 ok = true;
1599 ok &= tldap_make_mod_fmt(
1600 msg[0], msg, &num_mods, &mods, "description",
1601 "%s", info->acct_desc);
1602 ok &= tldap_make_mod_fmt(
1603 msg[0], msg, &num_mods, &mods, "samAccountName",
1604 "%s", info->acct_name);
1605 if (!ok) {
1606 TALLOC_FREE(msg);
1607 return NT_STATUS_NO_MEMORY;
1609 if (num_mods == 0) {
1610 /* no change */
1611 TALLOC_FREE(msg);
1612 return NT_STATUS_OK;
1615 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1616 TALLOC_FREE(msg);
1617 if (rc != LDB_SUCCESS) {
1618 DEBUG(10, ("ldap_modify failed: %s\n",
1619 ldb_errstring(state->ldb)));
1620 return NT_STATUS_LDAP(rc);
1622 return NT_STATUS_OK;
1624 #endif
1625 static NTSTATUS pdb_samba_dsdb_add_aliasmem(struct pdb_methods *m,
1626 const struct dom_sid *alias,
1627 const struct dom_sid *member)
1629 NTSTATUS status;
1630 TALLOC_CTX *frame = talloc_stackframe();
1631 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1632 talloc_free(frame);
1633 return status;
1636 static NTSTATUS pdb_samba_dsdb_del_aliasmem(struct pdb_methods *m,
1637 const struct dom_sid *alias,
1638 const struct dom_sid *member)
1640 NTSTATUS status;
1641 TALLOC_CTX *frame = talloc_stackframe();
1642 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1643 talloc_free(frame);
1644 return status;
1647 static NTSTATUS pdb_samba_dsdb_enum_aliasmem(struct pdb_methods *m,
1648 const struct dom_sid *alias,
1649 TALLOC_CTX *mem_ctx,
1650 struct dom_sid **pmembers,
1651 size_t *pnum_members)
1653 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1654 m->private_data, struct pdb_samba_dsdb_state);
1655 struct ldb_dn *dn;
1656 unsigned int num_members;
1657 NTSTATUS status;
1658 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1659 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1661 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1662 if (!dn || !ldb_dn_validate(dn)) {
1663 return NT_STATUS_NO_MEMORY;
1666 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1667 *pnum_members = num_members;
1668 if (NT_STATUS_IS_OK(status)) {
1669 talloc_steal(mem_ctx, pmembers);
1671 talloc_free(tmp_ctx);
1672 return status;
1675 static NTSTATUS pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods *m,
1676 TALLOC_CTX *mem_ctx,
1677 const struct dom_sid *domain_sid,
1678 const struct dom_sid *members,
1679 size_t num_members,
1680 uint32_t **palias_rids,
1681 size_t *pnum_alias_rids)
1683 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1684 m->private_data, struct pdb_samba_dsdb_state);
1685 uint32_t *alias_rids = NULL;
1686 size_t num_alias_rids = 0;
1687 int i;
1688 struct dom_sid *groupSIDs = NULL;
1689 unsigned int num_groupSIDs = 0;
1690 char *filter;
1691 NTSTATUS status;
1692 const char *sid_string;
1693 const char *sid_dn;
1694 DATA_BLOB sid_blob;
1696 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1697 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1699 * TODO: Get the filter right so that we only get the aliases from
1700 * either the SAM or BUILTIN
1703 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1704 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1705 if (filter == NULL) {
1706 return NT_STATUS_NO_MEMORY;
1709 for (i = 0; i < num_members; i++) {
1710 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1711 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1713 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1714 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1716 sid_blob = data_blob_string_const(sid_dn);
1718 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1719 tmp_ctx, &groupSIDs, &num_groupSIDs);
1720 if (!NT_STATUS_IS_OK(status)) {
1721 talloc_free(tmp_ctx);
1722 return status;
1726 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1727 if (alias_rids == NULL) {
1728 talloc_free(tmp_ctx);
1729 return NT_STATUS_NO_MEMORY;
1732 for (i=0; i<num_groupSIDs; i++) {
1733 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1734 &alias_rids[num_alias_rids])) {
1735 num_alias_rids++;;
1739 *palias_rids = alias_rids;
1740 *pnum_alias_rids = num_alias_rids;
1741 return NT_STATUS_OK;
1744 static NTSTATUS pdb_samba_dsdb_lookup_rids(struct pdb_methods *m,
1745 const struct dom_sid *domain_sid,
1746 int num_rids,
1747 uint32 *rids,
1748 const char **names,
1749 enum lsa_SidType *lsa_attrs)
1751 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1752 m->private_data, struct pdb_samba_dsdb_state);
1753 NTSTATUS status;
1755 TALLOC_CTX *tmp_ctx;
1757 if (num_rids == 0) {
1758 return NT_STATUS_NONE_MAPPED;
1761 tmp_ctx = talloc_stackframe();
1762 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1764 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1765 talloc_free(tmp_ctx);
1766 return status;
1769 static NTSTATUS pdb_samba_dsdb_lookup_names(struct pdb_methods *m,
1770 const struct dom_sid *domain_sid,
1771 int num_names,
1772 const char **pp_names,
1773 uint32 *rids,
1774 enum lsa_SidType *attrs)
1776 return NT_STATUS_NOT_IMPLEMENTED;
1779 static NTSTATUS pdb_samba_dsdb_get_account_policy(struct pdb_methods *m,
1780 enum pdb_policy_type type,
1781 uint32_t *value)
1783 return account_policy_get(type, value)
1784 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1787 static NTSTATUS pdb_samba_dsdb_set_account_policy(struct pdb_methods *m,
1788 enum pdb_policy_type type,
1789 uint32_t value)
1791 return account_policy_set(type, value)
1792 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1795 static NTSTATUS pdb_samba_dsdb_get_seq_num(struct pdb_methods *m,
1796 time_t *seq_num_out)
1798 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1799 m->private_data, struct pdb_samba_dsdb_state);
1800 uint64_t seq_num;
1801 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1802 if (ret == LDB_SUCCESS) {
1803 *seq_num_out = seq_num;
1804 return NT_STATUS_OK;
1805 } else {
1806 return NT_STATUS_UNSUCCESSFUL;
1810 struct pdb_samba_dsdb_search_state {
1811 uint32_t acct_flags;
1812 struct samr_displayentry *entries;
1813 uint32_t num_entries;
1814 ssize_t array_size;
1815 uint32_t current;
1818 static bool pdb_samba_dsdb_next_entry(struct pdb_search *search,
1819 struct samr_displayentry *entry)
1821 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1822 search->private_data, struct pdb_samba_dsdb_search_state);
1824 if (state->current == state->num_entries) {
1825 return false;
1828 entry->idx = state->entries[state->current].idx;
1829 entry->rid = state->entries[state->current].rid;
1830 entry->acct_flags = state->entries[state->current].acct_flags;
1832 entry->account_name = talloc_strdup(
1833 search, state->entries[state->current].account_name);
1834 entry->fullname = talloc_strdup(
1835 search, state->entries[state->current].fullname);
1836 entry->description = talloc_strdup(
1837 search, state->entries[state->current].description);
1839 state->current += 1;
1840 return true;
1843 static void pdb_samba_dsdb_search_end(struct pdb_search *search)
1845 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1846 search->private_data, struct pdb_samba_dsdb_search_state);
1847 talloc_free(state);
1850 static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
1851 struct pdb_search *search,
1852 struct pdb_samba_dsdb_search_state **pstate,
1853 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1855 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1856 m->private_data, struct pdb_samba_dsdb_state);
1857 struct pdb_samba_dsdb_search_state *sstate;
1858 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1859 "userAccountControl", "description", NULL };
1860 struct ldb_result *res;
1861 int i, rc, num_users;
1863 va_list ap;
1864 char *expression = NULL;
1866 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1867 if (!tmp_ctx) {
1868 return false;
1871 va_start(ap, exp_fmt);
1872 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1873 va_end(ap);
1875 if (!expression) {
1876 talloc_free(tmp_ctx);
1877 return LDB_ERR_OPERATIONS_ERROR;
1880 sstate = talloc_zero(tmp_ctx, struct pdb_samba_dsdb_search_state);
1881 if (sstate == NULL) {
1882 talloc_free(tmp_ctx);
1883 return false;
1886 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1887 if (rc != LDB_SUCCESS) {
1888 talloc_free(tmp_ctx);
1889 DEBUG(10, ("dsdb_search failed: %s\n",
1890 ldb_errstring(state->ldb)));
1891 return false;
1894 num_users = res->count;
1896 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1897 num_users);
1898 if (sstate->entries == NULL) {
1899 talloc_free(tmp_ctx);
1900 DEBUG(10, ("talloc failed\n"));
1901 return false;
1904 sstate->num_entries = 0;
1906 for (i=0; i<num_users; i++) {
1907 struct samr_displayentry *e;
1908 struct dom_sid *sid;
1910 e = &sstate->entries[sstate->num_entries];
1912 e->idx = sstate->num_entries;
1913 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1914 if (!sid) {
1915 talloc_free(tmp_ctx);
1916 DEBUG(10, ("Could not pull SID\n"));
1917 return false;
1919 sid_peek_rid(sid, &e->rid);
1921 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1922 res->msgs[i],
1923 ldb_get_default_basedn(state->ldb));
1924 e->account_name = ldb_msg_find_attr_as_string(
1925 res->msgs[i], "samAccountName", NULL);
1926 if (e->account_name == NULL) {
1927 talloc_free(tmp_ctx);
1928 return false;
1930 e->fullname = ldb_msg_find_attr_as_string(
1931 res->msgs[i], "displayName", "");
1932 e->description = ldb_msg_find_attr_as_string(
1933 res->msgs[i], "description", "");
1935 sstate->num_entries += 1;
1936 if (sstate->num_entries >= num_users) {
1937 break;
1940 talloc_steal(sstate->entries, res->msgs);
1941 search->private_data = talloc_steal(search, sstate);
1942 search->next_entry = pdb_samba_dsdb_next_entry;
1943 search->search_end = pdb_samba_dsdb_search_end;
1944 *pstate = sstate;
1945 talloc_free(tmp_ctx);
1946 return true;
1949 static bool pdb_samba_dsdb_search_users(struct pdb_methods *m,
1950 struct pdb_search *search,
1951 uint32 acct_flags)
1953 struct pdb_samba_dsdb_search_state *sstate;
1954 bool ret;
1956 ret = pdb_samba_dsdb_search_filter(m, search, &sstate, "(objectclass=user)");
1957 if (!ret) {
1958 return false;
1960 sstate->acct_flags = acct_flags;
1961 return true;
1964 static bool pdb_samba_dsdb_search_groups(struct pdb_methods *m,
1965 struct pdb_search *search)
1967 struct pdb_samba_dsdb_search_state *sstate;
1968 bool ret;
1970 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
1971 "(&(grouptype=%d)(objectclass=group))",
1972 GTYPE_SECURITY_GLOBAL_GROUP);
1973 if (!ret) {
1974 return false;
1976 sstate->acct_flags = 0;
1977 return true;
1980 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods *m,
1981 struct pdb_search *search,
1982 const struct dom_sid *sid)
1984 struct pdb_samba_dsdb_search_state *sstate;
1985 bool ret;
1987 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
1988 "(&(grouptype=%d)(objectclass=group))",
1989 sid_check_is_builtin(sid)
1990 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1991 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1992 if (!ret) {
1993 return false;
1995 sstate->acct_flags = 0;
1996 return true;
1999 static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods *m, uid_t uid,
2000 struct dom_sid *sid)
2002 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2003 m->private_data, struct pdb_samba_dsdb_state);
2004 NTSTATUS status;
2005 struct id_map id_map;
2006 struct id_map *id_maps[2];
2007 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2008 if (!tmp_ctx) {
2009 return false;
2012 id_map.xid.id = uid;
2013 id_map.xid.type = ID_TYPE_UID;
2014 id_maps[0] = &id_map;
2015 id_maps[1] = NULL;
2017 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2018 if (!NT_STATUS_IS_OK(status)) {
2019 talloc_free(tmp_ctx);
2020 return false;
2022 *sid = *id_map.sid;
2023 talloc_free(tmp_ctx);
2024 return true;
2027 static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods *m, gid_t gid,
2028 struct dom_sid *sid)
2030 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2031 m->private_data, struct pdb_samba_dsdb_state);
2032 NTSTATUS status;
2033 struct id_map id_map;
2034 struct id_map *id_maps[2];
2035 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2036 if (!tmp_ctx) {
2037 return false;
2040 id_map.xid.id = gid;
2041 id_map.xid.type = ID_TYPE_GID;
2042 id_maps[0] = &id_map;
2043 id_maps[1] = NULL;
2045 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2046 if (!NT_STATUS_IS_OK(status)) {
2047 return false;
2049 *sid = *id_map.sid;
2050 talloc_free(tmp_ctx);
2051 return true;
2054 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2055 struct unixid *id)
2057 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2058 m->private_data, struct pdb_samba_dsdb_state);
2059 struct id_map id_map;
2060 struct id_map *id_maps[2];
2061 NTSTATUS status;
2062 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2063 if (!tmp_ctx) {
2064 return false;
2067 ZERO_STRUCT(id_map);
2068 id_map.sid = discard_const_p(struct dom_sid, sid);
2069 id_maps[0] = &id_map;
2070 id_maps[1] = NULL;
2072 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2073 talloc_free(tmp_ctx);
2074 if (!NT_STATUS_IS_OK(status)) {
2075 return false;
2077 if (id_map.xid.type != ID_TYPE_NOT_SPECIFIED) {
2078 *id = id_map.xid;
2079 return true;
2081 return false;
2084 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods *m)
2086 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2089 static bool pdb_samba_dsdb_new_rid(struct pdb_methods *m, uint32 *rid)
2091 return false;
2094 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods *m,
2095 const char *domain, char** pwd,
2096 struct dom_sid *sid,
2097 time_t *pass_last_set_time)
2099 return false;
2102 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m,
2103 const char* domain, const char* pwd,
2104 const struct dom_sid *sid)
2106 return false;
2109 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods *m,
2110 const char *domain)
2112 return false;
2115 static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m,
2116 TALLOC_CTX *mem_ctx,
2117 uint32 *num_domains,
2118 struct trustdom_info ***domains)
2120 *num_domains = 0;
2121 *domains = NULL;
2122 return NT_STATUS_OK;
2125 static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods *m)
2127 return true;
2130 static void pdb_samba_dsdb_init_methods(struct pdb_methods *m)
2132 m->name = "samba_dsdb";
2133 m->get_domain_info = pdb_samba_dsdb_get_domain_info;
2134 m->getsampwnam = pdb_samba_dsdb_getsampwnam;
2135 m->getsampwsid = pdb_samba_dsdb_getsampwsid;
2136 m->create_user = pdb_samba_dsdb_create_user;
2137 m->delete_user = pdb_samba_dsdb_delete_user;
2138 m->add_sam_account = pdb_samba_dsdb_add_sam_account;
2139 m->update_sam_account = pdb_samba_dsdb_update_sam_account;
2140 m->delete_sam_account = pdb_samba_dsdb_delete_sam_account;
2141 m->rename_sam_account = pdb_samba_dsdb_rename_sam_account;
2142 m->update_login_attempts = pdb_samba_dsdb_update_login_attempts;
2143 m->getgrsid = pdb_samba_dsdb_getgrsid;
2144 m->getgrgid = pdb_samba_dsdb_getgrgid;
2145 m->getgrnam = pdb_samba_dsdb_getgrnam;
2146 m->create_dom_group = pdb_samba_dsdb_create_dom_group;
2147 m->delete_dom_group = pdb_samba_dsdb_delete_dom_group;
2148 m->add_group_mapping_entry = pdb_samba_dsdb_add_group_mapping_entry;
2149 m->update_group_mapping_entry = pdb_samba_dsdb_update_group_mapping_entry;
2150 m->delete_group_mapping_entry = pdb_samba_dsdb_delete_group_mapping_entry;
2151 m->enum_group_mapping = pdb_samba_dsdb_enum_group_mapping;
2152 m->enum_group_members = pdb_samba_dsdb_enum_group_members;
2153 m->enum_group_memberships = pdb_samba_dsdb_enum_group_memberships;
2154 m->set_unix_primary_group = pdb_samba_dsdb_set_unix_primary_group;
2155 m->add_groupmem = pdb_samba_dsdb_add_groupmem;
2156 m->del_groupmem = pdb_samba_dsdb_del_groupmem;
2157 m->create_alias = pdb_samba_dsdb_create_alias;
2158 m->delete_alias = pdb_samba_dsdb_delete_alias;
2159 m->get_aliasinfo = pdb_default_get_aliasinfo;
2160 m->add_aliasmem = pdb_samba_dsdb_add_aliasmem;
2161 m->del_aliasmem = pdb_samba_dsdb_del_aliasmem;
2162 m->enum_aliasmem = pdb_samba_dsdb_enum_aliasmem;
2163 m->enum_alias_memberships = pdb_samba_dsdb_enum_alias_memberships;
2164 m->lookup_rids = pdb_samba_dsdb_lookup_rids;
2165 m->lookup_names = pdb_samba_dsdb_lookup_names;
2166 m->get_account_policy = pdb_samba_dsdb_get_account_policy;
2167 m->set_account_policy = pdb_samba_dsdb_set_account_policy;
2168 m->get_seq_num = pdb_samba_dsdb_get_seq_num;
2169 m->search_users = pdb_samba_dsdb_search_users;
2170 m->search_groups = pdb_samba_dsdb_search_groups;
2171 m->search_aliases = pdb_samba_dsdb_search_aliases;
2172 m->uid_to_sid = pdb_samba_dsdb_uid_to_sid;
2173 m->gid_to_sid = pdb_samba_dsdb_gid_to_sid;
2174 m->sid_to_id = pdb_samba_dsdb_sid_to_id;
2175 m->capabilities = pdb_samba_dsdb_capabilities;
2176 m->new_rid = pdb_samba_dsdb_new_rid;
2177 m->get_trusteddom_pw = pdb_samba_dsdb_get_trusteddom_pw;
2178 m->set_trusteddom_pw = pdb_samba_dsdb_set_trusteddom_pw;
2179 m->del_trusteddom_pw = pdb_samba_dsdb_del_trusteddom_pw;
2180 m->enum_trusteddoms = pdb_samba_dsdb_enum_trusteddoms;
2181 m->is_responsible_for_wellknown =
2182 pdb_samba_dsdb_is_responsible_for_wellknown;
2185 static void free_private_data(void **vp)
2187 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2188 *vp, struct pdb_samba_dsdb_state);
2189 talloc_unlink(state, state->ldb);
2190 return;
2193 static NTSTATUS pdb_samba_dsdb_init_secrets(struct pdb_methods *m)
2195 struct pdb_domain_info *dom_info;
2196 bool ret;
2198 dom_info = pdb_samba_dsdb_get_domain_info(m, m);
2199 if (!dom_info) {
2200 return NT_STATUS_UNSUCCESSFUL;
2203 secrets_clear_domain_protection(dom_info->name);
2204 ret = secrets_store_domain_sid(dom_info->name,
2205 &dom_info->sid);
2206 if (!ret) {
2207 goto done;
2209 ret = secrets_store_domain_guid(dom_info->name,
2210 &dom_info->guid);
2211 if (!ret) {
2212 goto done;
2214 ret = secrets_mark_domain_protected(dom_info->name);
2215 if (!ret) {
2216 goto done;
2219 done:
2220 TALLOC_FREE(dom_info);
2221 if (!ret) {
2222 return NT_STATUS_UNSUCCESSFUL;
2224 return NT_STATUS_OK;
2227 static NTSTATUS pdb_init_samba_dsdb(struct pdb_methods **pdb_method,
2228 const char *location)
2230 struct pdb_methods *m;
2231 struct pdb_samba_dsdb_state *state;
2232 NTSTATUS status;
2234 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2235 return status;
2238 state = talloc_zero(m, struct pdb_samba_dsdb_state);
2239 if (state == NULL) {
2240 goto nomem;
2242 m->private_data = state;
2243 m->free_private_data = free_private_data;
2244 pdb_samba_dsdb_init_methods(m);
2246 state->ev = s4_event_context_init(state);
2247 if (!state->ev) {
2248 DEBUG(0, ("s4_event_context_init failed\n"));
2249 goto nomem;
2252 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_helpers());
2253 if (state->lp_ctx == NULL) {
2254 DEBUG(0, ("loadparm_init_s3 failed\n"));
2255 goto nomem;
2258 if (location) {
2259 state->ldb = samdb_connect_url(state,
2260 state->ev,
2261 state->lp_ctx,
2262 system_session(state->lp_ctx),
2263 0, location);
2264 } else {
2265 state->ldb = samdb_connect(state,
2266 state->ev,
2267 state->lp_ctx,
2268 system_session(state->lp_ctx), 0);
2271 if (!state->ldb) {
2272 DEBUG(0, ("samdb_connect failed\n"));
2273 status = NT_STATUS_INTERNAL_ERROR;
2274 goto fail;
2277 state->idmap_ctx = idmap_init(state, state->ev,
2278 state->lp_ctx);
2279 if (!state->idmap_ctx) {
2280 DEBUG(0, ("idmap failed\n"));
2281 status = NT_STATUS_INTERNAL_ERROR;
2282 goto fail;
2285 status = pdb_samba_dsdb_init_secrets(m);
2286 if (!NT_STATUS_IS_OK(status)) {
2287 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
2288 goto fail;
2291 *pdb_method = m;
2292 return NT_STATUS_OK;
2293 nomem:
2294 status = NT_STATUS_NO_MEMORY;
2295 fail:
2296 TALLOC_FREE(m);
2297 return status;
2300 NTSTATUS pdb_samba_dsdb_init(void);
2301 NTSTATUS pdb_samba_dsdb_init(void)
2303 NTSTATUS status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba_dsdb",
2304 pdb_init_samba_dsdb);
2305 if (!NT_STATUS_IS_OK(status)) {
2306 return status;
2308 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2309 pdb_init_samba_dsdb);