s3:net registry import: add an assert
[Samba/gebeck_regimport.git] / source3 / passdb / pdb_samba4.c
blobc94f29c7ae156b7329aafd197ccb0ee70c8a9414
1 /*
2 Unix SMB/CIFS implementation.
3 pdb glue module for samba4
4 Copyright (C) Volker Lendecke 2009-2011
5 Copyright (C) Andrew Bartlett 2010
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_samba4_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_samba4_getsampwsid(struct pdb_methods *m,
47 struct samu *sam_acct,
48 const struct dom_sid *sid);
49 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
50 const char *filter,
51 TALLOC_CTX *mem_ctx,
52 struct ldb_message **pmsg);
53 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
54 struct unixid *id);
56 static bool pdb_samba4_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 = uint64s_nt_time_to_unix_abs(&tmp);
65 return true;
68 static struct pdb_domain_info *pdb_samba4_get_domain_info(
69 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
71 struct pdb_samba4_state *state = talloc_get_type_abort(
72 m->private_data, struct pdb_samba4_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_samba4_get_samu_private(
146 struct pdb_methods *m, struct samu *sam)
148 struct pdb_samba4_state *state = talloc_get_type_abort(
149 m->private_data, struct pdb_samba4_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_samba4_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_samba4_init_sam_from_priv(struct pdb_methods *m,
183 struct samu *sam,
184 struct ldb_message *msg)
186 struct pdb_samba4_state *state = talloc_get_type_abort(
187 m->private_data, struct pdb_samba4_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_samba4_pull_time(msg, "lastLogon", &tmp_time)) {
204 pdb_set_logon_time(sam, tmp_time, PDB_SET);
206 if (pdb_samba4_pull_time(msg, "lastLogoff", &tmp_time)) {
207 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
209 if (pdb_samba4_pull_time(msg, "pwdLastSet", &tmp_time)) {
210 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
212 if (pdb_samba4_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, "profilePath",
245 NULL);
246 if (str != NULL) {
247 pdb_set_profile_path(sam, str, PDB_SET);
250 str = ldb_msg_find_attr_as_string(msg, "comment",
251 NULL);
252 if (str != NULL) {
253 pdb_set_comment(sam, str, PDB_SET);
256 str = ldb_msg_find_attr_as_string(msg, "description",
257 NULL);
258 if (str != NULL) {
259 pdb_set_acct_desc(sam, str, PDB_SET);
262 str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
263 NULL);
264 if (str != NULL) {
265 pdb_set_workstations(sam, str, PDB_SET);
268 str = ldb_msg_find_attr_as_string(msg, "userParameters",
269 NULL);
270 if (str != NULL) {
271 pdb_set_munged_dial(sam, str, PDB_SET);
274 sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
275 if (!sid) {
276 DEBUG(10, ("Could not pull SID\n"));
277 goto fail;
279 pdb_set_user_sid(sam, sid, PDB_SET);
281 n = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
282 if (n == 0) {
283 DEBUG(10, ("Could not pull userAccountControl\n"));
284 goto fail;
286 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
288 blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
289 if (blob) {
290 if (blob->length != NT_HASH_LEN) {
291 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
292 (int)blob->length, NT_HASH_LEN));
293 goto fail;
295 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
298 blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
299 if (blob) {
300 if (blob->length != LM_HASH_LEN) {
301 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
302 (int)blob->length, LM_HASH_LEN));
303 goto fail;
305 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
308 n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
309 if (n == 0) {
310 DEBUG(10, ("Could not pull primaryGroupID\n"));
311 goto fail;
313 sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
314 pdb_set_group_sid(sam, &group_sid, PDB_SET);
316 status = NT_STATUS_OK;
317 fail:
318 TALLOC_FREE(frame);
319 return status;
322 static bool pdb_samba4_add_time(struct ldb_message *msg,
323 const char *attrib, time_t t)
325 uint64_t nt_time;
327 unix_to_nt_time(&nt_time, t);
329 return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
332 static int pdb_samba4_replace_by_sam(struct pdb_samba4_state *state,
333 bool (*need_update)(const struct samu *,
334 enum pdb_elements),
335 struct ldb_dn *dn,
336 struct samu *sam)
338 TALLOC_CTX *frame = talloc_stackframe();
339 int ret = LDB_SUCCESS;
340 const char *pw;
341 struct ldb_message *msg;
342 struct ldb_request *req;
343 uint32_t dsdb_flags = 0;
344 /* TODO: All fields :-) */
346 msg = ldb_msg_new(frame);
347 if (!msg) {
348 return false;
351 msg->dn = dn;
353 /* build modify request */
354 ret = ldb_build_mod_req(&req, state->ldb, frame, msg, NULL, NULL,
355 ldb_op_default_callback,
356 NULL);
357 if (ret != LDB_SUCCESS) {
358 talloc_free(frame);
359 return ret;
362 /* If we set a plaintext password, the system will
363 * force the pwdLastSet to now() */
364 if (need_update(sam, PDB_PASSLASTSET)) {
365 dsdb_flags = DSDB_PASSWORD_BYPASS_LAST_SET;
367 ret |= pdb_samba4_add_time(msg, "pwdLastSet",
368 pdb_get_pass_last_set_time(sam));
371 pw = pdb_get_plaintext_passwd(sam);
372 if (need_update(sam, PDB_PLAINTEXT_PW)) {
373 struct ldb_val pw_utf16;
374 if (pw == NULL) {
375 talloc_free(frame);
376 return LDB_ERR_OPERATIONS_ERROR;
379 if (!convert_string_talloc(msg,
380 CH_UNIX, CH_UTF16,
381 pw, strlen(pw),
382 (void *)&pw_utf16.data,
383 &pw_utf16.length)) {
384 return LDB_ERR_OPERATIONS_ERROR;
386 ret |= ldb_msg_add_value(msg, "clearTextPassword", &pw_utf16, NULL);
387 } else {
388 bool changed_lm_pw = false;
389 bool changed_nt_pw = false;
390 bool changed_history = false;
391 if (need_update(sam, PDB_LMPASSWD)) {
392 struct ldb_val val;
393 val.data = pdb_get_lanman_passwd(sam);
394 if (!val.data) {
395 samdb_msg_add_delete(state->ldb, msg, msg,
396 "dBCSPwd");
397 } else {
398 val.length = LM_HASH_LEN;
399 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
401 changed_lm_pw = true;
403 if (need_update(sam, PDB_NTPASSWD)) {
404 struct ldb_val val;
405 val.data = pdb_get_nt_passwd(sam);
406 if (!val.data) {
407 samdb_msg_add_delete(state->ldb, msg, msg,
408 "unicodePwd");
409 } else {
410 val.length = NT_HASH_LEN;
411 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
413 changed_nt_pw = true;
416 /* Try to ensure we don't get out of sync */
417 if (changed_lm_pw && !changed_nt_pw) {
418 samdb_msg_add_delete(state->ldb, msg, msg,
419 "unicodePwd");
420 } else if (changed_nt_pw && !changed_lm_pw) {
421 samdb_msg_add_delete(state->ldb, msg, msg,
422 "dBCSPwd");
424 if (changed_lm_pw || changed_nt_pw) {
425 samdb_msg_add_delete(state->ldb, msg, msg,
426 "supplementalCredentials");
430 if (need_update(sam, PDB_PWHISTORY)) {
431 uint32_t current_hist_len;
432 const uint8_t *history = pdb_get_pw_history(sam, &current_hist_len);
434 bool invalid_history = false;
435 struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
436 current_hist_len);
437 if (!history) {
438 invalid_history = true;
439 } else {
440 unsigned int i;
441 static const uint8_t zeros[16];
442 /* Parse the history into the correct format */
443 for (i = 0; i < current_hist_len; i++) {
444 if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
445 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
446 invalid_history = true;
447 break;
449 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
450 memcpy(history_hashes[i].hash,
451 &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
452 sizeof(history_hashes[i].hash));
455 if (invalid_history) {
456 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
457 "ntPwdHistory");
459 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
460 "lmPwdHistory");
461 } else {
462 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
463 "ntPwdHistory",
464 history_hashes,
465 current_hist_len);
467 changed_history = true;
469 if (changed_lm_pw || changed_nt_pw || changed_history) {
470 /* These attributes can only be modified directly by using a special control */
471 dsdb_flags = DSDB_BYPASS_PASSWORD_HASH;
475 /* PDB_USERSID is only allowed on ADD, handled in caller */
476 if (need_update(sam, PDB_GROUPSID)) {
477 const struct dom_sid *sid = pdb_get_group_sid(sam);
478 uint32_t rid;
479 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
480 if (!NT_STATUS_IS_OK(status)) {
481 talloc_free(frame);
482 return LDB_ERR_OPERATIONS_ERROR;
484 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
485 talloc_free(frame);
486 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
488 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
490 if (need_update(sam, PDB_FULLNAME)) {
491 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
494 if (need_update(sam, PDB_SMBHOME)) {
495 ret |= ldb_msg_add_string(msg, "homeDirectory",
496 pdb_get_homedir(sam));
499 if (need_update(sam, PDB_PROFILE)) {
500 ret |= ldb_msg_add_string(msg, "profilePath",
501 pdb_get_profile_path(sam));
504 if (need_update(sam, PDB_DRIVE)) {
505 ret |= ldb_msg_add_string(msg, "homeDrive",
506 pdb_get_dir_drive(sam));
509 if (need_update(sam, PDB_LOGONSCRIPT)) {
510 ret |= ldb_msg_add_string(msg, "scriptPath",
511 pdb_get_logon_script(sam));
514 if (need_update(sam, PDB_KICKOFFTIME)) {
515 ret |= pdb_samba4_add_time(msg, "accountExpires",
516 pdb_get_kickoff_time(sam));
519 if (need_update(sam, PDB_USERNAME)) {
520 ret |= ldb_msg_add_string(msg, "samAccountName",
521 pdb_get_username(sam));
524 if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
525 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
526 ret |= ldb_msg_add_value(msg, "logonHours",
527 &hours, NULL);
530 if (need_update(sam, PDB_ACCTCTRL)) {
531 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
532 "userAccountControl", pdb_get_acct_ctrl(sam));
535 if (need_update(sam, PDB_COMMENT)) {
536 ret |= ldb_msg_add_string(msg, "comment",
537 pdb_get_comment(sam));
540 if (need_update(sam, PDB_ACCTDESC)) {
541 ret |= ldb_msg_add_string(msg, "description",
542 pdb_get_acct_desc(sam));
545 if (need_update(sam, PDB_WORKSTATIONS)) {
546 ret |= ldb_msg_add_string(msg, "userWorkstations",
547 pdb_get_workstations(sam));
550 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
551 if (need_update(sam, PDB_MUNGEDDIAL)) {
552 ret |= ldb_msg_add_string(msg, "userParameters",
553 pdb_get_munged_dial(sam));
556 if (need_update(sam, PDB_COUNTRY_CODE)) {
557 ret |= ldb_msg_add_fmt(msg, "countryCode",
558 "%i", (int)pdb_get_country_code(sam));
561 if (need_update(sam, PDB_CODE_PAGE)) {
562 ret |= ldb_msg_add_fmt(msg, "codePage",
563 "%i", (int)pdb_get_code_page(sam));
566 /* Not yet handled here or not meaningful for modifies on a Samba4 backend:
567 PDB_LOGONTIME,
568 PDB_LOGOFFTIME,
569 PDB_BAD_PASSWORD_TIME,
570 PDB_CANCHANGETIME, - these are calculated per policy, not stored
571 PDB_DOMAIN,
572 PDB_NTUSERNAME, - this makes no sense, and never really did
573 PDB_LOGONDIVS,
574 PDB_USERSID, - Handled in pdb_samba4_add_sam_account()
575 PDB_FIELDS_PRESENT,
576 PDB_BAD_PASSWORD_COUNT,
577 PDB_LOGON_COUNT,
578 PDB_UNKNOWN6,
579 PDB_BACKEND_PRIVATE_DATA,
582 if (ret != LDB_SUCCESS) {
583 talloc_free(frame);
584 return LDB_ERR_OPERATIONS_ERROR;
587 if (msg->num_elements == 0) {
588 talloc_free(frame);
589 /* Nothing to do, just return success */
590 return LDB_SUCCESS;
593 ret = dsdb_replace(state->ldb, msg, dsdb_flags);
595 if (ret != LDB_SUCCESS) {
596 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
597 ldb_dn_get_linearized(msg->dn),
598 ldb_errstring(state->ldb)));
601 talloc_free(frame);
602 return ret;
605 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
606 const char *filter,
607 TALLOC_CTX *mem_ctx,
608 struct ldb_message **msg)
610 const char * attrs[] = {
611 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
612 "sAMAccountName", "displayName", "homeDirectory",
613 "homeDrive", "scriptPath", "profilePath", "description",
614 "userWorkstations", "comment", "userParameters", "objectSid",
615 "primaryGroupID", "userAccountControl", "logonHours",
616 "badPwdCount", "logonCount", "countryCode", "codePage",
617 "unicodePwd", "dBCSPwd", NULL };
619 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
620 if (rc != LDB_SUCCESS) {
621 DEBUG(10, ("ldap_search failed %s\n",
622 ldb_errstring(state->ldb)));
623 return NT_STATUS_LDAP(rc);
626 return NT_STATUS_OK;
629 static NTSTATUS pdb_samba4_getsampwfilter(struct pdb_methods *m,
630 struct pdb_samba4_state *state,
631 struct samu *sam_acct,
632 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
634 struct ldb_message *priv;
635 NTSTATUS status;
636 va_list ap;
637 char *expression = NULL;
638 TALLOC_CTX *tmp_ctx = talloc_new(state);
639 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
641 va_start(ap, exp_fmt);
642 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
643 va_end(ap);
645 if (!expression) {
646 talloc_free(tmp_ctx);
647 return NT_STATUS_NO_MEMORY;
650 status = pdb_samba4_getsamupriv(state, expression, sam_acct, &priv);
651 talloc_free(tmp_ctx);
652 if (!NT_STATUS_IS_OK(status)) {
653 DEBUG(10, ("pdb_samba4_getsamupriv failed: %s\n",
654 nt_errstr(status)));
655 return status;
658 status = pdb_samba4_init_sam_from_priv(m, sam_acct, priv);
659 if (!NT_STATUS_IS_OK(status)) {
660 DEBUG(10, ("pdb_samba4_init_sam_from_priv failed: %s\n",
661 nt_errstr(status)));
662 TALLOC_FREE(priv);
663 return status;
666 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
667 return NT_STATUS_OK;
670 static NTSTATUS pdb_samba4_getsampwnam(struct pdb_methods *m,
671 struct samu *sam_acct,
672 const char *username)
674 struct pdb_samba4_state *state = talloc_get_type_abort(
675 m->private_data, struct pdb_samba4_state);
677 return pdb_samba4_getsampwfilter(m, state, sam_acct,
678 "(&(samaccountname=%s)(objectclass=user))",
679 username);
682 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
683 struct samu *sam_acct,
684 const struct dom_sid *sid)
686 NTSTATUS status;
687 struct pdb_samba4_state *state = talloc_get_type_abort(
688 m->private_data, struct pdb_samba4_state);
689 char *sidstr;
691 sidstr = dom_sid_string(talloc_tos(), sid);
692 NT_STATUS_HAVE_NO_MEMORY(sidstr);
694 status = pdb_samba4_getsampwfilter(m, state, sam_acct,
695 "(&(objectsid=%s)(objectclass=user))",
696 sidstr);
697 talloc_free(sidstr);
698 return status;
701 static NTSTATUS pdb_samba4_create_user(struct pdb_methods *m,
702 TALLOC_CTX *mem_ctx,
703 const char *name, uint32 acct_flags,
704 uint32 *rid)
706 struct pdb_samba4_state *state = talloc_get_type_abort(
707 m->private_data, struct pdb_samba4_state);
708 struct dom_sid *sid;
709 struct ldb_dn *dn;
710 NTSTATUS status;
711 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
712 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
714 /* Internally this uses transactions to ensure all the steps
715 * happen or fail as one */
716 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
717 &sid, &dn);
718 if (!NT_STATUS_IS_OK(status)) {
719 talloc_free(tmp_ctx);
720 return status;
722 sid_peek_rid(sid, rid);
723 talloc_free(tmp_ctx);
724 return NT_STATUS_OK;
727 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
728 TALLOC_CTX *mem_ctx,
729 struct samu *sam)
731 struct pdb_samba4_state *state = talloc_get_type_abort(
732 m->private_data, struct pdb_samba4_state);
733 struct ldb_dn *dn;
734 int rc;
735 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
736 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
738 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
739 if (!dn || !ldb_dn_validate(dn)) {
740 talloc_free(tmp_ctx);
741 return NT_STATUS_NO_MEMORY;
743 rc = ldb_delete(state->ldb, dn);
745 if (rc != LDB_SUCCESS) {
746 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
747 ldb_errstring(state->ldb)));
748 talloc_free(tmp_ctx);
749 return NT_STATUS_LDAP(rc);
751 talloc_free(tmp_ctx);
752 return NT_STATUS_OK;
755 /* This interface takes a fully populated struct samu and places it in
756 * the database. This is not implemented at this time as we need to
757 * be careful around the creation of arbitary SIDs (ie, we must ensrue
758 * they are not left in a RID pool */
759 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
760 struct samu *sampass)
762 int ret;
763 NTSTATUS status;
764 struct ldb_dn *dn;
765 struct pdb_samba4_state *state = talloc_get_type_abort(
766 m->private_data, struct pdb_samba4_state);
767 uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
768 const char *username = pdb_get_username(sampass);
769 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
770 TALLOC_CTX *tframe = talloc_stackframe();
772 acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
774 ret = ldb_transaction_start(state->ldb);
775 if (ret != LDB_SUCCESS) {
776 talloc_free(tframe);
777 return NT_STATUS_LOCK_NOT_GRANTED;
780 status = dsdb_add_user(state->ldb, talloc_tos(), username,
781 acb_flags, user_sid, NULL, &dn);
782 if (!NT_STATUS_IS_OK(status)) {
783 ldb_transaction_cancel(state->ldb);
784 talloc_free(tframe);
785 return status;
788 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_set_or_changed,
789 dn, sampass);
790 if (ret != LDB_SUCCESS) {
791 ldb_transaction_cancel(state->ldb);
792 talloc_free(tframe);
793 return dsdb_ldb_err_to_ntstatus(ret);
796 ret = ldb_transaction_commit(state->ldb);
797 if (ret != LDB_SUCCESS) {
798 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
799 ldb_dn_get_linearized(dn),
800 ldb_errstring(state->ldb)));
801 talloc_free(tframe);
802 return NT_STATUS_INTERNAL_DB_CORRUPTION;
804 talloc_free(tframe);
805 return NT_STATUS_OK;
809 * Update the Samba4 LDB with the changes from a struct samu.
811 * This takes care not to update elements that have not been changed
812 * by the caller
814 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
815 struct samu *sam)
817 struct pdb_samba4_state *state = talloc_get_type_abort(
818 m->private_data, struct pdb_samba4_state);
819 struct ldb_message *msg = pdb_samba4_get_samu_private(
820 m, sam);
821 int ret;
823 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_changed, msg->dn,
824 sam);
825 return dsdb_ldb_err_to_ntstatus(ret);
828 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
829 struct samu *username)
831 NTSTATUS status;
832 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
833 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
834 status = pdb_samba4_delete_user(m, tmp_ctx, username);
835 talloc_free(tmp_ctx);
836 return status;
839 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
840 struct samu *oldname,
841 const char *newname)
843 return NT_STATUS_NOT_IMPLEMENTED;
846 /* This is not implemented, as this module is exptected to be used
847 * with auth_samba4, and this is responible for login counters etc
850 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
851 struct samu *sam_acct,
852 bool success)
854 return NT_STATUS_NOT_IMPLEMENTED;
857 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
858 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
860 struct pdb_samba4_state *state = talloc_get_type_abort(
861 m->private_data, struct pdb_samba4_state);
862 const char *attrs[] = { "objectSid", "description", "samAccountName", "groupType",
863 NULL };
864 struct ldb_message *msg;
865 va_list ap;
866 char *expression = NULL;
867 struct dom_sid *sid;
868 const char *str;
869 int rc;
870 struct id_map id_map;
871 struct id_map *id_maps[2];
872 TALLOC_CTX *tmp_ctx = talloc_stackframe();
873 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
875 va_start(ap, exp_fmt);
876 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
877 va_end(ap);
879 if (!expression) {
880 talloc_free(tmp_ctx);
881 return NT_STATUS_NO_MEMORY;
884 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
885 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
886 talloc_free(tmp_ctx);
887 return NT_STATUS_NO_SUCH_GROUP;
888 } else if (rc != LDB_SUCCESS) {
889 talloc_free(tmp_ctx);
890 DEBUG(10, ("dsdb_search_one failed %s\n",
891 ldb_errstring(state->ldb)));
892 return NT_STATUS_LDAP(rc);
895 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
896 if (!sid) {
897 talloc_free(tmp_ctx);
898 DEBUG(10, ("Could not pull SID\n"));
899 return NT_STATUS_INTERNAL_DB_CORRUPTION;
902 map->sid = *sid;
904 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
905 NTSTATUS status;
906 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
907 switch (grouptype) {
908 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
909 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
910 map->sid_name_use = SID_NAME_ALIAS;
911 break;
912 case GTYPE_SECURITY_GLOBAL_GROUP:
913 map->sid_name_use = SID_NAME_DOM_GRP;
914 break;
915 default:
916 talloc_free(tmp_ctx);
917 DEBUG(10, ("Could not pull groupType\n"));
918 return NT_STATUS_INTERNAL_DB_CORRUPTION;
921 map->sid_name_use = SID_NAME_DOM_GRP;
923 ZERO_STRUCT(id_map);
924 id_map.sid = sid;
925 id_maps[0] = &id_map;
926 id_maps[1] = NULL;
928 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
929 talloc_free(tmp_ctx);
930 if (!NT_STATUS_IS_OK(status)) {
931 talloc_free(tmp_ctx);
932 return status;
934 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
935 map->gid = id_map.xid.id;
936 } else {
937 DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
938 talloc_free(tmp_ctx);
939 return NT_STATUS_INTERNAL_DB_CORRUPTION;
941 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
942 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
943 talloc_free(tmp_ctx);
944 return NT_STATUS_INTERNAL_DB_CORRUPTION;
947 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
948 NULL);
949 if (str == NULL) {
950 talloc_free(tmp_ctx);
951 return NT_STATUS_INTERNAL_DB_CORRUPTION;
953 map->nt_name = talloc_strdup(map, str);
954 if (!map->nt_name) {
955 talloc_free(tmp_ctx);
956 return NT_STATUS_NO_MEMORY;
959 str = ldb_msg_find_attr_as_string(msg, "description",
960 NULL);
961 if (str != NULL) {
962 map->comment = talloc_strdup(map, str);
963 } else {
964 map->comment = talloc_strdup(map, "");
966 if (!map->comment) {
967 talloc_free(tmp_ctx);
968 return NT_STATUS_NO_MEMORY;
971 talloc_free(tmp_ctx);
972 return NT_STATUS_OK;
975 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
976 struct dom_sid sid)
978 char *filter;
979 NTSTATUS status;
981 filter = talloc_asprintf(talloc_tos(),
982 "(&(objectsid=%s)(objectclass=group))",
983 sid_string_talloc(talloc_tos(), &sid));
984 if (filter == NULL) {
985 return NT_STATUS_NO_MEMORY;
988 status = pdb_samba4_getgrfilter(m, map, filter);
989 TALLOC_FREE(filter);
990 return status;
993 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
994 gid_t gid)
996 struct pdb_samba4_state *state = talloc_get_type_abort(
997 m->private_data, struct pdb_samba4_state);
998 NTSTATUS status;
999 struct id_map id_map;
1000 struct id_map *id_maps[2];
1001 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1002 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1004 id_map.xid.id = gid;
1005 id_map.xid.type = ID_TYPE_GID;
1006 id_maps[0] = &id_map;
1007 id_maps[1] = NULL;
1009 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1010 if (!NT_STATUS_IS_OK(status)) {
1011 return status;
1013 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
1014 talloc_free(tmp_ctx);
1015 return status;
1018 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
1019 const char *name)
1021 char *filter;
1022 NTSTATUS status;
1024 filter = talloc_asprintf(talloc_tos(),
1025 "(&(samaccountname=%s)(objectclass=group))",
1026 name);
1027 if (filter == NULL) {
1028 return NT_STATUS_NO_MEMORY;
1031 status = pdb_samba4_getgrfilter(m, map, filter);
1032 TALLOC_FREE(filter);
1033 return status;
1036 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
1037 TALLOC_CTX *mem_ctx, const char *name,
1038 uint32 *rid)
1040 struct pdb_samba4_state *state = talloc_get_type_abort(
1041 m->private_data, struct pdb_samba4_state);
1042 NTSTATUS status;
1043 struct dom_sid *sid;
1044 struct ldb_dn *dn;
1045 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1046 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1048 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1049 if (!NT_STATUS_IS_OK(status)) {
1050 talloc_free(tmp_ctx);
1051 return status;
1054 sid_peek_rid(sid, rid);
1055 talloc_free(tmp_ctx);
1056 return NT_STATUS_OK;
1059 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1060 TALLOC_CTX *mem_ctx, uint32 rid)
1062 const char *attrs[] = { NULL };
1063 struct pdb_samba4_state *state = talloc_get_type_abort(
1064 m->private_data, struct pdb_samba4_state);
1065 struct dom_sid sid;
1066 struct ldb_message *msg;
1067 struct ldb_dn *dn;
1068 int rc;
1069 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1070 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1072 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1074 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1075 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1076 return NT_STATUS_INTERNAL_ERROR;
1079 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1080 if (!dn || !ldb_dn_validate(dn)) {
1081 talloc_free(tmp_ctx);
1082 ldb_transaction_cancel(state->ldb);
1083 return NT_STATUS_NO_MEMORY;
1085 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1086 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1087 talloc_free(tmp_ctx);
1088 ldb_transaction_cancel(state->ldb);
1089 return NT_STATUS_NO_SUCH_GROUP;
1091 rc = ldb_delete(state->ldb, dn);
1092 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1093 talloc_free(tmp_ctx);
1094 ldb_transaction_cancel(state->ldb);
1095 return NT_STATUS_NO_SUCH_GROUP;
1096 } else if (rc != LDB_SUCCESS) {
1097 DEBUG(10, ("ldb_delete failed %s\n",
1098 ldb_errstring(state->ldb)));
1099 ldb_transaction_cancel(state->ldb);
1100 return NT_STATUS_LDAP(rc);
1103 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1104 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1105 return NT_STATUS_INTERNAL_ERROR;
1107 return NT_STATUS_OK;
1110 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1111 GROUP_MAP *map)
1113 return NT_STATUS_NOT_IMPLEMENTED;
1116 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1117 GROUP_MAP *map)
1119 return NT_STATUS_NOT_IMPLEMENTED;
1122 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1123 struct dom_sid sid)
1125 return NT_STATUS_NOT_IMPLEMENTED;
1128 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1129 const struct dom_sid *sid,
1130 enum lsa_SidType sid_name_use,
1131 GROUP_MAP ***pp_rmap,
1132 size_t *p_num_entries,
1133 bool unix_only)
1135 return NT_STATUS_NOT_IMPLEMENTED;
1138 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1139 TALLOC_CTX *mem_ctx,
1140 const struct dom_sid *group,
1141 uint32_t **pmembers,
1142 size_t *pnum_members)
1144 unsigned int i, num_sids, num_members;
1145 struct pdb_samba4_state *state = talloc_get_type_abort(
1146 m->private_data, struct pdb_samba4_state);
1147 struct dom_sid *members_as_sids;
1148 struct dom_sid *dom_sid;
1149 uint32_t *members;
1150 struct ldb_dn *dn;
1151 NTSTATUS status;
1153 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1154 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1156 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1157 if (!dn || !ldb_dn_validate(dn)) {
1158 return NT_STATUS_NO_MEMORY;
1161 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1162 if (!NT_STATUS_IS_OK(status)) {
1163 talloc_free(tmp_ctx);
1164 return status;
1166 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1167 if (!NT_STATUS_IS_OK(status)) {
1168 talloc_free(tmp_ctx);
1169 return status;
1172 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1173 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1174 num_members = 0;
1176 for (i = 0; i < num_sids; i++) {
1177 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1178 continue;
1180 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1181 NULL, &members[num_members]);
1182 if (!NT_STATUS_IS_OK(status)) {
1183 talloc_free(tmp_ctx);
1184 return status;
1186 num_members++;
1188 *pnum_members = num_members;
1189 return NT_STATUS_OK;
1192 /* Just convert the primary group SID into a group */
1193 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1194 TALLOC_CTX *mem_ctx,
1195 struct samu *user,
1196 struct dom_sid **pp_sids,
1197 gid_t **pp_gids,
1198 uint32_t *p_num_groups)
1200 NTSTATUS status;
1201 size_t num_groups = 0;
1202 struct dom_sid *group_sids;
1203 gid_t *gids;
1204 TALLOC_CTX *tmp_ctx;
1206 tmp_ctx = talloc_new(mem_ctx);
1207 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1209 if (user->group_sid) {
1210 struct id_map *id_maps[2];
1211 struct id_map id_map;
1213 num_groups = 1;
1215 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1216 if (group_sids == NULL) {
1217 talloc_free(tmp_ctx);
1218 return NT_STATUS_NO_MEMORY;
1220 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1221 if (gids == NULL) {
1222 talloc_free(tmp_ctx);
1223 return NT_STATUS_NO_MEMORY;
1226 group_sids[0] = *user->group_sid;
1228 ZERO_STRUCT(id_map);
1229 id_map.sid = &group_sids[0];
1230 id_maps[0] = &id_map;
1231 id_maps[1] = NULL;
1233 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1234 if (!NT_STATUS_IS_OK(status)) {
1235 talloc_free(tmp_ctx);
1236 return status;
1238 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1239 gids[0] = id_map.xid.id;
1240 } else {
1241 DEBUG(1, (__location__
1242 "Group %s, of which %s is a member, could not be converted to a GID\n",
1243 dom_sid_string(tmp_ctx, &group_sids[0]),
1244 dom_sid_string(tmp_ctx, &user->user_sid)));
1245 talloc_free(tmp_ctx);
1246 /* We must error out, otherwise a user might
1247 * avoid a DENY acl based on a group they
1248 * missed out on */
1249 return NT_STATUS_NO_SUCH_GROUP;
1253 *pp_sids = talloc_steal(mem_ctx, group_sids);
1254 *pp_gids = talloc_steal(mem_ctx, gids);
1255 *p_num_groups = num_groups;
1256 talloc_free(tmp_ctx);
1257 return NT_STATUS_OK;
1260 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1261 TALLOC_CTX *mem_ctx,
1262 struct samu *user,
1263 struct dom_sid **pp_sids,
1264 gid_t **pp_gids,
1265 uint32_t *p_num_groups)
1267 struct pdb_samba4_state *state = talloc_get_type_abort(
1268 m->private_data, struct pdb_samba4_state);
1269 struct ldb_message *msg = pdb_samba4_get_samu_private(
1270 m, user);
1271 const char *attrs[] = { "tokenGroups", NULL};
1272 struct ldb_message *tokengroups_msg;
1273 struct ldb_message_element *tokengroups;
1274 int i, rc;
1275 NTSTATUS status;
1276 unsigned int count = 0;
1277 size_t num_groups;
1278 struct dom_sid *group_sids;
1279 gid_t *gids;
1280 TALLOC_CTX *tmp_ctx;
1282 if (msg == NULL) {
1283 /* Fake up some things here */
1284 return fake_enum_group_memberships(state,
1285 mem_ctx,
1286 user, pp_sids,
1287 pp_gids, p_num_groups);
1290 tmp_ctx = talloc_new(mem_ctx);
1291 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1293 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1295 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1296 talloc_free(tmp_ctx);
1297 return NT_STATUS_NO_SUCH_USER;
1298 } else if (rc != LDB_SUCCESS) {
1299 DEBUG(10, ("dsdb_search_one failed %s\n",
1300 ldb_errstring(state->ldb)));
1301 talloc_free(tmp_ctx);
1302 return NT_STATUS_LDAP(rc);
1305 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1307 if (tokengroups) {
1308 count = tokengroups->num_values;
1311 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1312 if (group_sids == NULL) {
1313 talloc_free(tmp_ctx);
1314 return NT_STATUS_NO_MEMORY;
1316 gids = talloc_array(tmp_ctx, gid_t, count);
1317 if (gids == NULL) {
1318 talloc_free(tmp_ctx);
1319 return NT_STATUS_NO_MEMORY;
1321 num_groups = 0;
1323 for (i=0; i<count; i++) {
1324 struct id_map *id_maps[2];
1325 struct id_map id_map;
1326 struct ldb_val *v = &tokengroups->values[i];
1327 enum ndr_err_code ndr_err
1328 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1329 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1330 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1331 talloc_free(tmp_ctx);
1332 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1335 ZERO_STRUCT(id_map);
1336 id_map.sid = &group_sids[num_groups];
1337 id_maps[0] = &id_map;
1338 id_maps[1] = NULL;
1340 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1341 if (!NT_STATUS_IS_OK(status)) {
1342 talloc_free(tmp_ctx);
1343 return status;
1345 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1346 gids[num_groups] = id_map.xid.id;
1347 } else {
1348 DEBUG(1, (__location__
1349 "Group %s, of which %s is a member, could not be converted to a GID\n",
1350 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1351 ldb_dn_get_linearized(msg->dn)));
1352 talloc_free(tmp_ctx);
1353 /* We must error out, otherwise a user might
1354 * avoid a DENY acl based on a group they
1355 * missed out on */
1356 return NT_STATUS_NO_SUCH_GROUP;
1359 num_groups += 1;
1360 if (num_groups == count) {
1361 break;
1365 *pp_sids = talloc_steal(mem_ctx, group_sids);
1366 *pp_gids = talloc_steal(mem_ctx, gids);
1367 *p_num_groups = num_groups;
1368 talloc_free(tmp_ctx);
1369 return NT_STATUS_OK;
1372 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1373 TALLOC_CTX *mem_ctx,
1374 struct samu *user)
1376 return NT_STATUS_NOT_IMPLEMENTED;
1379 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1380 TALLOC_CTX *mem_ctx,
1381 const struct dom_sid *groupsid,
1382 const struct dom_sid *membersid,
1383 int mod_op)
1385 struct pdb_samba4_state *state = talloc_get_type_abort(
1386 m->private_data, struct pdb_samba4_state);
1387 struct ldb_message *msg;
1388 int ret;
1389 struct ldb_message_element *el;
1390 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1391 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1392 msg = ldb_msg_new(tmp_ctx);
1393 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1395 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1396 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1397 talloc_free(tmp_ctx);
1398 return NT_STATUS_NO_MEMORY;
1400 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1401 if (ret != LDB_SUCCESS) {
1402 talloc_free(tmp_ctx);
1403 return NT_STATUS_NO_MEMORY;
1405 el = ldb_msg_find_element(msg, "member");
1406 el->flags = mod_op;
1408 /* No need for transactions here, the ldb auto-transaction
1409 * code will handle things for the single operation */
1410 ret = ldb_modify(state->ldb, msg);
1411 talloc_free(tmp_ctx);
1412 if (ret != LDB_SUCCESS) {
1413 DEBUG(10, ("ldb_modify failed: %s\n",
1414 ldb_errstring(state->ldb)));
1415 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1416 return NT_STATUS_MEMBER_IN_GROUP;
1418 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1419 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1421 return NT_STATUS_LDAP(ret);
1424 return NT_STATUS_OK;
1427 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1428 TALLOC_CTX *mem_ctx,
1429 uint32 grouprid, uint32 memberrid,
1430 int mod_op)
1432 struct pdb_samba4_state *state = talloc_get_type_abort(
1433 m->private_data, struct pdb_samba4_state);
1434 const struct dom_sid *dom_sid, *groupsid, *membersid;
1435 NTSTATUS status;
1436 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1437 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1439 dom_sid = samdb_domain_sid(state->ldb);
1441 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1442 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1443 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1444 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1445 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1446 talloc_free(tmp_ctx);
1447 return status;
1450 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1451 TALLOC_CTX *mem_ctx,
1452 uint32 group_rid, uint32 member_rid)
1454 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1455 LDB_FLAG_MOD_ADD);
1458 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1459 TALLOC_CTX *mem_ctx,
1460 uint32 group_rid, uint32 member_rid)
1462 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1463 LDB_FLAG_MOD_DELETE);
1466 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1467 const char *name, uint32 *rid)
1469 TALLOC_CTX *frame = talloc_stackframe();
1470 struct pdb_samba4_state *state = talloc_get_type_abort(
1471 m->private_data, struct pdb_samba4_state);
1472 struct dom_sid *sid;
1474 struct ldb_dn *dn;
1475 NTSTATUS status;
1477 /* Internally this uses transactions to ensure all the steps
1478 * happen or fail as one */
1479 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1480 if (!NT_STATUS_IS_OK(status)) {
1481 TALLOC_FREE(frame);
1484 sid_peek_rid(sid, rid);
1485 TALLOC_FREE(frame);
1486 return NT_STATUS_OK;
1489 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1490 const struct dom_sid *sid)
1492 const char *attrs[] = { NULL };
1493 struct pdb_samba4_state *state = talloc_get_type_abort(
1494 m->private_data, struct pdb_samba4_state);
1495 struct ldb_message *msg;
1496 struct ldb_dn *dn;
1497 int rc;
1498 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1499 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1501 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1502 if (!dn || !ldb_dn_validate(dn)) {
1503 talloc_free(tmp_ctx);
1504 return NT_STATUS_NO_MEMORY;
1507 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1508 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1509 return NT_STATUS_INTERNAL_ERROR;
1512 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1513 "(|(grouptype=%d)(grouptype=%d)))",
1514 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1515 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1516 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1517 talloc_free(tmp_ctx);
1518 ldb_transaction_cancel(state->ldb);
1519 return NT_STATUS_NO_SUCH_ALIAS;
1521 rc = ldb_delete(state->ldb, dn);
1522 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1523 talloc_free(tmp_ctx);
1524 ldb_transaction_cancel(state->ldb);
1525 return NT_STATUS_NO_SUCH_ALIAS;
1526 } else if (rc != LDB_SUCCESS) {
1527 DEBUG(10, ("ldb_delete failed %s\n",
1528 ldb_errstring(state->ldb)));
1529 ldb_transaction_cancel(state->ldb);
1530 return NT_STATUS_LDAP(rc);
1533 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1534 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1535 ldb_errstring(state->ldb)));
1536 return NT_STATUS_INTERNAL_ERROR;
1539 return NT_STATUS_OK;
1542 #if 0
1543 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1544 const struct dom_sid *sid,
1545 struct acct_info *info)
1547 struct pdb_samba4_state *state = talloc_get_type_abort(
1548 m->private_data, struct pdb_samba4_state);
1549 struct tldap_context *ld;
1550 const char *attrs[3] = { "objectSid", "description",
1551 "samAccountName" };
1552 struct ldb_message **msg;
1553 char *sidstr, *dn;
1554 int rc;
1555 struct tldap_mod *mods;
1556 int num_mods;
1557 bool ok;
1559 ld = pdb_samba4_ld(state);
1560 if (ld == NULL) {
1561 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1564 sidstr = sid_binstring(talloc_tos(), sid);
1565 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1567 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1568 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1569 &msg, "(&(objectSid=%s)(objectclass=group)"
1570 "(|(grouptype=%d)(grouptype=%d)))",
1571 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1572 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1573 TALLOC_FREE(sidstr)
1574 if (rc != LDB_SUCCESS) {
1575 DEBUG(10, ("ldap_search failed %s\n",
1576 ldb_errstring(state->ldb)));
1577 return NT_STATUS_LDAP(rc);
1579 switch talloc_array_length(msg) {
1580 case 0:
1581 return NT_STATUS_NO_SUCH_ALIAS;
1582 case 1:
1583 break;
1584 default:
1585 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1588 if (!tldap_entry_dn(msg[0], &dn)) {
1589 TALLOC_FREE(msg);
1590 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1593 mods = NULL;
1594 num_mods = 0;
1595 ok = true;
1597 ok &= tldap_make_mod_fmt(
1598 msg[0], msg, &num_mods, &mods, "description",
1599 "%s", info->acct_desc);
1600 ok &= tldap_make_mod_fmt(
1601 msg[0], msg, &num_mods, &mods, "samAccountName",
1602 "%s", info->acct_name);
1603 if (!ok) {
1604 TALLOC_FREE(msg);
1605 return NT_STATUS_NO_MEMORY;
1607 if (num_mods == 0) {
1608 /* no change */
1609 TALLOC_FREE(msg);
1610 return NT_STATUS_OK;
1613 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1614 TALLOC_FREE(msg);
1615 if (rc != LDB_SUCCESS) {
1616 DEBUG(10, ("ldap_modify failed: %s\n",
1617 ldb_errstring(state->ldb)));
1618 return NT_STATUS_LDAP(rc);
1620 return NT_STATUS_OK;
1622 #endif
1623 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1624 const struct dom_sid *alias,
1625 const struct dom_sid *member)
1627 NTSTATUS status;
1628 TALLOC_CTX *frame = talloc_stackframe();
1629 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1630 talloc_free(frame);
1631 return status;
1634 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1635 const struct dom_sid *alias,
1636 const struct dom_sid *member)
1638 NTSTATUS status;
1639 TALLOC_CTX *frame = talloc_stackframe();
1640 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1641 talloc_free(frame);
1642 return status;
1645 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1646 const struct dom_sid *alias,
1647 TALLOC_CTX *mem_ctx,
1648 struct dom_sid **pmembers,
1649 size_t *pnum_members)
1651 struct pdb_samba4_state *state = talloc_get_type_abort(
1652 m->private_data, struct pdb_samba4_state);
1653 struct ldb_dn *dn;
1654 unsigned int num_members;
1655 NTSTATUS status;
1656 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1657 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1659 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1660 if (!dn || !ldb_dn_validate(dn)) {
1661 return NT_STATUS_NO_MEMORY;
1664 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1665 *pnum_members = num_members;
1666 if (NT_STATUS_IS_OK(status)) {
1667 talloc_steal(mem_ctx, pmembers);
1669 talloc_free(tmp_ctx);
1670 return status;
1673 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1674 TALLOC_CTX *mem_ctx,
1675 const struct dom_sid *domain_sid,
1676 const struct dom_sid *members,
1677 size_t num_members,
1678 uint32_t **palias_rids,
1679 size_t *pnum_alias_rids)
1681 struct pdb_samba4_state *state = talloc_get_type_abort(
1682 m->private_data, struct pdb_samba4_state);
1683 uint32_t *alias_rids = NULL;
1684 size_t num_alias_rids = 0;
1685 int i;
1686 struct dom_sid *groupSIDs = NULL;
1687 unsigned int num_groupSIDs = 0;
1688 char *filter;
1689 NTSTATUS status;
1690 const char *sid_string;
1691 const char *sid_dn;
1692 DATA_BLOB sid_blob;
1694 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1695 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1697 * TODO: Get the filter right so that we only get the aliases from
1698 * either the SAM or BUILTIN
1701 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1702 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1703 if (filter == NULL) {
1704 return NT_STATUS_NO_MEMORY;
1707 for (i = 0; i < num_members; i++) {
1708 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1709 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1711 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1712 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1714 sid_blob = data_blob_string_const(sid_dn);
1716 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1717 tmp_ctx, &groupSIDs, &num_groupSIDs);
1718 if (!NT_STATUS_IS_OK(status)) {
1719 talloc_free(tmp_ctx);
1720 return status;
1724 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1725 if (alias_rids == NULL) {
1726 talloc_free(tmp_ctx);
1727 return NT_STATUS_NO_MEMORY;
1730 for (i=0; i<num_groupSIDs; i++) {
1731 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1732 &alias_rids[num_alias_rids])) {
1733 num_alias_rids++;;
1737 *palias_rids = alias_rids;
1738 *pnum_alias_rids = num_alias_rids;
1739 return NT_STATUS_OK;
1742 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1743 const struct dom_sid *domain_sid,
1744 int num_rids,
1745 uint32 *rids,
1746 const char **names,
1747 enum lsa_SidType *lsa_attrs)
1749 struct pdb_samba4_state *state = talloc_get_type_abort(
1750 m->private_data, struct pdb_samba4_state);
1751 NTSTATUS status;
1753 TALLOC_CTX *tmp_ctx;
1755 if (num_rids == 0) {
1756 return NT_STATUS_NONE_MAPPED;
1759 tmp_ctx = talloc_stackframe();
1760 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1762 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1763 talloc_free(tmp_ctx);
1764 return status;
1767 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1768 const struct dom_sid *domain_sid,
1769 int num_names,
1770 const char **pp_names,
1771 uint32 *rids,
1772 enum lsa_SidType *attrs)
1774 return NT_STATUS_NOT_IMPLEMENTED;
1777 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1778 enum pdb_policy_type type,
1779 uint32_t *value)
1781 return account_policy_get(type, value)
1782 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1785 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1786 enum pdb_policy_type type,
1787 uint32_t value)
1789 return account_policy_set(type, value)
1790 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1793 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1794 time_t *seq_num_out)
1796 struct pdb_samba4_state *state = talloc_get_type_abort(
1797 m->private_data, struct pdb_samba4_state);
1798 uint64_t seq_num;
1799 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1800 if (ret == LDB_SUCCESS) {
1801 *seq_num_out = seq_num;
1802 return NT_STATUS_OK;
1803 } else {
1804 return NT_STATUS_UNSUCCESSFUL;
1808 struct pdb_samba4_search_state {
1809 uint32_t acct_flags;
1810 struct samr_displayentry *entries;
1811 uint32_t num_entries;
1812 ssize_t array_size;
1813 uint32_t current;
1816 static bool pdb_samba4_next_entry(struct pdb_search *search,
1817 struct samr_displayentry *entry)
1819 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1820 search->private_data, struct pdb_samba4_search_state);
1822 if (state->current == state->num_entries) {
1823 return false;
1826 entry->idx = state->entries[state->current].idx;
1827 entry->rid = state->entries[state->current].rid;
1828 entry->acct_flags = state->entries[state->current].acct_flags;
1830 entry->account_name = talloc_strdup(
1831 search, state->entries[state->current].account_name);
1832 entry->fullname = talloc_strdup(
1833 search, state->entries[state->current].fullname);
1834 entry->description = talloc_strdup(
1835 search, state->entries[state->current].description);
1837 state->current += 1;
1838 return true;
1841 static void pdb_samba4_search_end(struct pdb_search *search)
1843 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1844 search->private_data, struct pdb_samba4_search_state);
1845 talloc_free(state);
1848 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1849 struct pdb_search *search,
1850 struct pdb_samba4_search_state **pstate,
1851 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1853 struct pdb_samba4_state *state = talloc_get_type_abort(
1854 m->private_data, struct pdb_samba4_state);
1855 struct pdb_samba4_search_state *sstate;
1856 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1857 "userAccountControl", "description", NULL };
1858 struct ldb_result *res;
1859 int i, rc, num_users;
1861 va_list ap;
1862 char *expression = NULL;
1864 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1865 if (!tmp_ctx) {
1866 return false;
1869 va_start(ap, exp_fmt);
1870 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1871 va_end(ap);
1873 if (!expression) {
1874 talloc_free(tmp_ctx);
1875 return LDB_ERR_OPERATIONS_ERROR;
1878 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1879 if (sstate == NULL) {
1880 talloc_free(tmp_ctx);
1881 return false;
1884 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1885 if (rc != LDB_SUCCESS) {
1886 talloc_free(tmp_ctx);
1887 DEBUG(10, ("dsdb_search failed: %s\n",
1888 ldb_errstring(state->ldb)));
1889 return false;
1892 num_users = res->count;
1894 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1895 num_users);
1896 if (sstate->entries == NULL) {
1897 talloc_free(tmp_ctx);
1898 DEBUG(10, ("talloc failed\n"));
1899 return false;
1902 sstate->num_entries = 0;
1904 for (i=0; i<num_users; i++) {
1905 struct samr_displayentry *e;
1906 struct dom_sid *sid;
1908 e = &sstate->entries[sstate->num_entries];
1910 e->idx = sstate->num_entries;
1911 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1912 if (!sid) {
1913 talloc_free(tmp_ctx);
1914 DEBUG(10, ("Could not pull SID\n"));
1915 return false;
1917 sid_peek_rid(sid, &e->rid);
1919 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1920 res->msgs[i],
1921 ldb_get_default_basedn(state->ldb));
1922 e->account_name = ldb_msg_find_attr_as_string(
1923 res->msgs[i], "samAccountName", NULL);
1924 if (e->account_name == NULL) {
1925 talloc_free(tmp_ctx);
1926 return false;
1928 e->fullname = ldb_msg_find_attr_as_string(
1929 res->msgs[i], "displayName", "");
1930 e->description = ldb_msg_find_attr_as_string(
1931 res->msgs[i], "description", "");
1933 sstate->num_entries += 1;
1934 if (sstate->num_entries >= num_users) {
1935 break;
1938 talloc_steal(sstate->entries, res->msgs);
1939 search->private_data = talloc_steal(search, sstate);
1940 search->next_entry = pdb_samba4_next_entry;
1941 search->search_end = pdb_samba4_search_end;
1942 *pstate = sstate;
1943 talloc_free(tmp_ctx);
1944 return true;
1947 static bool pdb_samba4_search_users(struct pdb_methods *m,
1948 struct pdb_search *search,
1949 uint32 acct_flags)
1951 struct pdb_samba4_search_state *sstate;
1952 bool ret;
1954 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1955 if (!ret) {
1956 return false;
1958 sstate->acct_flags = acct_flags;
1959 return true;
1962 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1963 struct pdb_search *search)
1965 struct pdb_samba4_search_state *sstate;
1966 bool ret;
1968 ret = pdb_samba4_search_filter(m, search, &sstate,
1969 "(&(grouptype=%d)(objectclass=group))",
1970 GTYPE_SECURITY_GLOBAL_GROUP);
1971 if (!ret) {
1972 return false;
1974 sstate->acct_flags = 0;
1975 return true;
1978 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1979 struct pdb_search *search,
1980 const struct dom_sid *sid)
1982 struct pdb_samba4_search_state *sstate;
1983 bool ret;
1985 ret = pdb_samba4_search_filter(m, search, &sstate,
1986 "(&(grouptype=%d)(objectclass=group))",
1987 sid_check_is_builtin(sid)
1988 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1989 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1990 if (!ret) {
1991 return false;
1993 sstate->acct_flags = 0;
1994 return true;
1997 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1998 struct dom_sid *sid)
2000 struct pdb_samba4_state *state = talloc_get_type_abort(
2001 m->private_data, struct pdb_samba4_state);
2002 NTSTATUS status;
2003 struct id_map id_map;
2004 struct id_map *id_maps[2];
2005 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2006 if (!tmp_ctx) {
2007 return false;
2010 id_map.xid.id = uid;
2011 id_map.xid.type = ID_TYPE_UID;
2012 id_maps[0] = &id_map;
2013 id_maps[1] = NULL;
2015 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2016 if (!NT_STATUS_IS_OK(status)) {
2017 talloc_free(tmp_ctx);
2018 return false;
2020 *sid = *id_map.sid;
2021 talloc_free(tmp_ctx);
2022 return true;
2025 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
2026 struct dom_sid *sid)
2028 struct pdb_samba4_state *state = talloc_get_type_abort(
2029 m->private_data, struct pdb_samba4_state);
2030 NTSTATUS status;
2031 struct id_map id_map;
2032 struct id_map *id_maps[2];
2033 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2034 if (!tmp_ctx) {
2035 return false;
2038 id_map.xid.id = gid;
2039 id_map.xid.type = ID_TYPE_GID;
2040 id_maps[0] = &id_map;
2041 id_maps[1] = NULL;
2043 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2044 if (!NT_STATUS_IS_OK(status)) {
2045 return false;
2047 *sid = *id_map.sid;
2048 talloc_free(tmp_ctx);
2049 return true;
2052 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2053 struct unixid *id)
2055 struct pdb_samba4_state *state = talloc_get_type_abort(
2056 m->private_data, struct pdb_samba4_state);
2057 struct id_map id_map;
2058 struct id_map *id_maps[2];
2059 const char *attrs[] = { "objectClass", NULL };
2060 struct ldb_message *msg;
2061 struct ldb_dn *dn;
2062 NTSTATUS status;
2063 int rc;
2064 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2065 if (!tmp_ctx) {
2066 return false;
2069 ZERO_STRUCT(id_map);
2071 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2072 if (!dn || !ldb_dn_validate(dn)) {
2073 talloc_free(tmp_ctx);
2074 return false;
2076 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2077 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2078 DEBUG(5, (__location__ "SID to Unix ID lookup failed because SID %s could not be found in the samdb\n", dom_sid_string(tmp_ctx, sid)));
2079 talloc_free(tmp_ctx);
2080 return false;
2082 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2083 id->type = ID_TYPE_GID;
2085 ZERO_STRUCT(id_map);
2086 id_map.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_GID || id_map.xid.type == ID_TYPE_BOTH) {
2096 id->id = id_map.xid.id;
2097 return true;
2099 return false;
2100 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2101 id->type = ID_TYPE_UID;
2102 ZERO_STRUCT(id_map);
2103 id_map.sid = sid;
2104 id_maps[0] = &id_map;
2105 id_maps[1] = NULL;
2107 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2108 talloc_free(tmp_ctx);
2109 if (!NT_STATUS_IS_OK(status)) {
2110 return false;
2112 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2113 id->id = id_map.xid.id;
2114 return true;
2116 return false;
2118 DEBUG(5, (__location__ "SID to Unix ID lookup failed because SID %s was found, but was not a user or group\n", dom_sid_string(tmp_ctx, sid)));
2119 talloc_free(tmp_ctx);
2120 return false;
2123 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2125 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2128 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2130 return false;
2133 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2134 const char *domain, char** pwd,
2135 struct dom_sid *sid,
2136 time_t *pass_last_set_time)
2138 return false;
2141 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2142 const char* domain, const char* pwd,
2143 const struct dom_sid *sid)
2145 return false;
2148 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2149 const char *domain)
2151 return false;
2154 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2155 TALLOC_CTX *mem_ctx,
2156 uint32 *num_domains,
2157 struct trustdom_info ***domains)
2159 *num_domains = 0;
2160 *domains = NULL;
2161 return NT_STATUS_OK;
2164 static void pdb_samba4_init_methods(struct pdb_methods *m)
2166 m->name = "samba4";
2167 m->get_domain_info = pdb_samba4_get_domain_info;
2168 m->getsampwnam = pdb_samba4_getsampwnam;
2169 m->getsampwsid = pdb_samba4_getsampwsid;
2170 m->create_user = pdb_samba4_create_user;
2171 m->delete_user = pdb_samba4_delete_user;
2172 m->add_sam_account = pdb_samba4_add_sam_account;
2173 m->update_sam_account = pdb_samba4_update_sam_account;
2174 m->delete_sam_account = pdb_samba4_delete_sam_account;
2175 m->rename_sam_account = pdb_samba4_rename_sam_account;
2176 m->update_login_attempts = pdb_samba4_update_login_attempts;
2177 m->getgrsid = pdb_samba4_getgrsid;
2178 m->getgrgid = pdb_samba4_getgrgid;
2179 m->getgrnam = pdb_samba4_getgrnam;
2180 m->create_dom_group = pdb_samba4_create_dom_group;
2181 m->delete_dom_group = pdb_samba4_delete_dom_group;
2182 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2183 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2184 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2185 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2186 m->enum_group_members = pdb_samba4_enum_group_members;
2187 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2188 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2189 m->add_groupmem = pdb_samba4_add_groupmem;
2190 m->del_groupmem = pdb_samba4_del_groupmem;
2191 m->create_alias = pdb_samba4_create_alias;
2192 m->delete_alias = pdb_samba4_delete_alias;
2193 m->get_aliasinfo = pdb_default_get_aliasinfo;
2194 m->add_aliasmem = pdb_samba4_add_aliasmem;
2195 m->del_aliasmem = pdb_samba4_del_aliasmem;
2196 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2197 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2198 m->lookup_rids = pdb_samba4_lookup_rids;
2199 m->lookup_names = pdb_samba4_lookup_names;
2200 m->get_account_policy = pdb_samba4_get_account_policy;
2201 m->set_account_policy = pdb_samba4_set_account_policy;
2202 m->get_seq_num = pdb_samba4_get_seq_num;
2203 m->search_users = pdb_samba4_search_users;
2204 m->search_groups = pdb_samba4_search_groups;
2205 m->search_aliases = pdb_samba4_search_aliases;
2206 m->uid_to_sid = pdb_samba4_uid_to_sid;
2207 m->gid_to_sid = pdb_samba4_gid_to_sid;
2208 m->sid_to_id = pdb_samba4_sid_to_id;
2209 m->capabilities = pdb_samba4_capabilities;
2210 m->new_rid = pdb_samba4_new_rid;
2211 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2212 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2213 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2214 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2217 static void free_private_data(void **vp)
2219 struct pdb_samba4_state *state = talloc_get_type_abort(
2220 *vp, struct pdb_samba4_state);
2221 talloc_unlink(state, state->ldb);
2222 return;
2225 static NTSTATUS pdb_samba4_init_secrets(struct pdb_methods *m)
2227 struct pdb_domain_info *dom_info;
2228 bool ret;
2230 dom_info = pdb_samba4_get_domain_info(m, m);
2231 if (!dom_info) {
2232 return NT_STATUS_UNSUCCESSFUL;
2235 secrets_clear_domain_protection(dom_info->name);
2236 ret = secrets_store_domain_sid(dom_info->name,
2237 &dom_info->sid);
2238 if (!ret) {
2239 goto done;
2241 ret = secrets_store_domain_guid(dom_info->name,
2242 &dom_info->guid);
2243 if (!ret) {
2244 goto done;
2246 ret = secrets_mark_domain_protected(dom_info->name);
2247 if (!ret) {
2248 goto done;
2251 done:
2252 TALLOC_FREE(dom_info);
2253 if (!ret) {
2254 return NT_STATUS_UNSUCCESSFUL;
2256 return NT_STATUS_OK;
2259 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2260 const char *location)
2262 struct pdb_methods *m;
2263 struct pdb_samba4_state *state;
2264 NTSTATUS status;
2266 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2267 return status;
2270 state = talloc_zero(m, struct pdb_samba4_state);
2271 if (state == NULL) {
2272 goto nomem;
2274 m->private_data = state;
2275 m->free_private_data = free_private_data;
2276 pdb_samba4_init_methods(m);
2278 state->ev = s4_event_context_init(state);
2279 if (!state->ev) {
2280 DEBUG(0, ("s4_event_context_init failed\n"));
2281 goto nomem;
2284 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2285 if (state->lp_ctx == NULL) {
2286 DEBUG(0, ("loadparm_init_s3 failed\n"));
2287 goto nomem;
2290 if (location) {
2291 state->ldb = samdb_connect_url(state,
2292 state->ev,
2293 state->lp_ctx,
2294 system_session(state->lp_ctx),
2295 0, location);
2296 } else {
2297 state->ldb = samdb_connect(state,
2298 state->ev,
2299 state->lp_ctx,
2300 system_session(state->lp_ctx), 0);
2303 if (!state->ldb) {
2304 DEBUG(0, ("samdb_connect failed\n"));
2305 status = NT_STATUS_INTERNAL_ERROR;
2306 goto fail;
2309 state->idmap_ctx = idmap_init(state, state->ev,
2310 state->lp_ctx);
2311 if (!state->idmap_ctx) {
2312 DEBUG(0, ("idmap failed\n"));
2313 status = NT_STATUS_INTERNAL_ERROR;
2314 goto fail;
2317 status = pdb_samba4_init_secrets(m);
2318 if (!NT_STATUS_IS_OK(status)) {
2319 DEBUG(10, ("pdb_samba4_init_secrets failed!\n"));
2320 goto fail;
2323 *pdb_method = m;
2324 return NT_STATUS_OK;
2325 nomem:
2326 status = NT_STATUS_NO_MEMORY;
2327 fail:
2328 TALLOC_FREE(m);
2329 return status;
2332 NTSTATUS pdb_samba4_init(void);
2333 NTSTATUS pdb_samba4_init(void)
2335 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2336 pdb_init_samba4);