s4 dns: Clean up tests a bit
[Samba/gebeck_regimport.git] / source3 / passdb / pdb_samba4.c
blob2b785fa4245cd7fd1620a2fb77394e0cc12ba9cd
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 uid_t *uid, gid_t *gid, enum lsa_SidType *type);
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 int ret = LDB_SUCCESS;
339 const char *pw;
340 struct ldb_message *msg;
341 struct ldb_request *req;
342 uint32_t dsdb_flags = 0;
343 /* TODO: All fields :-) */
345 msg = ldb_msg_new(talloc_tos());
346 if (!msg) {
347 return false;
350 msg->dn = dn;
352 /* build modify request */
353 ret = ldb_build_mod_req(&req, state->ldb, talloc_tos(), msg, NULL, NULL,
354 ldb_op_default_callback,
355 NULL);
356 if (ret != LDB_SUCCESS) {
357 talloc_free(msg);
358 return ret;
361 /* If we set a plaintext password, the system will
362 * force the pwdLastSet to now() */
363 if (need_update(sam, PDB_PASSLASTSET)) {
364 dsdb_flags = DSDB_PASSWORD_BYPASS_LAST_SET;
366 ret |= pdb_samba4_add_time(msg, "pwdLastSet",
367 pdb_get_pass_last_set_time(sam));
370 pw = pdb_get_plaintext_passwd(sam);
371 if (need_update(sam, PDB_PLAINTEXT_PW)) {
372 struct ldb_val pw_utf16;
373 if (pw == NULL) {
374 return LDB_ERR_OPERATIONS_ERROR;
377 if (!convert_string_talloc(msg,
378 CH_UNIX, CH_UTF16,
379 pw, strlen(pw),
380 (void *)&pw_utf16.data,
381 &pw_utf16.length)) {
382 return LDB_ERR_OPERATIONS_ERROR;
384 ret |= ldb_msg_add_value(msg, "clearTextPassword", &pw_utf16, NULL);
385 } else {
386 bool changed_lm_pw = false;
387 bool changed_nt_pw = false;
388 bool changed_history = false;
389 if (need_update(sam, PDB_LMPASSWD)) {
390 struct ldb_val val;
391 val.data = pdb_get_lanman_passwd(sam);
392 if (!val.data) {
393 samdb_msg_add_delete(state->ldb, msg, msg,
394 "dBCSPwd");
395 } else {
396 val.length = LM_HASH_LEN;
397 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
399 changed_lm_pw = true;
401 if (need_update(sam, PDB_NTPASSWD)) {
402 struct ldb_val val;
403 val.data = pdb_get_nt_passwd(sam);
404 if (!val.data) {
405 samdb_msg_add_delete(state->ldb, msg, msg,
406 "unicodePwd");
407 } else {
408 val.length = NT_HASH_LEN;
409 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
411 changed_nt_pw = true;
414 /* Try to ensure we don't get out of sync */
415 if (changed_lm_pw && !changed_nt_pw) {
416 samdb_msg_add_delete(state->ldb, msg, msg,
417 "unicodePwd");
418 } else if (changed_nt_pw && !changed_lm_pw) {
419 samdb_msg_add_delete(state->ldb, msg, msg,
420 "dBCSPwd");
422 if (changed_lm_pw || changed_nt_pw) {
423 samdb_msg_add_delete(state->ldb, msg, msg,
424 "supplementalCredentials");
428 if (need_update(sam, PDB_PWHISTORY)) {
429 uint32_t current_hist_len;
430 const uint8_t *history = pdb_get_pw_history(sam, &current_hist_len);
432 bool invalid_history = false;
433 struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
434 current_hist_len);
435 if (!history) {
436 invalid_history = true;
437 } else {
438 unsigned int i;
439 static const uint8_t zeros[16];
440 /* Parse the history into the correct format */
441 for (i = 0; i < current_hist_len; i++) {
442 if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
443 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
444 invalid_history = true;
445 break;
447 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
448 memcpy(history_hashes[i].hash,
449 &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
450 sizeof(history_hashes[i].hash));
453 if (invalid_history) {
454 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
455 "ntPwdHistory");
457 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
458 "lmPwdHistory");
459 } else {
460 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
461 "ntPwdHistory",
462 history_hashes,
463 current_hist_len);
465 changed_history = true;
467 if (changed_lm_pw || changed_nt_pw || changed_history) {
468 /* These attributes can only be modified directly by using a special control */
469 dsdb_flags = DSDB_BYPASS_PASSWORD_HASH;
473 /* PDB_USERSID is only allowed on ADD, handled in caller */
474 if (need_update(sam, PDB_GROUPSID)) {
475 const struct dom_sid *sid = pdb_get_group_sid(sam);
476 uint32_t rid;
477 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
478 if (!NT_STATUS_IS_OK(status)) {
479 return LDB_ERR_OPERATIONS_ERROR;
481 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
482 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
484 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
486 if (need_update(sam, PDB_FULLNAME)) {
487 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
490 if (need_update(sam, PDB_SMBHOME)) {
491 ret |= ldb_msg_add_string(msg, "homeDirectory",
492 pdb_get_homedir(sam));
495 if (need_update(sam, PDB_PROFILE)) {
496 ret |= ldb_msg_add_string(msg, "profilePath",
497 pdb_get_profile_path(sam));
500 if (need_update(sam, PDB_DRIVE)) {
501 ret |= ldb_msg_add_string(msg, "homeDrive",
502 pdb_get_dir_drive(sam));
505 if (need_update(sam, PDB_LOGONSCRIPT)) {
506 ret |= ldb_msg_add_string(msg, "scriptPath",
507 pdb_get_logon_script(sam));
510 if (need_update(sam, PDB_KICKOFFTIME)) {
511 ret |= pdb_samba4_add_time(msg, "accountExpires",
512 pdb_get_kickoff_time(sam));
515 if (need_update(sam, PDB_USERNAME)) {
516 ret |= ldb_msg_add_string(msg, "samAccountName",
517 pdb_get_username(sam));
520 if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
521 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
522 ret |= ldb_msg_add_value(msg, "logonHours",
523 &hours, NULL);
526 if (need_update(sam, PDB_ACCTCTRL)) {
527 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
528 "userAccountControl", pdb_get_acct_ctrl(sam));
531 if (need_update(sam, PDB_COMMENT)) {
532 ret |= ldb_msg_add_string(msg, "comment",
533 pdb_get_comment(sam));
536 if (need_update(sam, PDB_ACCTDESC)) {
537 ret |= ldb_msg_add_string(msg, "description",
538 pdb_get_acct_desc(sam));
541 if (need_update(sam, PDB_WORKSTATIONS)) {
542 ret |= ldb_msg_add_string(msg, "userWorkstations",
543 pdb_get_workstations(sam));
546 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
547 if (need_update(sam, PDB_MUNGEDDIAL)) {
548 ret |= ldb_msg_add_string(msg, "userParameters",
549 pdb_get_munged_dial(sam));
552 if (need_update(sam, PDB_COUNTRY_CODE)) {
553 ret |= ldb_msg_add_fmt(msg, "countryCode",
554 "%i", (int)pdb_get_country_code(sam));
557 if (need_update(sam, PDB_CODE_PAGE)) {
558 ret |= ldb_msg_add_fmt(msg, "codePage",
559 "%i", (int)pdb_get_code_page(sam));
562 /* Not yet handled here or not meaningful for modifies on a Samba4 backend:
563 PDB_LOGONTIME,
564 PDB_LOGOFFTIME,
565 PDB_BAD_PASSWORD_TIME,
566 PDB_CANCHANGETIME, - these are calculated per policy, not stored
567 PDB_MUSTCHANGETIME, - these are calculated per policy, not stored
568 PDB_DOMAIN,
569 PDB_NTUSERNAME, - this makes no sense, and never really did
570 PDB_LOGONDIVS,
571 PDB_USERSID, - Handled in pdb_samba4_add_sam_account()
572 PDB_FIELDS_PRESENT,
573 PDB_BAD_PASSWORD_COUNT,
574 PDB_LOGON_COUNT,
575 PDB_UNKNOWN6,
576 PDB_BACKEND_PRIVATE_DATA,
579 if (ret != LDB_SUCCESS) {
580 return LDB_ERR_OPERATIONS_ERROR;
583 if (msg->num_elements == 0) {
584 /* Nothing to do, just return success */
585 return LDB_SUCCESS;
588 ret = dsdb_replace(state->ldb, msg, dsdb_flags);
590 if (ret != LDB_SUCCESS) {
591 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
592 ldb_dn_get_linearized(msg->dn),
593 ldb_errstring(state->ldb)));
596 return ret;
599 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
600 const char *filter,
601 TALLOC_CTX *mem_ctx,
602 struct ldb_message **msg)
604 const char * attrs[] = {
605 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
606 "sAMAccountName", "displayName", "homeDirectory",
607 "homeDrive", "scriptPath", "profilePath", "description",
608 "userWorkstations", "comment", "userParameters", "objectSid",
609 "primaryGroupID", "userAccountControl", "logonHours",
610 "badPwdCount", "logonCount", "countryCode", "codePage",
611 "unicodePwd", "dBCSPwd", NULL };
613 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
614 if (rc != LDB_SUCCESS) {
615 DEBUG(10, ("ldap_search failed %s\n",
616 ldb_errstring(state->ldb)));
617 return NT_STATUS_LDAP(rc);
620 return NT_STATUS_OK;
623 static NTSTATUS pdb_samba4_getsampwfilter(struct pdb_methods *m,
624 struct pdb_samba4_state *state,
625 struct samu *sam_acct,
626 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
628 struct ldb_message *priv;
629 NTSTATUS status;
630 va_list ap;
631 char *expression = NULL;
632 TALLOC_CTX *tmp_ctx = talloc_new(state);
633 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
635 va_start(ap, exp_fmt);
636 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
637 va_end(ap);
639 if (!expression) {
640 talloc_free(tmp_ctx);
641 return NT_STATUS_NO_MEMORY;
644 status = pdb_samba4_getsamupriv(state, expression, sam_acct, &priv);
645 talloc_free(tmp_ctx);
646 if (!NT_STATUS_IS_OK(status)) {
647 DEBUG(10, ("pdb_samba4_getsamupriv failed: %s\n",
648 nt_errstr(status)));
649 return status;
652 status = pdb_samba4_init_sam_from_priv(m, sam_acct, priv);
653 if (!NT_STATUS_IS_OK(status)) {
654 DEBUG(10, ("pdb_samba4_init_sam_from_priv failed: %s\n",
655 nt_errstr(status)));
656 TALLOC_FREE(priv);
657 return status;
660 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
661 return NT_STATUS_OK;
664 static NTSTATUS pdb_samba4_getsampwnam(struct pdb_methods *m,
665 struct samu *sam_acct,
666 const char *username)
668 struct pdb_samba4_state *state = talloc_get_type_abort(
669 m->private_data, struct pdb_samba4_state);
671 return pdb_samba4_getsampwfilter(m, state, sam_acct,
672 "(&(samaccountname=%s)(objectclass=user))",
673 username);
676 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
677 struct samu *sam_acct,
678 const struct dom_sid *sid)
680 NTSTATUS status;
681 struct pdb_samba4_state *state = talloc_get_type_abort(
682 m->private_data, struct pdb_samba4_state);
683 char *sidstr;
685 sidstr = dom_sid_string(talloc_tos(), sid);
686 NT_STATUS_HAVE_NO_MEMORY(sidstr);
688 status = pdb_samba4_getsampwfilter(m, state, sam_acct,
689 "(&(objectsid=%s)(objectclass=user))",
690 sidstr);
691 talloc_free(sidstr);
692 return status;
695 static NTSTATUS pdb_samba4_create_user(struct pdb_methods *m,
696 TALLOC_CTX *mem_ctx,
697 const char *name, uint32 acct_flags,
698 uint32 *rid)
700 struct pdb_samba4_state *state = talloc_get_type_abort(
701 m->private_data, struct pdb_samba4_state);
702 struct dom_sid *sid;
703 struct ldb_dn *dn;
704 NTSTATUS status;
705 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
706 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
708 /* Internally this uses transactions to ensure all the steps
709 * happen or fail as one */
710 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
711 &sid, &dn);
712 if (!NT_STATUS_IS_OK(status)) {
713 talloc_free(tmp_ctx);
714 return status;
716 sid_peek_rid(sid, rid);
717 talloc_free(tmp_ctx);
718 return NT_STATUS_OK;
721 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
722 TALLOC_CTX *mem_ctx,
723 struct samu *sam)
725 struct pdb_samba4_state *state = talloc_get_type_abort(
726 m->private_data, struct pdb_samba4_state);
727 struct ldb_dn *dn;
728 int rc;
729 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
730 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
732 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
733 if (!dn || !ldb_dn_validate(dn)) {
734 talloc_free(tmp_ctx);
735 return NT_STATUS_NO_MEMORY;
737 rc = ldb_delete(state->ldb, dn);
739 if (rc != LDB_SUCCESS) {
740 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
741 ldb_errstring(state->ldb)));
742 talloc_free(tmp_ctx);
743 return NT_STATUS_LDAP(rc);
745 talloc_free(tmp_ctx);
746 return NT_STATUS_OK;
749 /* This interface takes a fully populated struct samu and places it in
750 * the database. This is not implemented at this time as we need to
751 * be careful around the creation of arbitary SIDs (ie, we must ensrue
752 * they are not left in a RID pool */
753 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
754 struct samu *sampass)
756 int ret;
757 NTSTATUS status;
758 struct ldb_dn *dn;
759 struct pdb_samba4_state *state = talloc_get_type_abort(
760 m->private_data, struct pdb_samba4_state);
761 uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
762 const char *username = pdb_get_username(sampass);
763 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
764 TALLOC_CTX *tframe = talloc_stackframe();
766 acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
768 ret = ldb_transaction_start(state->ldb);
769 if (ret != LDB_SUCCESS) {
770 talloc_free(tframe);
771 return NT_STATUS_LOCK_NOT_GRANTED;
774 status = dsdb_add_user(state->ldb, talloc_tos(), username,
775 acb_flags, user_sid, NULL, &dn);
776 if (!NT_STATUS_IS_OK(status)) {
777 ldb_transaction_cancel(state->ldb);
778 talloc_free(tframe);
779 return status;
782 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_set_or_changed,
783 dn, sampass);
784 if (ret != LDB_SUCCESS) {
785 ldb_transaction_cancel(state->ldb);
786 talloc_free(tframe);
787 return dsdb_ldb_err_to_ntstatus(ret);
790 ret = ldb_transaction_commit(state->ldb);
791 if (ret != LDB_SUCCESS) {
792 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
793 ldb_dn_get_linearized(dn),
794 ldb_errstring(state->ldb)));
795 talloc_free(tframe);
796 return NT_STATUS_INTERNAL_DB_CORRUPTION;
798 talloc_free(tframe);
799 return NT_STATUS_OK;
803 * Update the Samba4 LDB with the changes from a struct samu.
805 * This takes care not to update elements that have not been changed
806 * by the caller
808 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
809 struct samu *sam)
811 struct pdb_samba4_state *state = talloc_get_type_abort(
812 m->private_data, struct pdb_samba4_state);
813 struct ldb_message *msg = pdb_samba4_get_samu_private(
814 m, sam);
815 int ret;
817 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_changed, msg->dn,
818 sam);
819 return dsdb_ldb_err_to_ntstatus(ret);
822 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
823 struct samu *username)
825 NTSTATUS status;
826 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
827 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
828 status = pdb_samba4_delete_user(m, tmp_ctx, username);
829 talloc_free(tmp_ctx);
830 return status;
833 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
834 struct samu *oldname,
835 const char *newname)
837 return NT_STATUS_NOT_IMPLEMENTED;
840 /* This is not implemented, as this module is exptected to be used
841 * with auth_samba4, and this is responible for login counters etc
844 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
845 struct samu *sam_acct,
846 bool success)
848 return NT_STATUS_NOT_IMPLEMENTED;
851 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
852 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
854 struct pdb_samba4_state *state = talloc_get_type_abort(
855 m->private_data, struct pdb_samba4_state);
856 const char *attrs[] = { "objectSid", "description", "samAccountName",
857 NULL };
858 struct ldb_message *msg;
859 va_list ap;
860 char *expression = NULL;
861 struct dom_sid *sid;
862 const char *str;
863 int rc;
864 uid_t uid;
865 TALLOC_CTX *tmp_ctx = talloc_stackframe();
866 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
868 va_start(ap, exp_fmt);
869 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
870 va_end(ap);
872 if (!expression) {
873 talloc_free(tmp_ctx);
874 return NT_STATUS_NO_MEMORY;
877 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
878 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
879 talloc_free(tmp_ctx);
880 return NT_STATUS_NO_SUCH_GROUP;
881 } else if (rc != LDB_SUCCESS) {
882 talloc_free(tmp_ctx);
883 DEBUG(10, ("dsdb_search_one failed %s\n",
884 ldb_errstring(state->ldb)));
885 return NT_STATUS_LDAP(rc);
888 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
889 if (!sid) {
890 talloc_free(tmp_ctx);
891 DEBUG(10, ("Could not pull SID\n"));
892 return NT_STATUS_INTERNAL_DB_CORRUPTION;
895 map->sid = *sid;
897 if (!pdb_samba4_sid_to_id(m, sid, &uid, &map->gid, &map->sid_name_use)) {
898 talloc_free(tmp_ctx);
899 return NT_STATUS_NO_SUCH_GROUP;
901 if (map->sid_name_use == SID_NAME_USER) {
902 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
903 return NT_STATUS_INTERNAL_DB_CORRUPTION;
906 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
907 NULL);
908 if (str == NULL) {
909 talloc_free(tmp_ctx);
910 return NT_STATUS_INTERNAL_DB_CORRUPTION;
912 map->nt_name = talloc_strdup(map, str);
913 if (!map->nt_name) {
914 talloc_free(tmp_ctx);
915 return NT_STATUS_NO_MEMORY;
918 str = ldb_msg_find_attr_as_string(msg, "description",
919 NULL);
920 if (str != NULL) {
921 map->comment = talloc_strdup(map, str);
922 } else {
923 map->comment = talloc_strdup(map, "");
925 if (!map->comment) {
926 talloc_free(tmp_ctx);
927 return NT_STATUS_NO_MEMORY;
930 talloc_free(tmp_ctx);
931 return NT_STATUS_OK;
934 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
935 struct dom_sid sid)
937 char *filter;
938 NTSTATUS status;
940 filter = talloc_asprintf(talloc_tos(),
941 "(&(objectsid=%s)(objectclass=group))",
942 sid_string_talloc(talloc_tos(), &sid));
943 if (filter == NULL) {
944 return NT_STATUS_NO_MEMORY;
947 status = pdb_samba4_getgrfilter(m, map, filter);
948 TALLOC_FREE(filter);
949 return status;
952 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
953 gid_t gid)
955 struct pdb_samba4_state *state = talloc_get_type_abort(
956 m->private_data, struct pdb_samba4_state);
957 NTSTATUS status;
958 struct id_map id_map;
959 struct id_map *id_maps[2];
960 TALLOC_CTX *tmp_ctx = talloc_stackframe();
961 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
963 id_map.xid.id = gid;
964 id_map.xid.type = ID_TYPE_GID;
965 id_maps[0] = &id_map;
966 id_maps[1] = NULL;
968 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
969 if (!NT_STATUS_IS_OK(status)) {
970 return status;
972 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
973 talloc_free(tmp_ctx);
974 return status;
977 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
978 const char *name)
980 char *filter;
981 NTSTATUS status;
983 filter = talloc_asprintf(talloc_tos(),
984 "(&(samaccountname=%s)(objectclass=group))",
985 name);
986 if (filter == NULL) {
987 return NT_STATUS_NO_MEMORY;
990 status = pdb_samba4_getgrfilter(m, map, filter);
991 TALLOC_FREE(filter);
992 return status;
995 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
996 TALLOC_CTX *mem_ctx, const char *name,
997 uint32 *rid)
999 struct pdb_samba4_state *state = talloc_get_type_abort(
1000 m->private_data, struct pdb_samba4_state);
1001 NTSTATUS status;
1002 struct dom_sid *sid;
1003 struct ldb_dn *dn;
1004 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1005 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1007 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1008 if (!NT_STATUS_IS_OK(status)) {
1009 talloc_free(tmp_ctx);
1010 return status;
1013 sid_peek_rid(sid, rid);
1014 talloc_free(tmp_ctx);
1015 return NT_STATUS_OK;
1018 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1019 TALLOC_CTX *mem_ctx, uint32 rid)
1021 const char *attrs[] = { NULL };
1022 struct pdb_samba4_state *state = talloc_get_type_abort(
1023 m->private_data, struct pdb_samba4_state);
1024 struct dom_sid sid;
1025 struct ldb_message *msg;
1026 struct ldb_dn *dn;
1027 int rc;
1028 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1029 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1031 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1033 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1034 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1035 return NT_STATUS_INTERNAL_ERROR;
1038 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1039 if (!dn || !ldb_dn_validate(dn)) {
1040 talloc_free(tmp_ctx);
1041 ldb_transaction_cancel(state->ldb);
1042 return NT_STATUS_NO_MEMORY;
1044 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1045 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1046 talloc_free(tmp_ctx);
1047 ldb_transaction_cancel(state->ldb);
1048 return NT_STATUS_NO_SUCH_GROUP;
1050 rc = ldb_delete(state->ldb, dn);
1051 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1052 talloc_free(tmp_ctx);
1053 ldb_transaction_cancel(state->ldb);
1054 return NT_STATUS_NO_SUCH_GROUP;
1055 } else if (rc != LDB_SUCCESS) {
1056 DEBUG(10, ("ldb_delete failed %s\n",
1057 ldb_errstring(state->ldb)));
1058 ldb_transaction_cancel(state->ldb);
1059 return NT_STATUS_LDAP(rc);
1062 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1063 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1064 return NT_STATUS_INTERNAL_ERROR;
1066 return NT_STATUS_OK;
1069 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1070 GROUP_MAP *map)
1072 return NT_STATUS_NOT_IMPLEMENTED;
1075 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1076 GROUP_MAP *map)
1078 return NT_STATUS_NOT_IMPLEMENTED;
1081 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1082 struct dom_sid sid)
1084 return NT_STATUS_NOT_IMPLEMENTED;
1087 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1088 const struct dom_sid *sid,
1089 enum lsa_SidType sid_name_use,
1090 GROUP_MAP ***pp_rmap,
1091 size_t *p_num_entries,
1092 bool unix_only)
1094 return NT_STATUS_NOT_IMPLEMENTED;
1097 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1098 TALLOC_CTX *mem_ctx,
1099 const struct dom_sid *group,
1100 uint32_t **pmembers,
1101 size_t *pnum_members)
1103 unsigned int i, num_sids, num_members;
1104 struct pdb_samba4_state *state = talloc_get_type_abort(
1105 m->private_data, struct pdb_samba4_state);
1106 struct dom_sid *members_as_sids;
1107 struct dom_sid *dom_sid;
1108 uint32_t *members;
1109 struct ldb_dn *dn;
1110 NTSTATUS status;
1112 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1113 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1115 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1116 if (!dn || !ldb_dn_validate(dn)) {
1117 return NT_STATUS_NO_MEMORY;
1120 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1121 if (!NT_STATUS_IS_OK(status)) {
1122 talloc_free(tmp_ctx);
1123 return status;
1125 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1126 if (!NT_STATUS_IS_OK(status)) {
1127 talloc_free(tmp_ctx);
1128 return status;
1131 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1132 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1133 num_members = 0;
1135 for (i = 0; i < num_sids; i++) {
1136 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1137 continue;
1139 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1140 NULL, &members[num_members]);
1141 if (!NT_STATUS_IS_OK(status)) {
1142 talloc_free(tmp_ctx);
1143 return status;
1145 num_members++;
1147 *pnum_members = num_members;
1148 return NT_STATUS_OK;
1151 /* Just convert the primary group SID into a group */
1152 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1153 TALLOC_CTX *mem_ctx,
1154 struct samu *user,
1155 struct dom_sid **pp_sids,
1156 gid_t **pp_gids,
1157 uint32_t *p_num_groups)
1159 NTSTATUS status;
1160 size_t num_groups = 0;
1161 struct dom_sid *group_sids;
1162 gid_t *gids;
1163 TALLOC_CTX *tmp_ctx;
1165 tmp_ctx = talloc_new(mem_ctx);
1166 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1168 if (user->group_sid) {
1169 struct id_map *id_maps[2];
1170 struct id_map id_map;
1172 num_groups = 1;
1174 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1175 if (group_sids == NULL) {
1176 talloc_free(tmp_ctx);
1177 return NT_STATUS_NO_MEMORY;
1179 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1180 if (gids == NULL) {
1181 talloc_free(tmp_ctx);
1182 return NT_STATUS_NO_MEMORY;
1185 group_sids[0] = *user->group_sid;
1187 ZERO_STRUCT(id_map);
1188 id_map.sid = &group_sids[0];
1189 id_maps[0] = &id_map;
1190 id_maps[1] = NULL;
1192 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1193 if (!NT_STATUS_IS_OK(status)) {
1194 talloc_free(tmp_ctx);
1195 return status;
1197 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1198 gids[0] = id_map.xid.id;
1199 } else {
1200 DEBUG(1, (__location__
1201 "Group %s, of which %s is a member, could not be converted to a GID\n",
1202 dom_sid_string(tmp_ctx, &group_sids[0]),
1203 dom_sid_string(tmp_ctx, &user->user_sid)));
1204 talloc_free(tmp_ctx);
1205 /* We must error out, otherwise a user might
1206 * avoid a DENY acl based on a group they
1207 * missed out on */
1208 return NT_STATUS_NO_SUCH_GROUP;
1212 *pp_sids = talloc_steal(mem_ctx, group_sids);
1213 *pp_gids = talloc_steal(mem_ctx, gids);
1214 *p_num_groups = num_groups;
1215 talloc_free(tmp_ctx);
1216 return NT_STATUS_OK;
1219 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1220 TALLOC_CTX *mem_ctx,
1221 struct samu *user,
1222 struct dom_sid **pp_sids,
1223 gid_t **pp_gids,
1224 uint32_t *p_num_groups)
1226 struct pdb_samba4_state *state = talloc_get_type_abort(
1227 m->private_data, struct pdb_samba4_state);
1228 struct ldb_message *msg = pdb_samba4_get_samu_private(
1229 m, user);
1230 const char *attrs[] = { "tokenGroups", NULL};
1231 struct ldb_message *tokengroups_msg;
1232 struct ldb_message_element *tokengroups;
1233 int i, rc;
1234 NTSTATUS status;
1235 unsigned int count = 0;
1236 size_t num_groups;
1237 struct dom_sid *group_sids;
1238 gid_t *gids;
1239 TALLOC_CTX *tmp_ctx;
1241 if (msg == NULL) {
1242 /* Fake up some things here */
1243 return fake_enum_group_memberships(state,
1244 mem_ctx,
1245 user, pp_sids,
1246 pp_gids, p_num_groups);
1249 tmp_ctx = talloc_new(mem_ctx);
1250 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1252 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1254 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1255 talloc_free(tmp_ctx);
1256 return NT_STATUS_NO_SUCH_USER;
1257 } else if (rc != LDB_SUCCESS) {
1258 DEBUG(10, ("dsdb_search_one failed %s\n",
1259 ldb_errstring(state->ldb)));
1260 talloc_free(tmp_ctx);
1261 return NT_STATUS_LDAP(rc);
1264 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1266 if (tokengroups) {
1267 count = tokengroups->num_values;
1270 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1271 if (group_sids == NULL) {
1272 talloc_free(tmp_ctx);
1273 return NT_STATUS_NO_MEMORY;
1275 gids = talloc_array(tmp_ctx, gid_t, count);
1276 if (gids == NULL) {
1277 talloc_free(tmp_ctx);
1278 return NT_STATUS_NO_MEMORY;
1280 num_groups = 0;
1282 for (i=0; i<count; i++) {
1283 struct id_map *id_maps[2];
1284 struct id_map id_map;
1285 struct ldb_val *v = &tokengroups->values[i];
1286 enum ndr_err_code ndr_err
1287 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1288 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1289 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1290 talloc_free(tmp_ctx);
1291 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1294 ZERO_STRUCT(id_map);
1295 id_map.sid = &group_sids[num_groups];
1296 id_maps[0] = &id_map;
1297 id_maps[1] = NULL;
1299 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 talloc_free(tmp_ctx);
1302 return status;
1304 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1305 gids[num_groups] = id_map.xid.id;
1306 } else {
1307 DEBUG(1, (__location__
1308 "Group %s, of which %s is a member, could not be converted to a GID\n",
1309 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1310 ldb_dn_get_linearized(msg->dn)));
1311 talloc_free(tmp_ctx);
1312 /* We must error out, otherwise a user might
1313 * avoid a DENY acl based on a group they
1314 * missed out on */
1315 return NT_STATUS_NO_SUCH_GROUP;
1318 num_groups += 1;
1319 if (num_groups == count) {
1320 break;
1324 *pp_sids = talloc_steal(mem_ctx, group_sids);
1325 *pp_gids = talloc_steal(mem_ctx, gids);
1326 *p_num_groups = num_groups;
1327 talloc_free(tmp_ctx);
1328 return NT_STATUS_OK;
1331 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1332 TALLOC_CTX *mem_ctx,
1333 struct samu *user)
1335 return NT_STATUS_NOT_IMPLEMENTED;
1338 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1339 TALLOC_CTX *mem_ctx,
1340 const struct dom_sid *groupsid,
1341 const struct dom_sid *membersid,
1342 int mod_op)
1344 struct pdb_samba4_state *state = talloc_get_type_abort(
1345 m->private_data, struct pdb_samba4_state);
1346 struct ldb_message *msg;
1347 int ret;
1348 struct ldb_message_element *el;
1349 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1350 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1351 msg = ldb_msg_new(tmp_ctx);
1352 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1354 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1355 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1356 talloc_free(tmp_ctx);
1357 return NT_STATUS_NO_MEMORY;
1359 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1360 if (ret != LDB_SUCCESS) {
1361 talloc_free(tmp_ctx);
1362 return NT_STATUS_NO_MEMORY;
1364 el = ldb_msg_find_element(msg, "member");
1365 el->flags = mod_op;
1367 /* No need for transactions here, the ldb auto-transaction
1368 * code will handle things for the single operation */
1369 ret = ldb_modify(state->ldb, msg);
1370 talloc_free(tmp_ctx);
1371 if (ret != LDB_SUCCESS) {
1372 DEBUG(10, ("ldb_modify failed: %s\n",
1373 ldb_errstring(state->ldb)));
1374 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1375 return NT_STATUS_MEMBER_IN_GROUP;
1377 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1378 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1380 return NT_STATUS_LDAP(ret);
1383 return NT_STATUS_OK;
1386 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1387 TALLOC_CTX *mem_ctx,
1388 uint32 grouprid, uint32 memberrid,
1389 int mod_op)
1391 struct pdb_samba4_state *state = talloc_get_type_abort(
1392 m->private_data, struct pdb_samba4_state);
1393 const struct dom_sid *dom_sid, *groupsid, *membersid;
1394 NTSTATUS status;
1395 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1396 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1398 dom_sid = samdb_domain_sid(state->ldb);
1400 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1401 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1402 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1403 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1404 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1405 talloc_free(tmp_ctx);
1406 return status;
1409 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1410 TALLOC_CTX *mem_ctx,
1411 uint32 group_rid, uint32 member_rid)
1413 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1414 LDB_FLAG_MOD_ADD);
1417 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1418 TALLOC_CTX *mem_ctx,
1419 uint32 group_rid, uint32 member_rid)
1421 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1422 LDB_FLAG_MOD_DELETE);
1425 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1426 const char *name, uint32 *rid)
1428 TALLOC_CTX *frame = talloc_stackframe();
1429 struct pdb_samba4_state *state = talloc_get_type_abort(
1430 m->private_data, struct pdb_samba4_state);
1431 struct dom_sid *sid;
1433 struct ldb_dn *dn;
1434 NTSTATUS status;
1436 /* Internally this uses transactions to ensure all the steps
1437 * happen or fail as one */
1438 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1439 if (!NT_STATUS_IS_OK(status)) {
1440 TALLOC_FREE(frame);
1443 sid_peek_rid(sid, rid);
1444 TALLOC_FREE(frame);
1445 return NT_STATUS_OK;
1448 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1449 const struct dom_sid *sid)
1451 const char *attrs[] = { NULL };
1452 struct pdb_samba4_state *state = talloc_get_type_abort(
1453 m->private_data, struct pdb_samba4_state);
1454 struct ldb_message *msg;
1455 struct ldb_dn *dn;
1456 int rc;
1457 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1458 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1460 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1461 if (!dn || !ldb_dn_validate(dn)) {
1462 talloc_free(tmp_ctx);
1463 return NT_STATUS_NO_MEMORY;
1466 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1467 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1468 return NT_STATUS_INTERNAL_ERROR;
1471 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1472 "(|(grouptype=%d)(grouptype=%d)))",
1473 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1474 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1475 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1476 talloc_free(tmp_ctx);
1477 ldb_transaction_cancel(state->ldb);
1478 return NT_STATUS_NO_SUCH_ALIAS;
1480 rc = ldb_delete(state->ldb, dn);
1481 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1482 talloc_free(tmp_ctx);
1483 ldb_transaction_cancel(state->ldb);
1484 return NT_STATUS_NO_SUCH_ALIAS;
1485 } else if (rc != LDB_SUCCESS) {
1486 DEBUG(10, ("ldb_delete failed %s\n",
1487 ldb_errstring(state->ldb)));
1488 ldb_transaction_cancel(state->ldb);
1489 return NT_STATUS_LDAP(rc);
1492 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1493 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1494 ldb_errstring(state->ldb)));
1495 return NT_STATUS_INTERNAL_ERROR;
1498 return NT_STATUS_OK;
1501 #if 0
1502 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1503 const struct dom_sid *sid,
1504 struct acct_info *info)
1506 struct pdb_samba4_state *state = talloc_get_type_abort(
1507 m->private_data, struct pdb_samba4_state);
1508 struct tldap_context *ld;
1509 const char *attrs[3] = { "objectSid", "description",
1510 "samAccountName" };
1511 struct ldb_message **msg;
1512 char *sidstr, *dn;
1513 int rc;
1514 struct tldap_mod *mods;
1515 int num_mods;
1516 bool ok;
1518 ld = pdb_samba4_ld(state);
1519 if (ld == NULL) {
1520 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1523 sidstr = sid_binstring(talloc_tos(), sid);
1524 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1526 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1527 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1528 &msg, "(&(objectSid=%s)(objectclass=group)"
1529 "(|(grouptype=%d)(grouptype=%d)))",
1530 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1531 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1532 TALLOC_FREE(sidstr)
1533 if (rc != LDB_SUCCESS) {
1534 DEBUG(10, ("ldap_search failed %s\n",
1535 ldb_errstring(state->ldb)));
1536 return NT_STATUS_LDAP(rc);
1538 switch talloc_array_length(msg) {
1539 case 0:
1540 return NT_STATUS_NO_SUCH_ALIAS;
1541 case 1:
1542 break;
1543 default:
1544 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1547 if (!tldap_entry_dn(msg[0], &dn)) {
1548 TALLOC_FREE(msg);
1549 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1552 mods = NULL;
1553 num_mods = 0;
1554 ok = true;
1556 ok &= tldap_make_mod_fmt(
1557 msg[0], msg, &num_mods, &mods, "description",
1558 "%s", info->acct_desc);
1559 ok &= tldap_make_mod_fmt(
1560 msg[0], msg, &num_mods, &mods, "samAccountName",
1561 "%s", info->acct_name);
1562 if (!ok) {
1563 TALLOC_FREE(msg);
1564 return NT_STATUS_NO_MEMORY;
1566 if (num_mods == 0) {
1567 /* no change */
1568 TALLOC_FREE(msg);
1569 return NT_STATUS_OK;
1572 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1573 TALLOC_FREE(msg);
1574 if (rc != LDB_SUCCESS) {
1575 DEBUG(10, ("ldap_modify failed: %s\n",
1576 ldb_errstring(state->ldb)));
1577 return NT_STATUS_LDAP(rc);
1579 return NT_STATUS_OK;
1581 #endif
1582 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1583 const struct dom_sid *alias,
1584 const struct dom_sid *member)
1586 NTSTATUS status;
1587 TALLOC_CTX *frame = talloc_stackframe();
1588 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1589 talloc_free(frame);
1590 return status;
1593 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1594 const struct dom_sid *alias,
1595 const struct dom_sid *member)
1597 NTSTATUS status;
1598 TALLOC_CTX *frame = talloc_stackframe();
1599 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1600 talloc_free(frame);
1601 return status;
1604 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1605 const struct dom_sid *alias,
1606 TALLOC_CTX *mem_ctx,
1607 struct dom_sid **pmembers,
1608 size_t *pnum_members)
1610 struct pdb_samba4_state *state = talloc_get_type_abort(
1611 m->private_data, struct pdb_samba4_state);
1612 struct ldb_dn *dn;
1613 unsigned int num_members;
1614 NTSTATUS status;
1615 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1616 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1618 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1619 if (!dn || !ldb_dn_validate(dn)) {
1620 return NT_STATUS_NO_MEMORY;
1623 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1624 *pnum_members = num_members;
1625 if (NT_STATUS_IS_OK(status)) {
1626 talloc_steal(mem_ctx, pmembers);
1628 talloc_free(tmp_ctx);
1629 return status;
1632 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1633 TALLOC_CTX *mem_ctx,
1634 const struct dom_sid *domain_sid,
1635 const struct dom_sid *members,
1636 size_t num_members,
1637 uint32_t **palias_rids,
1638 size_t *pnum_alias_rids)
1640 struct pdb_samba4_state *state = talloc_get_type_abort(
1641 m->private_data, struct pdb_samba4_state);
1642 uint32_t *alias_rids = NULL;
1643 size_t num_alias_rids = 0;
1644 int i;
1645 struct dom_sid *groupSIDs = NULL;
1646 unsigned int num_groupSIDs = 0;
1647 char *filter;
1648 NTSTATUS status;
1649 const char *sid_string;
1650 const char *sid_dn;
1651 DATA_BLOB sid_blob;
1653 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1654 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1656 * TODO: Get the filter right so that we only get the aliases from
1657 * either the SAM or BUILTIN
1660 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1661 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1662 if (filter == NULL) {
1663 return NT_STATUS_NO_MEMORY;
1666 for (i = 0; i < num_members; i++) {
1667 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1668 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1670 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1671 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1673 sid_blob = data_blob_string_const(sid_dn);
1675 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1676 tmp_ctx, &groupSIDs, &num_groupSIDs);
1677 if (!NT_STATUS_IS_OK(status)) {
1678 talloc_free(tmp_ctx);
1679 return status;
1683 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1684 if (alias_rids == NULL) {
1685 talloc_free(tmp_ctx);
1686 return NT_STATUS_NO_MEMORY;
1689 for (i=0; i<num_groupSIDs; i++) {
1690 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1691 &alias_rids[num_alias_rids])) {
1692 num_alias_rids++;;
1696 *palias_rids = alias_rids;
1697 *pnum_alias_rids = num_alias_rids;
1698 return NT_STATUS_OK;
1701 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1702 const struct dom_sid *domain_sid,
1703 int num_rids,
1704 uint32 *rids,
1705 const char **names,
1706 enum lsa_SidType *lsa_attrs)
1708 struct pdb_samba4_state *state = talloc_get_type_abort(
1709 m->private_data, struct pdb_samba4_state);
1710 NTSTATUS status;
1712 TALLOC_CTX *tmp_ctx;
1714 if (num_rids == 0) {
1715 return NT_STATUS_NONE_MAPPED;
1718 tmp_ctx = talloc_stackframe();
1719 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1721 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1722 talloc_free(tmp_ctx);
1723 return status;
1726 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1727 const struct dom_sid *domain_sid,
1728 int num_names,
1729 const char **pp_names,
1730 uint32 *rids,
1731 enum lsa_SidType *attrs)
1733 return NT_STATUS_NOT_IMPLEMENTED;
1736 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1737 enum pdb_policy_type type,
1738 uint32_t *value)
1740 return account_policy_get(type, value)
1741 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1744 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1745 enum pdb_policy_type type,
1746 uint32_t value)
1748 return account_policy_set(type, value)
1749 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1752 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1753 time_t *seq_num_out)
1755 struct pdb_samba4_state *state = talloc_get_type_abort(
1756 m->private_data, struct pdb_samba4_state);
1757 uint64_t seq_num;
1758 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1759 if (ret == LDB_SUCCESS) {
1760 *seq_num_out = seq_num;
1761 return NT_STATUS_OK;
1762 } else {
1763 return NT_STATUS_UNSUCCESSFUL;
1767 struct pdb_samba4_search_state {
1768 uint32_t acct_flags;
1769 struct samr_displayentry *entries;
1770 uint32_t num_entries;
1771 ssize_t array_size;
1772 uint32_t current;
1775 static bool pdb_samba4_next_entry(struct pdb_search *search,
1776 struct samr_displayentry *entry)
1778 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1779 search->private_data, struct pdb_samba4_search_state);
1781 if (state->current == state->num_entries) {
1782 return false;
1785 entry->idx = state->entries[state->current].idx;
1786 entry->rid = state->entries[state->current].rid;
1787 entry->acct_flags = state->entries[state->current].acct_flags;
1789 entry->account_name = talloc_strdup(
1790 search, state->entries[state->current].account_name);
1791 entry->fullname = talloc_strdup(
1792 search, state->entries[state->current].fullname);
1793 entry->description = talloc_strdup(
1794 search, state->entries[state->current].description);
1796 state->current += 1;
1797 return true;
1800 static void pdb_samba4_search_end(struct pdb_search *search)
1802 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1803 search->private_data, struct pdb_samba4_search_state);
1804 talloc_free(state);
1807 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1808 struct pdb_search *search,
1809 struct pdb_samba4_search_state **pstate,
1810 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1812 struct pdb_samba4_state *state = talloc_get_type_abort(
1813 m->private_data, struct pdb_samba4_state);
1814 struct pdb_samba4_search_state *sstate;
1815 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1816 "userAccountControl", "description", NULL };
1817 struct ldb_result *res;
1818 int i, rc, num_users;
1820 va_list ap;
1821 char *expression = NULL;
1823 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1824 if (!tmp_ctx) {
1825 return false;
1828 va_start(ap, exp_fmt);
1829 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1830 va_end(ap);
1832 if (!expression) {
1833 talloc_free(tmp_ctx);
1834 return LDB_ERR_OPERATIONS_ERROR;
1837 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1838 if (sstate == NULL) {
1839 talloc_free(tmp_ctx);
1840 return false;
1843 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1844 if (rc != LDB_SUCCESS) {
1845 talloc_free(tmp_ctx);
1846 DEBUG(10, ("dsdb_search failed: %s\n",
1847 ldb_errstring(state->ldb)));
1848 return false;
1851 num_users = res->count;
1853 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1854 num_users);
1855 if (sstate->entries == NULL) {
1856 talloc_free(tmp_ctx);
1857 DEBUG(10, ("talloc failed\n"));
1858 return false;
1861 sstate->num_entries = 0;
1863 for (i=0; i<num_users; i++) {
1864 struct samr_displayentry *e;
1865 struct dom_sid *sid;
1867 e = &sstate->entries[sstate->num_entries];
1869 e->idx = sstate->num_entries;
1870 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1871 if (!sid) {
1872 talloc_free(tmp_ctx);
1873 DEBUG(10, ("Could not pull SID\n"));
1874 return false;
1876 sid_peek_rid(sid, &e->rid);
1878 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1879 res->msgs[i],
1880 ldb_get_default_basedn(state->ldb));
1881 e->account_name = ldb_msg_find_attr_as_string(
1882 res->msgs[i], "samAccountName", NULL);
1883 if (e->account_name == NULL) {
1884 talloc_free(tmp_ctx);
1885 return false;
1887 e->fullname = ldb_msg_find_attr_as_string(
1888 res->msgs[i], "displayName", "");
1889 e->description = ldb_msg_find_attr_as_string(
1890 res->msgs[i], "description", "");
1892 sstate->num_entries += 1;
1893 if (sstate->num_entries >= num_users) {
1894 break;
1897 talloc_steal(sstate->entries, res->msgs);
1898 search->private_data = talloc_steal(search, sstate);
1899 search->next_entry = pdb_samba4_next_entry;
1900 search->search_end = pdb_samba4_search_end;
1901 *pstate = sstate;
1902 talloc_free(tmp_ctx);
1903 return true;
1906 static bool pdb_samba4_search_users(struct pdb_methods *m,
1907 struct pdb_search *search,
1908 uint32 acct_flags)
1910 struct pdb_samba4_search_state *sstate;
1911 bool ret;
1913 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1914 if (!ret) {
1915 return false;
1917 sstate->acct_flags = acct_flags;
1918 return true;
1921 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1922 struct pdb_search *search)
1924 struct pdb_samba4_search_state *sstate;
1925 bool ret;
1927 ret = pdb_samba4_search_filter(m, search, &sstate,
1928 "(&(grouptype=%d)(objectclass=group))",
1929 GTYPE_SECURITY_GLOBAL_GROUP);
1930 if (!ret) {
1931 return false;
1933 sstate->acct_flags = 0;
1934 return true;
1937 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1938 struct pdb_search *search,
1939 const struct dom_sid *sid)
1941 struct pdb_samba4_search_state *sstate;
1942 bool ret;
1944 ret = pdb_samba4_search_filter(m, search, &sstate,
1945 "(&(grouptype=%d)(objectclass=group))",
1946 sid_check_is_builtin(sid)
1947 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1948 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1949 if (!ret) {
1950 return false;
1952 sstate->acct_flags = 0;
1953 return true;
1956 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1957 struct dom_sid *sid)
1959 struct pdb_samba4_state *state = talloc_get_type_abort(
1960 m->private_data, struct pdb_samba4_state);
1961 NTSTATUS status;
1962 struct id_map id_map;
1963 struct id_map *id_maps[2];
1964 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1965 if (!tmp_ctx) {
1966 return false;
1969 id_map.xid.id = uid;
1970 id_map.xid.type = ID_TYPE_UID;
1971 id_maps[0] = &id_map;
1972 id_maps[1] = NULL;
1974 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1975 if (!NT_STATUS_IS_OK(status)) {
1976 talloc_free(tmp_ctx);
1977 return false;
1979 *sid = *id_map.sid;
1980 talloc_free(tmp_ctx);
1981 return true;
1984 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1985 struct dom_sid *sid)
1987 struct pdb_samba4_state *state = talloc_get_type_abort(
1988 m->private_data, struct pdb_samba4_state);
1989 NTSTATUS status;
1990 struct id_map id_map;
1991 struct id_map *id_maps[2];
1992 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1993 if (!tmp_ctx) {
1994 return false;
1997 id_map.xid.id = gid;
1998 id_map.xid.type = ID_TYPE_GID;
1999 id_maps[0] = &id_map;
2000 id_maps[1] = NULL;
2002 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2003 if (!NT_STATUS_IS_OK(status)) {
2004 return false;
2006 *sid = *id_map.sid;
2007 talloc_free(tmp_ctx);
2008 return true;
2011 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2012 uid_t *uid, gid_t *gid, enum lsa_SidType *type)
2014 struct pdb_samba4_state *state = talloc_get_type_abort(
2015 m->private_data, struct pdb_samba4_state);
2016 struct id_map id_map;
2017 struct id_map *id_maps[2];
2018 const char *attrs[] = { "objectClass", "groupType", NULL };
2019 struct ldb_message *msg;
2020 struct ldb_dn *dn;
2021 NTSTATUS status;
2022 int rc;
2023 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2024 if (!tmp_ctx) {
2025 return false;
2028 ZERO_STRUCT(id_map);
2030 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2031 if (!dn || !ldb_dn_validate(dn)) {
2032 talloc_free(tmp_ctx);
2033 return false;
2035 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2036 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2037 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)));
2038 talloc_free(tmp_ctx);
2039 return false;
2041 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2042 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
2043 switch (grouptype) {
2044 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
2045 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
2046 *type = SID_NAME_ALIAS;
2047 break;
2048 case GTYPE_SECURITY_GLOBAL_GROUP:
2049 *type = SID_NAME_DOM_GRP;
2050 break;
2051 default:
2052 talloc_free(tmp_ctx);
2053 DEBUG(10, ("Could not pull groupType\n"));
2054 return false;
2057 *type = SID_NAME_DOM_GRP;
2059 ZERO_STRUCT(id_map);
2060 id_map.sid = sid;
2061 id_maps[0] = &id_map;
2062 id_maps[1] = NULL;
2064 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2065 talloc_free(tmp_ctx);
2066 if (!NT_STATUS_IS_OK(status)) {
2067 return false;
2069 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
2070 *gid = id_map.xid.id;
2071 return true;
2073 return false;
2074 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2075 *type = SID_NAME_USER;
2076 ZERO_STRUCT(id_map);
2077 id_map.sid = sid;
2078 id_maps[0] = &id_map;
2079 id_maps[1] = NULL;
2081 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2082 talloc_free(tmp_ctx);
2083 if (!NT_STATUS_IS_OK(status)) {
2084 return false;
2086 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2087 *uid = id_map.xid.id;
2088 return true;
2090 return false;
2092 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)));
2093 talloc_free(tmp_ctx);
2094 return false;
2097 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2099 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2102 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2104 return false;
2107 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2108 const char *domain, char** pwd,
2109 struct dom_sid *sid,
2110 time_t *pass_last_set_time)
2112 return false;
2115 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2116 const char* domain, const char* pwd,
2117 const struct dom_sid *sid)
2119 return false;
2122 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2123 const char *domain)
2125 return false;
2128 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2129 TALLOC_CTX *mem_ctx,
2130 uint32 *num_domains,
2131 struct trustdom_info ***domains)
2133 *num_domains = 0;
2134 *domains = NULL;
2135 return NT_STATUS_OK;
2138 static void pdb_samba4_init_methods(struct pdb_methods *m)
2140 m->name = "samba4";
2141 m->get_domain_info = pdb_samba4_get_domain_info;
2142 m->getsampwnam = pdb_samba4_getsampwnam;
2143 m->getsampwsid = pdb_samba4_getsampwsid;
2144 m->create_user = pdb_samba4_create_user;
2145 m->delete_user = pdb_samba4_delete_user;
2146 m->add_sam_account = pdb_samba4_add_sam_account;
2147 m->update_sam_account = pdb_samba4_update_sam_account;
2148 m->delete_sam_account = pdb_samba4_delete_sam_account;
2149 m->rename_sam_account = pdb_samba4_rename_sam_account;
2150 m->update_login_attempts = pdb_samba4_update_login_attempts;
2151 m->getgrsid = pdb_samba4_getgrsid;
2152 m->getgrgid = pdb_samba4_getgrgid;
2153 m->getgrnam = pdb_samba4_getgrnam;
2154 m->create_dom_group = pdb_samba4_create_dom_group;
2155 m->delete_dom_group = pdb_samba4_delete_dom_group;
2156 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2157 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2158 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2159 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2160 m->enum_group_members = pdb_samba4_enum_group_members;
2161 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2162 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2163 m->add_groupmem = pdb_samba4_add_groupmem;
2164 m->del_groupmem = pdb_samba4_del_groupmem;
2165 m->create_alias = pdb_samba4_create_alias;
2166 m->delete_alias = pdb_samba4_delete_alias;
2167 m->get_aliasinfo = pdb_default_get_aliasinfo;
2168 m->add_aliasmem = pdb_samba4_add_aliasmem;
2169 m->del_aliasmem = pdb_samba4_del_aliasmem;
2170 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2171 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2172 m->lookup_rids = pdb_samba4_lookup_rids;
2173 m->lookup_names = pdb_samba4_lookup_names;
2174 m->get_account_policy = pdb_samba4_get_account_policy;
2175 m->set_account_policy = pdb_samba4_set_account_policy;
2176 m->get_seq_num = pdb_samba4_get_seq_num;
2177 m->search_users = pdb_samba4_search_users;
2178 m->search_groups = pdb_samba4_search_groups;
2179 m->search_aliases = pdb_samba4_search_aliases;
2180 m->uid_to_sid = pdb_samba4_uid_to_sid;
2181 m->gid_to_sid = pdb_samba4_gid_to_sid;
2182 m->sid_to_id = pdb_samba4_sid_to_id;
2183 m->capabilities = pdb_samba4_capabilities;
2184 m->new_rid = pdb_samba4_new_rid;
2185 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2186 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2187 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2188 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2191 static void free_private_data(void **vp)
2193 struct pdb_samba4_state *state = talloc_get_type_abort(
2194 *vp, struct pdb_samba4_state);
2195 talloc_unlink(state, state->ldb);
2196 return;
2199 static NTSTATUS pdb_samba4_init_secrets(struct pdb_methods *m)
2201 struct pdb_domain_info *dom_info;
2202 bool ret;
2204 dom_info = pdb_samba4_get_domain_info(m, m);
2205 if (!dom_info) {
2206 return NT_STATUS_UNSUCCESSFUL;
2209 secrets_clear_domain_protection(dom_info->name);
2210 ret = secrets_store_domain_sid(dom_info->name,
2211 &dom_info->sid);
2212 if (!ret) {
2213 goto done;
2215 ret = secrets_store_domain_guid(dom_info->name,
2216 &dom_info->guid);
2217 if (!ret) {
2218 goto done;
2220 ret = secrets_mark_domain_protected(dom_info->name);
2221 if (!ret) {
2222 goto done;
2225 done:
2226 TALLOC_FREE(dom_info);
2227 if (!ret) {
2228 return NT_STATUS_UNSUCCESSFUL;
2230 return NT_STATUS_OK;
2233 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2234 const char *location)
2236 struct pdb_methods *m;
2237 struct pdb_samba4_state *state;
2238 NTSTATUS status;
2240 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2241 return status;
2244 state = talloc_zero(m, struct pdb_samba4_state);
2245 if (state == NULL) {
2246 goto nomem;
2248 m->private_data = state;
2249 m->free_private_data = free_private_data;
2250 pdb_samba4_init_methods(m);
2252 state->ev = s4_event_context_init(state);
2253 if (!state->ev) {
2254 DEBUG(0, ("s4_event_context_init failed\n"));
2255 goto nomem;
2258 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2259 if (state->lp_ctx == NULL) {
2260 DEBUG(0, ("loadparm_init_s3 failed\n"));
2261 goto nomem;
2264 if (location) {
2265 state->ldb = samdb_connect_url(state,
2266 state->ev,
2267 state->lp_ctx,
2268 system_session(state->lp_ctx),
2269 0, location);
2270 } else {
2271 state->ldb = samdb_connect(state,
2272 state->ev,
2273 state->lp_ctx,
2274 system_session(state->lp_ctx), 0);
2277 if (!state->ldb) {
2278 DEBUG(0, ("samdb_connect failed\n"));
2279 status = NT_STATUS_INTERNAL_ERROR;
2280 goto fail;
2283 state->idmap_ctx = idmap_init(state, state->ev,
2284 state->lp_ctx);
2285 if (!state->idmap_ctx) {
2286 DEBUG(0, ("idmap failed\n"));
2287 status = NT_STATUS_INTERNAL_ERROR;
2288 goto fail;
2291 status = pdb_samba4_init_secrets(m);
2292 if (!NT_STATUS_IS_OK(status)) {
2293 DEBUG(10, ("pdb_samba4_init_secrets failed!\n"));
2294 goto fail;
2297 *pdb_method = m;
2298 return NT_STATUS_OK;
2299 nomem:
2300 status = NT_STATUS_NO_MEMORY;
2301 fail:
2302 TALLOC_FREE(m);
2303 return status;
2306 NTSTATUS pdb_samba4_init(void);
2307 NTSTATUS pdb_samba4_init(void)
2309 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2310 pdb_init_samba4);