ctdb-vacuum: rename ctdb_vacuum_db_full --> ctdb_vacuum_traverse_db
[Samba.git] / source3 / passdb / pdb_samba_dsdb.c
blobdee20efbf84314b6258e47e978a43460bf721637
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 if (*pmembers == NULL) {
1176 TALLOC_FREE(tmp_ctx);
1177 return NT_STATUS_NO_MEMORY;
1179 num_members = 0;
1181 for (i = 0; i < num_sids; i++) {
1182 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1183 continue;
1185 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1186 NULL, &members[num_members]);
1187 if (!NT_STATUS_IS_OK(status)) {
1188 talloc_free(tmp_ctx);
1189 return status;
1191 num_members++;
1193 *pnum_members = num_members;
1194 return NT_STATUS_OK;
1197 /* Just convert the primary group SID into a group */
1198 static NTSTATUS fake_enum_group_memberships(struct pdb_samba_dsdb_state *state,
1199 TALLOC_CTX *mem_ctx,
1200 struct samu *user,
1201 struct dom_sid **pp_sids,
1202 gid_t **pp_gids,
1203 uint32_t *p_num_groups)
1205 NTSTATUS status;
1206 size_t num_groups = 0;
1207 struct dom_sid *group_sids = NULL;
1208 gid_t *gids = NULL;
1209 TALLOC_CTX *tmp_ctx;
1211 tmp_ctx = talloc_new(mem_ctx);
1212 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1214 if (user->group_sid) {
1215 struct id_map *id_maps[2];
1216 struct id_map id_map;
1218 num_groups = 1;
1220 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1221 if (group_sids == NULL) {
1222 talloc_free(tmp_ctx);
1223 return NT_STATUS_NO_MEMORY;
1225 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1226 if (gids == NULL) {
1227 talloc_free(tmp_ctx);
1228 return NT_STATUS_NO_MEMORY;
1231 group_sids[0] = *user->group_sid;
1233 ZERO_STRUCT(id_map);
1234 id_map.sid = &group_sids[0];
1235 id_maps[0] = &id_map;
1236 id_maps[1] = NULL;
1238 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1239 if (!NT_STATUS_IS_OK(status)) {
1240 talloc_free(tmp_ctx);
1241 return status;
1243 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1244 gids[0] = id_map.xid.id;
1245 } else {
1246 DEBUG(1, (__location__
1247 "Group %s, of which %s is a member, could not be converted to a GID\n",
1248 dom_sid_string(tmp_ctx, &group_sids[0]),
1249 dom_sid_string(tmp_ctx, &user->user_sid)));
1250 talloc_free(tmp_ctx);
1251 /* We must error out, otherwise a user might
1252 * avoid a DENY acl based on a group they
1253 * missed out on */
1254 return NT_STATUS_NO_SUCH_GROUP;
1258 *pp_sids = talloc_steal(mem_ctx, group_sids);
1259 *pp_gids = talloc_steal(mem_ctx, gids);
1260 *p_num_groups = num_groups;
1261 talloc_free(tmp_ctx);
1262 return NT_STATUS_OK;
1265 static NTSTATUS pdb_samba_dsdb_enum_group_memberships(struct pdb_methods *m,
1266 TALLOC_CTX *mem_ctx,
1267 struct samu *user,
1268 struct dom_sid **pp_sids,
1269 gid_t **pp_gids,
1270 uint32_t *p_num_groups)
1272 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1273 m->private_data, struct pdb_samba_dsdb_state);
1274 struct ldb_message *msg = pdb_samba_dsdb_get_samu_private(
1275 m, user);
1276 const char *attrs[] = { "tokenGroups", NULL};
1277 struct ldb_message *tokengroups_msg;
1278 struct ldb_message_element *tokengroups;
1279 int i, rc;
1280 NTSTATUS status;
1281 unsigned int count = 0;
1282 size_t num_groups;
1283 struct dom_sid *group_sids;
1284 gid_t *gids;
1285 TALLOC_CTX *tmp_ctx;
1287 if (msg == NULL) {
1288 /* Fake up some things here */
1289 return fake_enum_group_memberships(state,
1290 mem_ctx,
1291 user, pp_sids,
1292 pp_gids, p_num_groups);
1295 tmp_ctx = talloc_new(mem_ctx);
1296 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1298 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1300 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1301 talloc_free(tmp_ctx);
1302 return NT_STATUS_NO_SUCH_USER;
1303 } else if (rc != LDB_SUCCESS) {
1304 DEBUG(10, ("dsdb_search_one failed %s\n",
1305 ldb_errstring(state->ldb)));
1306 talloc_free(tmp_ctx);
1307 return NT_STATUS_LDAP(rc);
1310 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1312 if (tokengroups) {
1313 count = tokengroups->num_values;
1316 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1317 if (group_sids == NULL) {
1318 talloc_free(tmp_ctx);
1319 return NT_STATUS_NO_MEMORY;
1321 gids = talloc_array(tmp_ctx, gid_t, count);
1322 if (gids == NULL) {
1323 talloc_free(tmp_ctx);
1324 return NT_STATUS_NO_MEMORY;
1326 num_groups = 0;
1328 for (i=0; i<count; i++) {
1329 struct id_map *id_maps[2];
1330 struct id_map id_map;
1331 struct ldb_val *v = &tokengroups->values[i];
1332 enum ndr_err_code ndr_err
1333 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1334 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1335 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1336 talloc_free(tmp_ctx);
1337 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1340 ZERO_STRUCT(id_map);
1341 id_map.sid = &group_sids[num_groups];
1342 id_maps[0] = &id_map;
1343 id_maps[1] = NULL;
1345 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 talloc_free(tmp_ctx);
1348 return status;
1350 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1351 gids[num_groups] = id_map.xid.id;
1352 } else {
1353 DEBUG(1, (__location__
1354 "Group %s, of which %s is a member, could not be converted to a GID\n",
1355 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1356 ldb_dn_get_linearized(msg->dn)));
1357 talloc_free(tmp_ctx);
1358 /* We must error out, otherwise a user might
1359 * avoid a DENY acl based on a group they
1360 * missed out on */
1361 return NT_STATUS_NO_SUCH_GROUP;
1364 num_groups += 1;
1365 if (num_groups == count) {
1366 break;
1370 *pp_sids = talloc_steal(mem_ctx, group_sids);
1371 *pp_gids = talloc_steal(mem_ctx, gids);
1372 *p_num_groups = num_groups;
1373 talloc_free(tmp_ctx);
1374 return NT_STATUS_OK;
1377 static NTSTATUS pdb_samba_dsdb_set_unix_primary_group(struct pdb_methods *m,
1378 TALLOC_CTX *mem_ctx,
1379 struct samu *user)
1381 return NT_STATUS_NOT_IMPLEMENTED;
1384 static NTSTATUS pdb_samba_dsdb_mod_groupmem_by_sid(struct pdb_methods *m,
1385 TALLOC_CTX *mem_ctx,
1386 const struct dom_sid *groupsid,
1387 const struct dom_sid *membersid,
1388 int mod_op)
1390 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1391 m->private_data, struct pdb_samba_dsdb_state);
1392 struct ldb_message *msg;
1393 int ret;
1394 struct ldb_message_element *el;
1395 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1396 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1397 msg = ldb_msg_new(tmp_ctx);
1398 if (msg == NULL) {
1399 TALLOC_FREE(tmp_ctx);
1400 return NT_STATUS_NO_MEMORY;
1403 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1404 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1405 talloc_free(tmp_ctx);
1406 return NT_STATUS_NO_MEMORY;
1408 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1409 if (ret != LDB_SUCCESS) {
1410 talloc_free(tmp_ctx);
1411 return NT_STATUS_NO_MEMORY;
1413 el = ldb_msg_find_element(msg, "member");
1414 el->flags = mod_op;
1416 /* No need for transactions here, the ldb auto-transaction
1417 * code will handle things for the single operation */
1418 ret = ldb_modify(state->ldb, msg);
1419 talloc_free(tmp_ctx);
1420 if (ret != LDB_SUCCESS) {
1421 DEBUG(10, ("ldb_modify failed: %s\n",
1422 ldb_errstring(state->ldb)));
1423 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1424 return NT_STATUS_MEMBER_IN_GROUP;
1426 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1427 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1429 return NT_STATUS_LDAP(ret);
1432 return NT_STATUS_OK;
1435 static NTSTATUS pdb_samba_dsdb_mod_groupmem(struct pdb_methods *m,
1436 TALLOC_CTX *mem_ctx,
1437 uint32 grouprid, uint32 memberrid,
1438 int mod_op)
1440 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1441 m->private_data, struct pdb_samba_dsdb_state);
1442 const struct dom_sid *dom_sid, *groupsid, *membersid;
1443 NTSTATUS status;
1444 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1445 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1447 dom_sid = samdb_domain_sid(state->ldb);
1449 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1450 if (groupsid == NULL) {
1451 TALLOC_FREE(tmp_ctx);
1452 return NT_STATUS_NO_MEMORY;
1454 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1455 if (membersid == NULL) {
1456 TALLOC_FREE(tmp_ctx);
1457 return NT_STATUS_NO_MEMORY;
1459 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1460 talloc_free(tmp_ctx);
1461 return status;
1464 static NTSTATUS pdb_samba_dsdb_add_groupmem(struct pdb_methods *m,
1465 TALLOC_CTX *mem_ctx,
1466 uint32 group_rid, uint32 member_rid)
1468 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1469 LDB_FLAG_MOD_ADD);
1472 static NTSTATUS pdb_samba_dsdb_del_groupmem(struct pdb_methods *m,
1473 TALLOC_CTX *mem_ctx,
1474 uint32 group_rid, uint32 member_rid)
1476 return pdb_samba_dsdb_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1477 LDB_FLAG_MOD_DELETE);
1480 static NTSTATUS pdb_samba_dsdb_create_alias(struct pdb_methods *m,
1481 const char *name, uint32 *rid)
1483 TALLOC_CTX *frame = talloc_stackframe();
1484 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1485 m->private_data, struct pdb_samba_dsdb_state);
1486 struct dom_sid *sid;
1488 struct ldb_dn *dn;
1489 NTSTATUS status;
1491 /* Internally this uses transactions to ensure all the steps
1492 * happen or fail as one */
1493 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1494 if (!NT_STATUS_IS_OK(status)) {
1495 TALLOC_FREE(frame);
1498 sid_peek_rid(sid, rid);
1499 TALLOC_FREE(frame);
1500 return NT_STATUS_OK;
1503 static NTSTATUS pdb_samba_dsdb_delete_alias(struct pdb_methods *m,
1504 const struct dom_sid *sid)
1506 const char *attrs[] = { NULL };
1507 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1508 m->private_data, struct pdb_samba_dsdb_state);
1509 struct ldb_message *msg;
1510 struct ldb_dn *dn;
1511 int rc;
1512 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1513 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1515 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1516 if (!dn || !ldb_dn_validate(dn)) {
1517 talloc_free(tmp_ctx);
1518 return NT_STATUS_NO_MEMORY;
1521 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1522 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1523 return NT_STATUS_INTERNAL_ERROR;
1526 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1527 "(|(grouptype=%d)(grouptype=%d)))",
1528 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1529 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1530 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1531 talloc_free(tmp_ctx);
1532 ldb_transaction_cancel(state->ldb);
1533 return NT_STATUS_NO_SUCH_ALIAS;
1535 rc = ldb_delete(state->ldb, dn);
1536 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1537 talloc_free(tmp_ctx);
1538 ldb_transaction_cancel(state->ldb);
1539 return NT_STATUS_NO_SUCH_ALIAS;
1540 } else if (rc != LDB_SUCCESS) {
1541 DEBUG(10, ("ldb_delete failed %s\n",
1542 ldb_errstring(state->ldb)));
1543 ldb_transaction_cancel(state->ldb);
1544 return NT_STATUS_LDAP(rc);
1547 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1548 DEBUG(0, ("Failed to commit transaction in pdb_samba_dsdb_delete_alias(): %s\n",
1549 ldb_errstring(state->ldb)));
1550 return NT_STATUS_INTERNAL_ERROR;
1553 return NT_STATUS_OK;
1556 #if 0
1557 static NTSTATUS pdb_samba_dsdb_set_aliasinfo(struct pdb_methods *m,
1558 const struct dom_sid *sid,
1559 struct acct_info *info)
1561 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1562 m->private_data, struct pdb_samba_dsdb_state);
1563 struct tldap_context *ld;
1564 const char *attrs[3] = { "objectSid", "description",
1565 "samAccountName" };
1566 struct ldb_message **msg;
1567 char *sidstr, *dn;
1568 int rc;
1569 struct tldap_mod *mods;
1570 int num_mods;
1571 bool ok;
1573 ld = pdb_samba_dsdb_ld(state);
1574 if (ld == NULL) {
1575 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1578 sidstr = sid_binstring(talloc_tos(), sid);
1579 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1581 rc = pdb_samba_dsdb_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1582 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1583 &msg, "(&(objectSid=%s)(objectclass=group)"
1584 "(|(grouptype=%d)(grouptype=%d)))",
1585 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1586 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1587 TALLOC_FREE(sidstr)
1588 if (rc != LDB_SUCCESS) {
1589 DEBUG(10, ("ldap_search failed %s\n",
1590 ldb_errstring(state->ldb)));
1591 return NT_STATUS_LDAP(rc);
1593 switch talloc_array_length(msg) {
1594 case 0:
1595 return NT_STATUS_NO_SUCH_ALIAS;
1596 case 1:
1597 break;
1598 default:
1599 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1602 if (!tldap_entry_dn(msg[0], &dn)) {
1603 TALLOC_FREE(msg);
1604 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1607 mods = NULL;
1608 num_mods = 0;
1609 ok = true;
1611 ok &= tldap_make_mod_fmt(
1612 msg[0], msg, &num_mods, &mods, "description",
1613 "%s", info->acct_desc);
1614 ok &= tldap_make_mod_fmt(
1615 msg[0], msg, &num_mods, &mods, "samAccountName",
1616 "%s", info->acct_name);
1617 if (!ok) {
1618 TALLOC_FREE(msg);
1619 return NT_STATUS_NO_MEMORY;
1621 if (num_mods == 0) {
1622 /* no change */
1623 TALLOC_FREE(msg);
1624 return NT_STATUS_OK;
1627 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1628 TALLOC_FREE(msg);
1629 if (rc != LDB_SUCCESS) {
1630 DEBUG(10, ("ldap_modify failed: %s\n",
1631 ldb_errstring(state->ldb)));
1632 return NT_STATUS_LDAP(rc);
1634 return NT_STATUS_OK;
1636 #endif
1637 static NTSTATUS pdb_samba_dsdb_add_aliasmem(struct pdb_methods *m,
1638 const struct dom_sid *alias,
1639 const struct dom_sid *member)
1641 NTSTATUS status;
1642 TALLOC_CTX *frame = talloc_stackframe();
1643 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1644 talloc_free(frame);
1645 return status;
1648 static NTSTATUS pdb_samba_dsdb_del_aliasmem(struct pdb_methods *m,
1649 const struct dom_sid *alias,
1650 const struct dom_sid *member)
1652 NTSTATUS status;
1653 TALLOC_CTX *frame = talloc_stackframe();
1654 status = pdb_samba_dsdb_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1655 talloc_free(frame);
1656 return status;
1659 static NTSTATUS pdb_samba_dsdb_enum_aliasmem(struct pdb_methods *m,
1660 const struct dom_sid *alias,
1661 TALLOC_CTX *mem_ctx,
1662 struct dom_sid **pmembers,
1663 size_t *pnum_members)
1665 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1666 m->private_data, struct pdb_samba_dsdb_state);
1667 struct ldb_dn *dn;
1668 unsigned int num_members;
1669 NTSTATUS status;
1670 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1671 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1673 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1674 if (!dn || !ldb_dn_validate(dn)) {
1675 return NT_STATUS_NO_MEMORY;
1678 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1679 *pnum_members = num_members;
1680 if (NT_STATUS_IS_OK(status)) {
1681 talloc_steal(mem_ctx, pmembers);
1683 talloc_free(tmp_ctx);
1684 return status;
1687 static NTSTATUS pdb_samba_dsdb_enum_alias_memberships(struct pdb_methods *m,
1688 TALLOC_CTX *mem_ctx,
1689 const struct dom_sid *domain_sid,
1690 const struct dom_sid *members,
1691 size_t num_members,
1692 uint32_t **palias_rids,
1693 size_t *pnum_alias_rids)
1695 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1696 m->private_data, struct pdb_samba_dsdb_state);
1697 uint32_t *alias_rids = NULL;
1698 size_t num_alias_rids = 0;
1699 int i;
1700 struct dom_sid *groupSIDs = NULL;
1701 unsigned int num_groupSIDs = 0;
1702 char *filter;
1703 NTSTATUS status;
1704 const char *sid_string;
1705 const char *sid_dn;
1706 DATA_BLOB sid_blob;
1708 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1709 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1711 * TODO: Get the filter right so that we only get the aliases from
1712 * either the SAM or BUILTIN
1715 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1716 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1717 if (filter == NULL) {
1718 return NT_STATUS_NO_MEMORY;
1721 for (i = 0; i < num_members; i++) {
1722 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1723 if (sid_string == NULL) {
1724 TALLOC_FREE(tmp_ctx);
1725 return NT_STATUS_NO_MEMORY;
1728 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1729 if (sid_dn == NULL) {
1730 TALLOC_FREE(tmp_ctx);
1731 return NT_STATUS_NO_MEMORY;
1734 sid_blob = data_blob_string_const(sid_dn);
1736 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1737 tmp_ctx, &groupSIDs, &num_groupSIDs);
1738 if (!NT_STATUS_IS_OK(status)) {
1739 talloc_free(tmp_ctx);
1740 return status;
1744 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1745 if (alias_rids == NULL) {
1746 talloc_free(tmp_ctx);
1747 return NT_STATUS_NO_MEMORY;
1750 for (i=0; i<num_groupSIDs; i++) {
1751 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1752 &alias_rids[num_alias_rids])) {
1753 num_alias_rids++;;
1757 *palias_rids = alias_rids;
1758 *pnum_alias_rids = num_alias_rids;
1759 return NT_STATUS_OK;
1762 static NTSTATUS pdb_samba_dsdb_lookup_rids(struct pdb_methods *m,
1763 const struct dom_sid *domain_sid,
1764 int num_rids,
1765 uint32 *rids,
1766 const char **names,
1767 enum lsa_SidType *lsa_attrs)
1769 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1770 m->private_data, struct pdb_samba_dsdb_state);
1771 NTSTATUS status;
1773 TALLOC_CTX *tmp_ctx;
1775 if (num_rids == 0) {
1776 return NT_STATUS_NONE_MAPPED;
1779 tmp_ctx = talloc_stackframe();
1780 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1782 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1783 talloc_free(tmp_ctx);
1784 return status;
1787 static NTSTATUS pdb_samba_dsdb_lookup_names(struct pdb_methods *m,
1788 const struct dom_sid *domain_sid,
1789 int num_names,
1790 const char **pp_names,
1791 uint32 *rids,
1792 enum lsa_SidType *attrs)
1794 return NT_STATUS_NOT_IMPLEMENTED;
1797 static NTSTATUS pdb_samba_dsdb_get_account_policy(struct pdb_methods *m,
1798 enum pdb_policy_type type,
1799 uint32_t *value)
1801 return account_policy_get(type, value)
1802 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1805 static NTSTATUS pdb_samba_dsdb_set_account_policy(struct pdb_methods *m,
1806 enum pdb_policy_type type,
1807 uint32_t value)
1809 return account_policy_set(type, value)
1810 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1813 static NTSTATUS pdb_samba_dsdb_get_seq_num(struct pdb_methods *m,
1814 time_t *seq_num_out)
1816 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1817 m->private_data, struct pdb_samba_dsdb_state);
1818 uint64_t seq_num;
1819 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1820 if (ret == LDB_SUCCESS) {
1821 *seq_num_out = seq_num;
1822 return NT_STATUS_OK;
1823 } else {
1824 return NT_STATUS_UNSUCCESSFUL;
1828 struct pdb_samba_dsdb_search_state {
1829 uint32_t acct_flags;
1830 struct samr_displayentry *entries;
1831 uint32_t num_entries;
1832 ssize_t array_size;
1833 uint32_t current;
1836 static bool pdb_samba_dsdb_next_entry(struct pdb_search *search,
1837 struct samr_displayentry *entry)
1839 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1840 search->private_data, struct pdb_samba_dsdb_search_state);
1842 if (state->current == state->num_entries) {
1843 return false;
1846 entry->idx = state->entries[state->current].idx;
1847 entry->rid = state->entries[state->current].rid;
1848 entry->acct_flags = state->entries[state->current].acct_flags;
1850 entry->account_name = talloc_strdup(
1851 search, state->entries[state->current].account_name);
1852 entry->fullname = talloc_strdup(
1853 search, state->entries[state->current].fullname);
1854 entry->description = talloc_strdup(
1855 search, state->entries[state->current].description);
1857 state->current += 1;
1858 return true;
1861 static void pdb_samba_dsdb_search_end(struct pdb_search *search)
1863 struct pdb_samba_dsdb_search_state *state = talloc_get_type_abort(
1864 search->private_data, struct pdb_samba_dsdb_search_state);
1865 talloc_free(state);
1868 static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
1869 struct pdb_search *search,
1870 struct pdb_samba_dsdb_search_state **pstate,
1871 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1873 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
1874 m->private_data, struct pdb_samba_dsdb_state);
1875 struct pdb_samba_dsdb_search_state *sstate;
1876 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1877 "userAccountControl", "description", NULL };
1878 struct ldb_result *res;
1879 int i, rc, num_users;
1881 va_list ap;
1882 char *expression = NULL;
1884 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1885 if (!tmp_ctx) {
1886 return false;
1889 va_start(ap, exp_fmt);
1890 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1891 va_end(ap);
1893 if (!expression) {
1894 talloc_free(tmp_ctx);
1895 return LDB_ERR_OPERATIONS_ERROR;
1898 sstate = talloc_zero(tmp_ctx, struct pdb_samba_dsdb_search_state);
1899 if (sstate == NULL) {
1900 talloc_free(tmp_ctx);
1901 return false;
1904 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1905 if (rc != LDB_SUCCESS) {
1906 talloc_free(tmp_ctx);
1907 DEBUG(10, ("dsdb_search failed: %s\n",
1908 ldb_errstring(state->ldb)));
1909 return false;
1912 num_users = res->count;
1914 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1915 num_users);
1916 if (sstate->entries == NULL) {
1917 talloc_free(tmp_ctx);
1918 DEBUG(10, ("talloc failed\n"));
1919 return false;
1922 sstate->num_entries = 0;
1924 for (i=0; i<num_users; i++) {
1925 struct samr_displayentry *e;
1926 struct dom_sid *sid;
1928 e = &sstate->entries[sstate->num_entries];
1930 e->idx = sstate->num_entries;
1931 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1932 if (!sid) {
1933 talloc_free(tmp_ctx);
1934 DEBUG(10, ("Could not pull SID\n"));
1935 return false;
1937 sid_peek_rid(sid, &e->rid);
1939 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1940 res->msgs[i],
1941 ldb_get_default_basedn(state->ldb));
1942 e->account_name = ldb_msg_find_attr_as_string(
1943 res->msgs[i], "samAccountName", NULL);
1944 if (e->account_name == NULL) {
1945 talloc_free(tmp_ctx);
1946 return false;
1948 e->fullname = ldb_msg_find_attr_as_string(
1949 res->msgs[i], "displayName", "");
1950 e->description = ldb_msg_find_attr_as_string(
1951 res->msgs[i], "description", "");
1953 sstate->num_entries += 1;
1954 if (sstate->num_entries >= num_users) {
1955 break;
1958 talloc_steal(sstate->entries, res->msgs);
1959 search->private_data = talloc_steal(search, sstate);
1960 search->next_entry = pdb_samba_dsdb_next_entry;
1961 search->search_end = pdb_samba_dsdb_search_end;
1962 *pstate = sstate;
1963 talloc_free(tmp_ctx);
1964 return true;
1967 static bool pdb_samba_dsdb_search_users(struct pdb_methods *m,
1968 struct pdb_search *search,
1969 uint32 acct_flags)
1971 struct pdb_samba_dsdb_search_state *sstate;
1972 bool ret;
1974 ret = pdb_samba_dsdb_search_filter(m, search, &sstate, "(objectclass=user)");
1975 if (!ret) {
1976 return false;
1978 sstate->acct_flags = acct_flags;
1979 return true;
1982 static bool pdb_samba_dsdb_search_groups(struct pdb_methods *m,
1983 struct pdb_search *search)
1985 struct pdb_samba_dsdb_search_state *sstate;
1986 bool ret;
1988 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
1989 "(&(grouptype=%d)(objectclass=group))",
1990 GTYPE_SECURITY_GLOBAL_GROUP);
1991 if (!ret) {
1992 return false;
1994 sstate->acct_flags = 0;
1995 return true;
1998 static bool pdb_samba_dsdb_search_aliases(struct pdb_methods *m,
1999 struct pdb_search *search,
2000 const struct dom_sid *sid)
2002 struct pdb_samba_dsdb_search_state *sstate;
2003 bool ret;
2005 ret = pdb_samba_dsdb_search_filter(m, search, &sstate,
2006 "(&(grouptype=%d)(objectclass=group))",
2007 sid_check_is_builtin(sid)
2008 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
2009 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
2010 if (!ret) {
2011 return false;
2013 sstate->acct_flags = 0;
2014 return true;
2017 static bool pdb_samba_dsdb_uid_to_sid(struct pdb_methods *m, uid_t uid,
2018 struct dom_sid *sid)
2020 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2021 m->private_data, struct pdb_samba_dsdb_state);
2022 NTSTATUS status;
2023 struct id_map id_map;
2024 struct id_map *id_maps[2];
2025 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2026 if (!tmp_ctx) {
2027 return false;
2030 id_map.xid.id = uid;
2031 id_map.xid.type = ID_TYPE_UID;
2032 id_maps[0] = &id_map;
2033 id_maps[1] = NULL;
2035 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2036 if (!NT_STATUS_IS_OK(status)) {
2037 talloc_free(tmp_ctx);
2038 return false;
2040 *sid = *id_map.sid;
2041 talloc_free(tmp_ctx);
2042 return true;
2045 static bool pdb_samba_dsdb_gid_to_sid(struct pdb_methods *m, gid_t gid,
2046 struct dom_sid *sid)
2048 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2049 m->private_data, struct pdb_samba_dsdb_state);
2050 NTSTATUS status;
2051 struct id_map id_map;
2052 struct id_map *id_maps[2];
2053 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2054 if (!tmp_ctx) {
2055 return false;
2058 id_map.xid.id = gid;
2059 id_map.xid.type = ID_TYPE_GID;
2060 id_maps[0] = &id_map;
2061 id_maps[1] = NULL;
2063 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2064 if (!NT_STATUS_IS_OK(status)) {
2065 return false;
2067 *sid = *id_map.sid;
2068 talloc_free(tmp_ctx);
2069 return true;
2072 static bool pdb_samba_dsdb_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2073 struct unixid *id)
2075 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2076 m->private_data, struct pdb_samba_dsdb_state);
2077 struct id_map id_map;
2078 struct id_map *id_maps[2];
2079 NTSTATUS status;
2080 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2081 if (!tmp_ctx) {
2082 return false;
2085 ZERO_STRUCT(id_map);
2086 id_map.sid = discard_const_p(struct dom_sid, sid);
2087 id_maps[0] = &id_map;
2088 id_maps[1] = NULL;
2090 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2091 talloc_free(tmp_ctx);
2092 if (!NT_STATUS_IS_OK(status)) {
2093 return false;
2095 if (id_map.xid.type != ID_TYPE_NOT_SPECIFIED) {
2096 *id = id_map.xid;
2097 return true;
2099 return false;
2102 static uint32_t pdb_samba_dsdb_capabilities(struct pdb_methods *m)
2104 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2107 static bool pdb_samba_dsdb_new_rid(struct pdb_methods *m, uint32 *rid)
2109 return false;
2112 static bool pdb_samba_dsdb_get_trusteddom_pw(struct pdb_methods *m,
2113 const char *domain, char** pwd,
2114 struct dom_sid *sid,
2115 time_t *pass_last_set_time)
2117 return false;
2120 static bool pdb_samba_dsdb_set_trusteddom_pw(struct pdb_methods *m,
2121 const char* domain, const char* pwd,
2122 const struct dom_sid *sid)
2124 return false;
2127 static bool pdb_samba_dsdb_del_trusteddom_pw(struct pdb_methods *m,
2128 const char *domain)
2130 return false;
2133 static NTSTATUS pdb_samba_dsdb_enum_trusteddoms(struct pdb_methods *m,
2134 TALLOC_CTX *mem_ctx,
2135 uint32 *num_domains,
2136 struct trustdom_info ***domains)
2138 *num_domains = 0;
2139 *domains = NULL;
2140 return NT_STATUS_OK;
2143 static bool pdb_samba_dsdb_is_responsible_for_wellknown(struct pdb_methods *m)
2145 return true;
2148 static void pdb_samba_dsdb_init_methods(struct pdb_methods *m)
2150 m->name = "samba_dsdb";
2151 m->get_domain_info = pdb_samba_dsdb_get_domain_info;
2152 m->getsampwnam = pdb_samba_dsdb_getsampwnam;
2153 m->getsampwsid = pdb_samba_dsdb_getsampwsid;
2154 m->create_user = pdb_samba_dsdb_create_user;
2155 m->delete_user = pdb_samba_dsdb_delete_user;
2156 m->add_sam_account = pdb_samba_dsdb_add_sam_account;
2157 m->update_sam_account = pdb_samba_dsdb_update_sam_account;
2158 m->delete_sam_account = pdb_samba_dsdb_delete_sam_account;
2159 m->rename_sam_account = pdb_samba_dsdb_rename_sam_account;
2160 m->update_login_attempts = pdb_samba_dsdb_update_login_attempts;
2161 m->getgrsid = pdb_samba_dsdb_getgrsid;
2162 m->getgrgid = pdb_samba_dsdb_getgrgid;
2163 m->getgrnam = pdb_samba_dsdb_getgrnam;
2164 m->create_dom_group = pdb_samba_dsdb_create_dom_group;
2165 m->delete_dom_group = pdb_samba_dsdb_delete_dom_group;
2166 m->add_group_mapping_entry = pdb_samba_dsdb_add_group_mapping_entry;
2167 m->update_group_mapping_entry = pdb_samba_dsdb_update_group_mapping_entry;
2168 m->delete_group_mapping_entry = pdb_samba_dsdb_delete_group_mapping_entry;
2169 m->enum_group_mapping = pdb_samba_dsdb_enum_group_mapping;
2170 m->enum_group_members = pdb_samba_dsdb_enum_group_members;
2171 m->enum_group_memberships = pdb_samba_dsdb_enum_group_memberships;
2172 m->set_unix_primary_group = pdb_samba_dsdb_set_unix_primary_group;
2173 m->add_groupmem = pdb_samba_dsdb_add_groupmem;
2174 m->del_groupmem = pdb_samba_dsdb_del_groupmem;
2175 m->create_alias = pdb_samba_dsdb_create_alias;
2176 m->delete_alias = pdb_samba_dsdb_delete_alias;
2177 m->get_aliasinfo = pdb_default_get_aliasinfo;
2178 m->add_aliasmem = pdb_samba_dsdb_add_aliasmem;
2179 m->del_aliasmem = pdb_samba_dsdb_del_aliasmem;
2180 m->enum_aliasmem = pdb_samba_dsdb_enum_aliasmem;
2181 m->enum_alias_memberships = pdb_samba_dsdb_enum_alias_memberships;
2182 m->lookup_rids = pdb_samba_dsdb_lookup_rids;
2183 m->lookup_names = pdb_samba_dsdb_lookup_names;
2184 m->get_account_policy = pdb_samba_dsdb_get_account_policy;
2185 m->set_account_policy = pdb_samba_dsdb_set_account_policy;
2186 m->get_seq_num = pdb_samba_dsdb_get_seq_num;
2187 m->search_users = pdb_samba_dsdb_search_users;
2188 m->search_groups = pdb_samba_dsdb_search_groups;
2189 m->search_aliases = pdb_samba_dsdb_search_aliases;
2190 m->uid_to_sid = pdb_samba_dsdb_uid_to_sid;
2191 m->gid_to_sid = pdb_samba_dsdb_gid_to_sid;
2192 m->sid_to_id = pdb_samba_dsdb_sid_to_id;
2193 m->capabilities = pdb_samba_dsdb_capabilities;
2194 m->new_rid = pdb_samba_dsdb_new_rid;
2195 m->get_trusteddom_pw = pdb_samba_dsdb_get_trusteddom_pw;
2196 m->set_trusteddom_pw = pdb_samba_dsdb_set_trusteddom_pw;
2197 m->del_trusteddom_pw = pdb_samba_dsdb_del_trusteddom_pw;
2198 m->enum_trusteddoms = pdb_samba_dsdb_enum_trusteddoms;
2199 m->is_responsible_for_wellknown =
2200 pdb_samba_dsdb_is_responsible_for_wellknown;
2203 static void free_private_data(void **vp)
2205 struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
2206 *vp, struct pdb_samba_dsdb_state);
2207 talloc_unlink(state, state->ldb);
2208 return;
2211 static NTSTATUS pdb_samba_dsdb_init_secrets(struct pdb_methods *m)
2213 struct pdb_domain_info *dom_info;
2214 bool ret;
2216 dom_info = pdb_samba_dsdb_get_domain_info(m, m);
2217 if (!dom_info) {
2218 return NT_STATUS_UNSUCCESSFUL;
2221 secrets_clear_domain_protection(dom_info->name);
2222 ret = secrets_store_domain_sid(dom_info->name,
2223 &dom_info->sid);
2224 if (!ret) {
2225 goto done;
2227 ret = secrets_store_domain_guid(dom_info->name,
2228 &dom_info->guid);
2229 if (!ret) {
2230 goto done;
2232 ret = secrets_mark_domain_protected(dom_info->name);
2233 if (!ret) {
2234 goto done;
2237 done:
2238 TALLOC_FREE(dom_info);
2239 if (!ret) {
2240 return NT_STATUS_UNSUCCESSFUL;
2242 return NT_STATUS_OK;
2245 static NTSTATUS pdb_init_samba_dsdb(struct pdb_methods **pdb_method,
2246 const char *location)
2248 struct pdb_methods *m;
2249 struct pdb_samba_dsdb_state *state;
2250 NTSTATUS status;
2252 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2253 return status;
2256 state = talloc_zero(m, struct pdb_samba_dsdb_state);
2257 if (state == NULL) {
2258 goto nomem;
2260 m->private_data = state;
2261 m->free_private_data = free_private_data;
2262 pdb_samba_dsdb_init_methods(m);
2264 state->ev = s4_event_context_init(state);
2265 if (!state->ev) {
2266 DEBUG(0, ("s4_event_context_init failed\n"));
2267 goto nomem;
2270 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_helpers());
2271 if (state->lp_ctx == NULL) {
2272 DEBUG(0, ("loadparm_init_s3 failed\n"));
2273 goto nomem;
2276 if (location) {
2277 state->ldb = samdb_connect_url(state,
2278 state->ev,
2279 state->lp_ctx,
2280 system_session(state->lp_ctx),
2281 0, location);
2282 } else {
2283 state->ldb = samdb_connect(state,
2284 state->ev,
2285 state->lp_ctx,
2286 system_session(state->lp_ctx), 0);
2289 if (!state->ldb) {
2290 DEBUG(0, ("samdb_connect failed\n"));
2291 status = NT_STATUS_INTERNAL_ERROR;
2292 goto fail;
2295 state->idmap_ctx = idmap_init(state, state->ev,
2296 state->lp_ctx);
2297 if (!state->idmap_ctx) {
2298 DEBUG(0, ("idmap failed\n"));
2299 status = NT_STATUS_INTERNAL_ERROR;
2300 goto fail;
2303 status = pdb_samba_dsdb_init_secrets(m);
2304 if (!NT_STATUS_IS_OK(status)) {
2305 DEBUG(10, ("pdb_samba_dsdb_init_secrets failed!\n"));
2306 goto fail;
2309 *pdb_method = m;
2310 return NT_STATUS_OK;
2311 nomem:
2312 status = NT_STATUS_NO_MEMORY;
2313 fail:
2314 TALLOC_FREE(m);
2315 return status;
2318 NTSTATUS pdb_samba_dsdb_init(void);
2319 NTSTATUS pdb_samba_dsdb_init(void)
2321 NTSTATUS status = smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba_dsdb",
2322 pdb_init_samba_dsdb);
2323 if (!NT_STATUS_IS_OK(status)) {
2324 return status;
2326 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2327 pdb_init_samba_dsdb);