s3-waf: Cleanup smbregistry.
[Samba/vl.git] / source3 / passdb / pdb_samba4.c
blob024c293aa1d19ed750f44b20a6245427bdae03c3
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_DOMAIN,
568 PDB_NTUSERNAME, - this makes no sense, and never really did
569 PDB_LOGONDIVS,
570 PDB_USERSID, - Handled in pdb_samba4_add_sam_account()
571 PDB_FIELDS_PRESENT,
572 PDB_BAD_PASSWORD_COUNT,
573 PDB_LOGON_COUNT,
574 PDB_UNKNOWN6,
575 PDB_BACKEND_PRIVATE_DATA,
578 if (ret != LDB_SUCCESS) {
579 return LDB_ERR_OPERATIONS_ERROR;
582 if (msg->num_elements == 0) {
583 /* Nothing to do, just return success */
584 return LDB_SUCCESS;
587 ret = dsdb_replace(state->ldb, msg, dsdb_flags);
589 if (ret != LDB_SUCCESS) {
590 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
591 ldb_dn_get_linearized(msg->dn),
592 ldb_errstring(state->ldb)));
595 return ret;
598 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
599 const char *filter,
600 TALLOC_CTX *mem_ctx,
601 struct ldb_message **msg)
603 const char * attrs[] = {
604 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
605 "sAMAccountName", "displayName", "homeDirectory",
606 "homeDrive", "scriptPath", "profilePath", "description",
607 "userWorkstations", "comment", "userParameters", "objectSid",
608 "primaryGroupID", "userAccountControl", "logonHours",
609 "badPwdCount", "logonCount", "countryCode", "codePage",
610 "unicodePwd", "dBCSPwd", NULL };
612 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
613 if (rc != LDB_SUCCESS) {
614 DEBUG(10, ("ldap_search failed %s\n",
615 ldb_errstring(state->ldb)));
616 return NT_STATUS_LDAP(rc);
619 return NT_STATUS_OK;
622 static NTSTATUS pdb_samba4_getsampwfilter(struct pdb_methods *m,
623 struct pdb_samba4_state *state,
624 struct samu *sam_acct,
625 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
627 struct ldb_message *priv;
628 NTSTATUS status;
629 va_list ap;
630 char *expression = NULL;
631 TALLOC_CTX *tmp_ctx = talloc_new(state);
632 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
634 va_start(ap, exp_fmt);
635 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
636 va_end(ap);
638 if (!expression) {
639 talloc_free(tmp_ctx);
640 return NT_STATUS_NO_MEMORY;
643 status = pdb_samba4_getsamupriv(state, expression, sam_acct, &priv);
644 talloc_free(tmp_ctx);
645 if (!NT_STATUS_IS_OK(status)) {
646 DEBUG(10, ("pdb_samba4_getsamupriv failed: %s\n",
647 nt_errstr(status)));
648 return status;
651 status = pdb_samba4_init_sam_from_priv(m, sam_acct, priv);
652 if (!NT_STATUS_IS_OK(status)) {
653 DEBUG(10, ("pdb_samba4_init_sam_from_priv failed: %s\n",
654 nt_errstr(status)));
655 TALLOC_FREE(priv);
656 return status;
659 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
660 return NT_STATUS_OK;
663 static NTSTATUS pdb_samba4_getsampwnam(struct pdb_methods *m,
664 struct samu *sam_acct,
665 const char *username)
667 struct pdb_samba4_state *state = talloc_get_type_abort(
668 m->private_data, struct pdb_samba4_state);
670 return pdb_samba4_getsampwfilter(m, state, sam_acct,
671 "(&(samaccountname=%s)(objectclass=user))",
672 username);
675 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
676 struct samu *sam_acct,
677 const struct dom_sid *sid)
679 NTSTATUS status;
680 struct pdb_samba4_state *state = talloc_get_type_abort(
681 m->private_data, struct pdb_samba4_state);
682 char *sidstr;
684 sidstr = dom_sid_string(talloc_tos(), sid);
685 NT_STATUS_HAVE_NO_MEMORY(sidstr);
687 status = pdb_samba4_getsampwfilter(m, state, sam_acct,
688 "(&(objectsid=%s)(objectclass=user))",
689 sidstr);
690 talloc_free(sidstr);
691 return status;
694 static NTSTATUS pdb_samba4_create_user(struct pdb_methods *m,
695 TALLOC_CTX *mem_ctx,
696 const char *name, uint32 acct_flags,
697 uint32 *rid)
699 struct pdb_samba4_state *state = talloc_get_type_abort(
700 m->private_data, struct pdb_samba4_state);
701 struct dom_sid *sid;
702 struct ldb_dn *dn;
703 NTSTATUS status;
704 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
705 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
707 /* Internally this uses transactions to ensure all the steps
708 * happen or fail as one */
709 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
710 &sid, &dn);
711 if (!NT_STATUS_IS_OK(status)) {
712 talloc_free(tmp_ctx);
713 return status;
715 sid_peek_rid(sid, rid);
716 talloc_free(tmp_ctx);
717 return NT_STATUS_OK;
720 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
721 TALLOC_CTX *mem_ctx,
722 struct samu *sam)
724 struct pdb_samba4_state *state = talloc_get_type_abort(
725 m->private_data, struct pdb_samba4_state);
726 struct ldb_dn *dn;
727 int rc;
728 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
729 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
731 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
732 if (!dn || !ldb_dn_validate(dn)) {
733 talloc_free(tmp_ctx);
734 return NT_STATUS_NO_MEMORY;
736 rc = ldb_delete(state->ldb, dn);
738 if (rc != LDB_SUCCESS) {
739 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
740 ldb_errstring(state->ldb)));
741 talloc_free(tmp_ctx);
742 return NT_STATUS_LDAP(rc);
744 talloc_free(tmp_ctx);
745 return NT_STATUS_OK;
748 /* This interface takes a fully populated struct samu and places it in
749 * the database. This is not implemented at this time as we need to
750 * be careful around the creation of arbitary SIDs (ie, we must ensrue
751 * they are not left in a RID pool */
752 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
753 struct samu *sampass)
755 int ret;
756 NTSTATUS status;
757 struct ldb_dn *dn;
758 struct pdb_samba4_state *state = talloc_get_type_abort(
759 m->private_data, struct pdb_samba4_state);
760 uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
761 const char *username = pdb_get_username(sampass);
762 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
763 TALLOC_CTX *tframe = talloc_stackframe();
765 acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
767 ret = ldb_transaction_start(state->ldb);
768 if (ret != LDB_SUCCESS) {
769 talloc_free(tframe);
770 return NT_STATUS_LOCK_NOT_GRANTED;
773 status = dsdb_add_user(state->ldb, talloc_tos(), username,
774 acb_flags, user_sid, NULL, &dn);
775 if (!NT_STATUS_IS_OK(status)) {
776 ldb_transaction_cancel(state->ldb);
777 talloc_free(tframe);
778 return status;
781 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_set_or_changed,
782 dn, sampass);
783 if (ret != LDB_SUCCESS) {
784 ldb_transaction_cancel(state->ldb);
785 talloc_free(tframe);
786 return dsdb_ldb_err_to_ntstatus(ret);
789 ret = ldb_transaction_commit(state->ldb);
790 if (ret != LDB_SUCCESS) {
791 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
792 ldb_dn_get_linearized(dn),
793 ldb_errstring(state->ldb)));
794 talloc_free(tframe);
795 return NT_STATUS_INTERNAL_DB_CORRUPTION;
797 talloc_free(tframe);
798 return NT_STATUS_OK;
802 * Update the Samba4 LDB with the changes from a struct samu.
804 * This takes care not to update elements that have not been changed
805 * by the caller
807 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
808 struct samu *sam)
810 struct pdb_samba4_state *state = talloc_get_type_abort(
811 m->private_data, struct pdb_samba4_state);
812 struct ldb_message *msg = pdb_samba4_get_samu_private(
813 m, sam);
814 int ret;
816 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_changed, msg->dn,
817 sam);
818 return dsdb_ldb_err_to_ntstatus(ret);
821 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
822 struct samu *username)
824 NTSTATUS status;
825 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
826 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
827 status = pdb_samba4_delete_user(m, tmp_ctx, username);
828 talloc_free(tmp_ctx);
829 return status;
832 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
833 struct samu *oldname,
834 const char *newname)
836 return NT_STATUS_NOT_IMPLEMENTED;
839 /* This is not implemented, as this module is exptected to be used
840 * with auth_samba4, and this is responible for login counters etc
843 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
844 struct samu *sam_acct,
845 bool success)
847 return NT_STATUS_NOT_IMPLEMENTED;
850 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
851 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
853 struct pdb_samba4_state *state = talloc_get_type_abort(
854 m->private_data, struct pdb_samba4_state);
855 const char *attrs[] = { "objectSid", "description", "samAccountName",
856 NULL };
857 struct ldb_message *msg;
858 va_list ap;
859 char *expression = NULL;
860 struct dom_sid *sid;
861 const char *str;
862 int rc;
863 uid_t uid;
864 TALLOC_CTX *tmp_ctx = talloc_stackframe();
865 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
867 va_start(ap, exp_fmt);
868 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
869 va_end(ap);
871 if (!expression) {
872 talloc_free(tmp_ctx);
873 return NT_STATUS_NO_MEMORY;
876 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
877 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
878 talloc_free(tmp_ctx);
879 return NT_STATUS_NO_SUCH_GROUP;
880 } else if (rc != LDB_SUCCESS) {
881 talloc_free(tmp_ctx);
882 DEBUG(10, ("dsdb_search_one failed %s\n",
883 ldb_errstring(state->ldb)));
884 return NT_STATUS_LDAP(rc);
887 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
888 if (!sid) {
889 talloc_free(tmp_ctx);
890 DEBUG(10, ("Could not pull SID\n"));
891 return NT_STATUS_INTERNAL_DB_CORRUPTION;
894 map->sid = *sid;
896 if (!pdb_samba4_sid_to_id(m, sid, &uid, &map->gid, &map->sid_name_use)) {
897 talloc_free(tmp_ctx);
898 return NT_STATUS_NO_SUCH_GROUP;
900 if (map->sid_name_use == SID_NAME_USER) {
901 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
902 return NT_STATUS_INTERNAL_DB_CORRUPTION;
905 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
906 NULL);
907 if (str == NULL) {
908 talloc_free(tmp_ctx);
909 return NT_STATUS_INTERNAL_DB_CORRUPTION;
911 map->nt_name = talloc_strdup(map, str);
912 if (!map->nt_name) {
913 talloc_free(tmp_ctx);
914 return NT_STATUS_NO_MEMORY;
917 str = ldb_msg_find_attr_as_string(msg, "description",
918 NULL);
919 if (str != NULL) {
920 map->comment = talloc_strdup(map, str);
921 } else {
922 map->comment = talloc_strdup(map, "");
924 if (!map->comment) {
925 talloc_free(tmp_ctx);
926 return NT_STATUS_NO_MEMORY;
929 talloc_free(tmp_ctx);
930 return NT_STATUS_OK;
933 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
934 struct dom_sid sid)
936 char *filter;
937 NTSTATUS status;
939 filter = talloc_asprintf(talloc_tos(),
940 "(&(objectsid=%s)(objectclass=group))",
941 sid_string_talloc(talloc_tos(), &sid));
942 if (filter == NULL) {
943 return NT_STATUS_NO_MEMORY;
946 status = pdb_samba4_getgrfilter(m, map, filter);
947 TALLOC_FREE(filter);
948 return status;
951 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
952 gid_t gid)
954 struct pdb_samba4_state *state = talloc_get_type_abort(
955 m->private_data, struct pdb_samba4_state);
956 NTSTATUS status;
957 struct id_map id_map;
958 struct id_map *id_maps[2];
959 TALLOC_CTX *tmp_ctx = talloc_stackframe();
960 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
962 id_map.xid.id = gid;
963 id_map.xid.type = ID_TYPE_GID;
964 id_maps[0] = &id_map;
965 id_maps[1] = NULL;
967 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
968 if (!NT_STATUS_IS_OK(status)) {
969 return status;
971 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
972 talloc_free(tmp_ctx);
973 return status;
976 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
977 const char *name)
979 char *filter;
980 NTSTATUS status;
982 filter = talloc_asprintf(talloc_tos(),
983 "(&(samaccountname=%s)(objectclass=group))",
984 name);
985 if (filter == NULL) {
986 return NT_STATUS_NO_MEMORY;
989 status = pdb_samba4_getgrfilter(m, map, filter);
990 TALLOC_FREE(filter);
991 return status;
994 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
995 TALLOC_CTX *mem_ctx, const char *name,
996 uint32 *rid)
998 struct pdb_samba4_state *state = talloc_get_type_abort(
999 m->private_data, struct pdb_samba4_state);
1000 NTSTATUS status;
1001 struct dom_sid *sid;
1002 struct ldb_dn *dn;
1003 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1004 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1006 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1007 if (!NT_STATUS_IS_OK(status)) {
1008 talloc_free(tmp_ctx);
1009 return status;
1012 sid_peek_rid(sid, rid);
1013 talloc_free(tmp_ctx);
1014 return NT_STATUS_OK;
1017 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1018 TALLOC_CTX *mem_ctx, uint32 rid)
1020 const char *attrs[] = { NULL };
1021 struct pdb_samba4_state *state = talloc_get_type_abort(
1022 m->private_data, struct pdb_samba4_state);
1023 struct dom_sid sid;
1024 struct ldb_message *msg;
1025 struct ldb_dn *dn;
1026 int rc;
1027 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1028 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1030 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1032 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1033 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1034 return NT_STATUS_INTERNAL_ERROR;
1037 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1038 if (!dn || !ldb_dn_validate(dn)) {
1039 talloc_free(tmp_ctx);
1040 ldb_transaction_cancel(state->ldb);
1041 return NT_STATUS_NO_MEMORY;
1043 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1044 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1045 talloc_free(tmp_ctx);
1046 ldb_transaction_cancel(state->ldb);
1047 return NT_STATUS_NO_SUCH_GROUP;
1049 rc = ldb_delete(state->ldb, dn);
1050 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1051 talloc_free(tmp_ctx);
1052 ldb_transaction_cancel(state->ldb);
1053 return NT_STATUS_NO_SUCH_GROUP;
1054 } else if (rc != LDB_SUCCESS) {
1055 DEBUG(10, ("ldb_delete failed %s\n",
1056 ldb_errstring(state->ldb)));
1057 ldb_transaction_cancel(state->ldb);
1058 return NT_STATUS_LDAP(rc);
1061 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1062 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1063 return NT_STATUS_INTERNAL_ERROR;
1065 return NT_STATUS_OK;
1068 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1069 GROUP_MAP *map)
1071 return NT_STATUS_NOT_IMPLEMENTED;
1074 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1075 GROUP_MAP *map)
1077 return NT_STATUS_NOT_IMPLEMENTED;
1080 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1081 struct dom_sid sid)
1083 return NT_STATUS_NOT_IMPLEMENTED;
1086 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1087 const struct dom_sid *sid,
1088 enum lsa_SidType sid_name_use,
1089 GROUP_MAP ***pp_rmap,
1090 size_t *p_num_entries,
1091 bool unix_only)
1093 return NT_STATUS_NOT_IMPLEMENTED;
1096 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1097 TALLOC_CTX *mem_ctx,
1098 const struct dom_sid *group,
1099 uint32_t **pmembers,
1100 size_t *pnum_members)
1102 unsigned int i, num_sids, num_members;
1103 struct pdb_samba4_state *state = talloc_get_type_abort(
1104 m->private_data, struct pdb_samba4_state);
1105 struct dom_sid *members_as_sids;
1106 struct dom_sid *dom_sid;
1107 uint32_t *members;
1108 struct ldb_dn *dn;
1109 NTSTATUS status;
1111 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1112 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1114 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1115 if (!dn || !ldb_dn_validate(dn)) {
1116 return NT_STATUS_NO_MEMORY;
1119 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1120 if (!NT_STATUS_IS_OK(status)) {
1121 talloc_free(tmp_ctx);
1122 return status;
1124 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 talloc_free(tmp_ctx);
1127 return status;
1130 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1131 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1132 num_members = 0;
1134 for (i = 0; i < num_sids; i++) {
1135 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1136 continue;
1138 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1139 NULL, &members[num_members]);
1140 if (!NT_STATUS_IS_OK(status)) {
1141 talloc_free(tmp_ctx);
1142 return status;
1144 num_members++;
1146 *pnum_members = num_members;
1147 return NT_STATUS_OK;
1150 /* Just convert the primary group SID into a group */
1151 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1152 TALLOC_CTX *mem_ctx,
1153 struct samu *user,
1154 struct dom_sid **pp_sids,
1155 gid_t **pp_gids,
1156 uint32_t *p_num_groups)
1158 NTSTATUS status;
1159 size_t num_groups = 0;
1160 struct dom_sid *group_sids;
1161 gid_t *gids;
1162 TALLOC_CTX *tmp_ctx;
1164 tmp_ctx = talloc_new(mem_ctx);
1165 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1167 if (user->group_sid) {
1168 struct id_map *id_maps[2];
1169 struct id_map id_map;
1171 num_groups = 1;
1173 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1174 if (group_sids == NULL) {
1175 talloc_free(tmp_ctx);
1176 return NT_STATUS_NO_MEMORY;
1178 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1179 if (gids == NULL) {
1180 talloc_free(tmp_ctx);
1181 return NT_STATUS_NO_MEMORY;
1184 group_sids[0] = *user->group_sid;
1186 ZERO_STRUCT(id_map);
1187 id_map.sid = &group_sids[0];
1188 id_maps[0] = &id_map;
1189 id_maps[1] = NULL;
1191 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1192 if (!NT_STATUS_IS_OK(status)) {
1193 talloc_free(tmp_ctx);
1194 return status;
1196 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1197 gids[0] = id_map.xid.id;
1198 } else {
1199 DEBUG(1, (__location__
1200 "Group %s, of which %s is a member, could not be converted to a GID\n",
1201 dom_sid_string(tmp_ctx, &group_sids[0]),
1202 dom_sid_string(tmp_ctx, &user->user_sid)));
1203 talloc_free(tmp_ctx);
1204 /* We must error out, otherwise a user might
1205 * avoid a DENY acl based on a group they
1206 * missed out on */
1207 return NT_STATUS_NO_SUCH_GROUP;
1211 *pp_sids = talloc_steal(mem_ctx, group_sids);
1212 *pp_gids = talloc_steal(mem_ctx, gids);
1213 *p_num_groups = num_groups;
1214 talloc_free(tmp_ctx);
1215 return NT_STATUS_OK;
1218 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1219 TALLOC_CTX *mem_ctx,
1220 struct samu *user,
1221 struct dom_sid **pp_sids,
1222 gid_t **pp_gids,
1223 uint32_t *p_num_groups)
1225 struct pdb_samba4_state *state = talloc_get_type_abort(
1226 m->private_data, struct pdb_samba4_state);
1227 struct ldb_message *msg = pdb_samba4_get_samu_private(
1228 m, user);
1229 const char *attrs[] = { "tokenGroups", NULL};
1230 struct ldb_message *tokengroups_msg;
1231 struct ldb_message_element *tokengroups;
1232 int i, rc;
1233 NTSTATUS status;
1234 unsigned int count = 0;
1235 size_t num_groups;
1236 struct dom_sid *group_sids;
1237 gid_t *gids;
1238 TALLOC_CTX *tmp_ctx;
1240 if (msg == NULL) {
1241 /* Fake up some things here */
1242 return fake_enum_group_memberships(state,
1243 mem_ctx,
1244 user, pp_sids,
1245 pp_gids, p_num_groups);
1248 tmp_ctx = talloc_new(mem_ctx);
1249 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1251 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1253 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1254 talloc_free(tmp_ctx);
1255 return NT_STATUS_NO_SUCH_USER;
1256 } else if (rc != LDB_SUCCESS) {
1257 DEBUG(10, ("dsdb_search_one failed %s\n",
1258 ldb_errstring(state->ldb)));
1259 talloc_free(tmp_ctx);
1260 return NT_STATUS_LDAP(rc);
1263 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1265 if (tokengroups) {
1266 count = tokengroups->num_values;
1269 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1270 if (group_sids == NULL) {
1271 talloc_free(tmp_ctx);
1272 return NT_STATUS_NO_MEMORY;
1274 gids = talloc_array(tmp_ctx, gid_t, count);
1275 if (gids == NULL) {
1276 talloc_free(tmp_ctx);
1277 return NT_STATUS_NO_MEMORY;
1279 num_groups = 0;
1281 for (i=0; i<count; i++) {
1282 struct id_map *id_maps[2];
1283 struct id_map id_map;
1284 struct ldb_val *v = &tokengroups->values[i];
1285 enum ndr_err_code ndr_err
1286 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1287 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1288 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1289 talloc_free(tmp_ctx);
1290 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1293 ZERO_STRUCT(id_map);
1294 id_map.sid = &group_sids[num_groups];
1295 id_maps[0] = &id_map;
1296 id_maps[1] = NULL;
1298 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1299 if (!NT_STATUS_IS_OK(status)) {
1300 talloc_free(tmp_ctx);
1301 return status;
1303 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1304 gids[num_groups] = id_map.xid.id;
1305 } else {
1306 DEBUG(1, (__location__
1307 "Group %s, of which %s is a member, could not be converted to a GID\n",
1308 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1309 ldb_dn_get_linearized(msg->dn)));
1310 talloc_free(tmp_ctx);
1311 /* We must error out, otherwise a user might
1312 * avoid a DENY acl based on a group they
1313 * missed out on */
1314 return NT_STATUS_NO_SUCH_GROUP;
1317 num_groups += 1;
1318 if (num_groups == count) {
1319 break;
1323 *pp_sids = talloc_steal(mem_ctx, group_sids);
1324 *pp_gids = talloc_steal(mem_ctx, gids);
1325 *p_num_groups = num_groups;
1326 talloc_free(tmp_ctx);
1327 return NT_STATUS_OK;
1330 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1331 TALLOC_CTX *mem_ctx,
1332 struct samu *user)
1334 return NT_STATUS_NOT_IMPLEMENTED;
1337 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1338 TALLOC_CTX *mem_ctx,
1339 const struct dom_sid *groupsid,
1340 const struct dom_sid *membersid,
1341 int mod_op)
1343 struct pdb_samba4_state *state = talloc_get_type_abort(
1344 m->private_data, struct pdb_samba4_state);
1345 struct ldb_message *msg;
1346 int ret;
1347 struct ldb_message_element *el;
1348 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1349 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1350 msg = ldb_msg_new(tmp_ctx);
1351 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1353 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1354 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1355 talloc_free(tmp_ctx);
1356 return NT_STATUS_NO_MEMORY;
1358 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1359 if (ret != LDB_SUCCESS) {
1360 talloc_free(tmp_ctx);
1361 return NT_STATUS_NO_MEMORY;
1363 el = ldb_msg_find_element(msg, "member");
1364 el->flags = mod_op;
1366 /* No need for transactions here, the ldb auto-transaction
1367 * code will handle things for the single operation */
1368 ret = ldb_modify(state->ldb, msg);
1369 talloc_free(tmp_ctx);
1370 if (ret != LDB_SUCCESS) {
1371 DEBUG(10, ("ldb_modify failed: %s\n",
1372 ldb_errstring(state->ldb)));
1373 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1374 return NT_STATUS_MEMBER_IN_GROUP;
1376 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1377 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1379 return NT_STATUS_LDAP(ret);
1382 return NT_STATUS_OK;
1385 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1386 TALLOC_CTX *mem_ctx,
1387 uint32 grouprid, uint32 memberrid,
1388 int mod_op)
1390 struct pdb_samba4_state *state = talloc_get_type_abort(
1391 m->private_data, struct pdb_samba4_state);
1392 const struct dom_sid *dom_sid, *groupsid, *membersid;
1393 NTSTATUS status;
1394 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1395 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1397 dom_sid = samdb_domain_sid(state->ldb);
1399 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1400 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1401 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1402 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1403 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1404 talloc_free(tmp_ctx);
1405 return status;
1408 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1409 TALLOC_CTX *mem_ctx,
1410 uint32 group_rid, uint32 member_rid)
1412 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1413 LDB_FLAG_MOD_ADD);
1416 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1417 TALLOC_CTX *mem_ctx,
1418 uint32 group_rid, uint32 member_rid)
1420 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1421 LDB_FLAG_MOD_DELETE);
1424 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1425 const char *name, uint32 *rid)
1427 TALLOC_CTX *frame = talloc_stackframe();
1428 struct pdb_samba4_state *state = talloc_get_type_abort(
1429 m->private_data, struct pdb_samba4_state);
1430 struct dom_sid *sid;
1432 struct ldb_dn *dn;
1433 NTSTATUS status;
1435 /* Internally this uses transactions to ensure all the steps
1436 * happen or fail as one */
1437 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1438 if (!NT_STATUS_IS_OK(status)) {
1439 TALLOC_FREE(frame);
1442 sid_peek_rid(sid, rid);
1443 TALLOC_FREE(frame);
1444 return NT_STATUS_OK;
1447 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1448 const struct dom_sid *sid)
1450 const char *attrs[] = { NULL };
1451 struct pdb_samba4_state *state = talloc_get_type_abort(
1452 m->private_data, struct pdb_samba4_state);
1453 struct ldb_message *msg;
1454 struct ldb_dn *dn;
1455 int rc;
1456 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1457 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1459 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1460 if (!dn || !ldb_dn_validate(dn)) {
1461 talloc_free(tmp_ctx);
1462 return NT_STATUS_NO_MEMORY;
1465 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1466 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1467 return NT_STATUS_INTERNAL_ERROR;
1470 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1471 "(|(grouptype=%d)(grouptype=%d)))",
1472 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1473 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1474 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1475 talloc_free(tmp_ctx);
1476 ldb_transaction_cancel(state->ldb);
1477 return NT_STATUS_NO_SUCH_ALIAS;
1479 rc = ldb_delete(state->ldb, dn);
1480 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1481 talloc_free(tmp_ctx);
1482 ldb_transaction_cancel(state->ldb);
1483 return NT_STATUS_NO_SUCH_ALIAS;
1484 } else if (rc != LDB_SUCCESS) {
1485 DEBUG(10, ("ldb_delete failed %s\n",
1486 ldb_errstring(state->ldb)));
1487 ldb_transaction_cancel(state->ldb);
1488 return NT_STATUS_LDAP(rc);
1491 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1492 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1493 ldb_errstring(state->ldb)));
1494 return NT_STATUS_INTERNAL_ERROR;
1497 return NT_STATUS_OK;
1500 #if 0
1501 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1502 const struct dom_sid *sid,
1503 struct acct_info *info)
1505 struct pdb_samba4_state *state = talloc_get_type_abort(
1506 m->private_data, struct pdb_samba4_state);
1507 struct tldap_context *ld;
1508 const char *attrs[3] = { "objectSid", "description",
1509 "samAccountName" };
1510 struct ldb_message **msg;
1511 char *sidstr, *dn;
1512 int rc;
1513 struct tldap_mod *mods;
1514 int num_mods;
1515 bool ok;
1517 ld = pdb_samba4_ld(state);
1518 if (ld == NULL) {
1519 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1522 sidstr = sid_binstring(talloc_tos(), sid);
1523 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1525 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1526 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1527 &msg, "(&(objectSid=%s)(objectclass=group)"
1528 "(|(grouptype=%d)(grouptype=%d)))",
1529 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1530 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1531 TALLOC_FREE(sidstr)
1532 if (rc != LDB_SUCCESS) {
1533 DEBUG(10, ("ldap_search failed %s\n",
1534 ldb_errstring(state->ldb)));
1535 return NT_STATUS_LDAP(rc);
1537 switch talloc_array_length(msg) {
1538 case 0:
1539 return NT_STATUS_NO_SUCH_ALIAS;
1540 case 1:
1541 break;
1542 default:
1543 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1546 if (!tldap_entry_dn(msg[0], &dn)) {
1547 TALLOC_FREE(msg);
1548 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1551 mods = NULL;
1552 num_mods = 0;
1553 ok = true;
1555 ok &= tldap_make_mod_fmt(
1556 msg[0], msg, &num_mods, &mods, "description",
1557 "%s", info->acct_desc);
1558 ok &= tldap_make_mod_fmt(
1559 msg[0], msg, &num_mods, &mods, "samAccountName",
1560 "%s", info->acct_name);
1561 if (!ok) {
1562 TALLOC_FREE(msg);
1563 return NT_STATUS_NO_MEMORY;
1565 if (num_mods == 0) {
1566 /* no change */
1567 TALLOC_FREE(msg);
1568 return NT_STATUS_OK;
1571 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1572 TALLOC_FREE(msg);
1573 if (rc != LDB_SUCCESS) {
1574 DEBUG(10, ("ldap_modify failed: %s\n",
1575 ldb_errstring(state->ldb)));
1576 return NT_STATUS_LDAP(rc);
1578 return NT_STATUS_OK;
1580 #endif
1581 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1582 const struct dom_sid *alias,
1583 const struct dom_sid *member)
1585 NTSTATUS status;
1586 TALLOC_CTX *frame = talloc_stackframe();
1587 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1588 talloc_free(frame);
1589 return status;
1592 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1593 const struct dom_sid *alias,
1594 const struct dom_sid *member)
1596 NTSTATUS status;
1597 TALLOC_CTX *frame = talloc_stackframe();
1598 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1599 talloc_free(frame);
1600 return status;
1603 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1604 const struct dom_sid *alias,
1605 TALLOC_CTX *mem_ctx,
1606 struct dom_sid **pmembers,
1607 size_t *pnum_members)
1609 struct pdb_samba4_state *state = talloc_get_type_abort(
1610 m->private_data, struct pdb_samba4_state);
1611 struct ldb_dn *dn;
1612 unsigned int num_members;
1613 NTSTATUS status;
1614 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1615 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1617 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1618 if (!dn || !ldb_dn_validate(dn)) {
1619 return NT_STATUS_NO_MEMORY;
1622 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1623 *pnum_members = num_members;
1624 if (NT_STATUS_IS_OK(status)) {
1625 talloc_steal(mem_ctx, pmembers);
1627 talloc_free(tmp_ctx);
1628 return status;
1631 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1632 TALLOC_CTX *mem_ctx,
1633 const struct dom_sid *domain_sid,
1634 const struct dom_sid *members,
1635 size_t num_members,
1636 uint32_t **palias_rids,
1637 size_t *pnum_alias_rids)
1639 struct pdb_samba4_state *state = talloc_get_type_abort(
1640 m->private_data, struct pdb_samba4_state);
1641 uint32_t *alias_rids = NULL;
1642 size_t num_alias_rids = 0;
1643 int i;
1644 struct dom_sid *groupSIDs = NULL;
1645 unsigned int num_groupSIDs = 0;
1646 char *filter;
1647 NTSTATUS status;
1648 const char *sid_string;
1649 const char *sid_dn;
1650 DATA_BLOB sid_blob;
1652 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1653 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1655 * TODO: Get the filter right so that we only get the aliases from
1656 * either the SAM or BUILTIN
1659 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1660 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1661 if (filter == NULL) {
1662 return NT_STATUS_NO_MEMORY;
1665 for (i = 0; i < num_members; i++) {
1666 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1667 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1669 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1670 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1672 sid_blob = data_blob_string_const(sid_dn);
1674 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1675 tmp_ctx, &groupSIDs, &num_groupSIDs);
1676 if (!NT_STATUS_IS_OK(status)) {
1677 talloc_free(tmp_ctx);
1678 return status;
1682 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1683 if (alias_rids == NULL) {
1684 talloc_free(tmp_ctx);
1685 return NT_STATUS_NO_MEMORY;
1688 for (i=0; i<num_groupSIDs; i++) {
1689 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1690 &alias_rids[num_alias_rids])) {
1691 num_alias_rids++;;
1695 *palias_rids = alias_rids;
1696 *pnum_alias_rids = num_alias_rids;
1697 return NT_STATUS_OK;
1700 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1701 const struct dom_sid *domain_sid,
1702 int num_rids,
1703 uint32 *rids,
1704 const char **names,
1705 enum lsa_SidType *lsa_attrs)
1707 struct pdb_samba4_state *state = talloc_get_type_abort(
1708 m->private_data, struct pdb_samba4_state);
1709 NTSTATUS status;
1711 TALLOC_CTX *tmp_ctx;
1713 if (num_rids == 0) {
1714 return NT_STATUS_NONE_MAPPED;
1717 tmp_ctx = talloc_stackframe();
1718 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1720 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1721 talloc_free(tmp_ctx);
1722 return status;
1725 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1726 const struct dom_sid *domain_sid,
1727 int num_names,
1728 const char **pp_names,
1729 uint32 *rids,
1730 enum lsa_SidType *attrs)
1732 return NT_STATUS_NOT_IMPLEMENTED;
1735 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1736 enum pdb_policy_type type,
1737 uint32_t *value)
1739 return account_policy_get(type, value)
1740 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1743 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1744 enum pdb_policy_type type,
1745 uint32_t value)
1747 return account_policy_set(type, value)
1748 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1751 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1752 time_t *seq_num_out)
1754 struct pdb_samba4_state *state = talloc_get_type_abort(
1755 m->private_data, struct pdb_samba4_state);
1756 uint64_t seq_num;
1757 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1758 if (ret == LDB_SUCCESS) {
1759 *seq_num_out = seq_num;
1760 return NT_STATUS_OK;
1761 } else {
1762 return NT_STATUS_UNSUCCESSFUL;
1766 struct pdb_samba4_search_state {
1767 uint32_t acct_flags;
1768 struct samr_displayentry *entries;
1769 uint32_t num_entries;
1770 ssize_t array_size;
1771 uint32_t current;
1774 static bool pdb_samba4_next_entry(struct pdb_search *search,
1775 struct samr_displayentry *entry)
1777 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1778 search->private_data, struct pdb_samba4_search_state);
1780 if (state->current == state->num_entries) {
1781 return false;
1784 entry->idx = state->entries[state->current].idx;
1785 entry->rid = state->entries[state->current].rid;
1786 entry->acct_flags = state->entries[state->current].acct_flags;
1788 entry->account_name = talloc_strdup(
1789 search, state->entries[state->current].account_name);
1790 entry->fullname = talloc_strdup(
1791 search, state->entries[state->current].fullname);
1792 entry->description = talloc_strdup(
1793 search, state->entries[state->current].description);
1795 state->current += 1;
1796 return true;
1799 static void pdb_samba4_search_end(struct pdb_search *search)
1801 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1802 search->private_data, struct pdb_samba4_search_state);
1803 talloc_free(state);
1806 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1807 struct pdb_search *search,
1808 struct pdb_samba4_search_state **pstate,
1809 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1811 struct pdb_samba4_state *state = talloc_get_type_abort(
1812 m->private_data, struct pdb_samba4_state);
1813 struct pdb_samba4_search_state *sstate;
1814 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1815 "userAccountControl", "description", NULL };
1816 struct ldb_result *res;
1817 int i, rc, num_users;
1819 va_list ap;
1820 char *expression = NULL;
1822 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1823 if (!tmp_ctx) {
1824 return false;
1827 va_start(ap, exp_fmt);
1828 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1829 va_end(ap);
1831 if (!expression) {
1832 talloc_free(tmp_ctx);
1833 return LDB_ERR_OPERATIONS_ERROR;
1836 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1837 if (sstate == NULL) {
1838 talloc_free(tmp_ctx);
1839 return false;
1842 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1843 if (rc != LDB_SUCCESS) {
1844 talloc_free(tmp_ctx);
1845 DEBUG(10, ("dsdb_search failed: %s\n",
1846 ldb_errstring(state->ldb)));
1847 return false;
1850 num_users = res->count;
1852 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1853 num_users);
1854 if (sstate->entries == NULL) {
1855 talloc_free(tmp_ctx);
1856 DEBUG(10, ("talloc failed\n"));
1857 return false;
1860 sstate->num_entries = 0;
1862 for (i=0; i<num_users; i++) {
1863 struct samr_displayentry *e;
1864 struct dom_sid *sid;
1866 e = &sstate->entries[sstate->num_entries];
1868 e->idx = sstate->num_entries;
1869 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1870 if (!sid) {
1871 talloc_free(tmp_ctx);
1872 DEBUG(10, ("Could not pull SID\n"));
1873 return false;
1875 sid_peek_rid(sid, &e->rid);
1877 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1878 res->msgs[i],
1879 ldb_get_default_basedn(state->ldb));
1880 e->account_name = ldb_msg_find_attr_as_string(
1881 res->msgs[i], "samAccountName", NULL);
1882 if (e->account_name == NULL) {
1883 talloc_free(tmp_ctx);
1884 return false;
1886 e->fullname = ldb_msg_find_attr_as_string(
1887 res->msgs[i], "displayName", "");
1888 e->description = ldb_msg_find_attr_as_string(
1889 res->msgs[i], "description", "");
1891 sstate->num_entries += 1;
1892 if (sstate->num_entries >= num_users) {
1893 break;
1896 talloc_steal(sstate->entries, res->msgs);
1897 search->private_data = talloc_steal(search, sstate);
1898 search->next_entry = pdb_samba4_next_entry;
1899 search->search_end = pdb_samba4_search_end;
1900 *pstate = sstate;
1901 talloc_free(tmp_ctx);
1902 return true;
1905 static bool pdb_samba4_search_users(struct pdb_methods *m,
1906 struct pdb_search *search,
1907 uint32 acct_flags)
1909 struct pdb_samba4_search_state *sstate;
1910 bool ret;
1912 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1913 if (!ret) {
1914 return false;
1916 sstate->acct_flags = acct_flags;
1917 return true;
1920 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1921 struct pdb_search *search)
1923 struct pdb_samba4_search_state *sstate;
1924 bool ret;
1926 ret = pdb_samba4_search_filter(m, search, &sstate,
1927 "(&(grouptype=%d)(objectclass=group))",
1928 GTYPE_SECURITY_GLOBAL_GROUP);
1929 if (!ret) {
1930 return false;
1932 sstate->acct_flags = 0;
1933 return true;
1936 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1937 struct pdb_search *search,
1938 const struct dom_sid *sid)
1940 struct pdb_samba4_search_state *sstate;
1941 bool ret;
1943 ret = pdb_samba4_search_filter(m, search, &sstate,
1944 "(&(grouptype=%d)(objectclass=group))",
1945 sid_check_is_builtin(sid)
1946 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1947 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1948 if (!ret) {
1949 return false;
1951 sstate->acct_flags = 0;
1952 return true;
1955 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1956 struct dom_sid *sid)
1958 struct pdb_samba4_state *state = talloc_get_type_abort(
1959 m->private_data, struct pdb_samba4_state);
1960 NTSTATUS status;
1961 struct id_map id_map;
1962 struct id_map *id_maps[2];
1963 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1964 if (!tmp_ctx) {
1965 return false;
1968 id_map.xid.id = uid;
1969 id_map.xid.type = ID_TYPE_UID;
1970 id_maps[0] = &id_map;
1971 id_maps[1] = NULL;
1973 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1974 if (!NT_STATUS_IS_OK(status)) {
1975 talloc_free(tmp_ctx);
1976 return false;
1978 *sid = *id_map.sid;
1979 talloc_free(tmp_ctx);
1980 return true;
1983 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1984 struct dom_sid *sid)
1986 struct pdb_samba4_state *state = talloc_get_type_abort(
1987 m->private_data, struct pdb_samba4_state);
1988 NTSTATUS status;
1989 struct id_map id_map;
1990 struct id_map *id_maps[2];
1991 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1992 if (!tmp_ctx) {
1993 return false;
1996 id_map.xid.id = gid;
1997 id_map.xid.type = ID_TYPE_GID;
1998 id_maps[0] = &id_map;
1999 id_maps[1] = NULL;
2001 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2002 if (!NT_STATUS_IS_OK(status)) {
2003 return false;
2005 *sid = *id_map.sid;
2006 talloc_free(tmp_ctx);
2007 return true;
2010 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2011 uid_t *uid, gid_t *gid, enum lsa_SidType *type)
2013 struct pdb_samba4_state *state = talloc_get_type_abort(
2014 m->private_data, struct pdb_samba4_state);
2015 struct id_map id_map;
2016 struct id_map *id_maps[2];
2017 const char *attrs[] = { "objectClass", "groupType", NULL };
2018 struct ldb_message *msg;
2019 struct ldb_dn *dn;
2020 NTSTATUS status;
2021 int rc;
2022 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2023 if (!tmp_ctx) {
2024 return false;
2027 ZERO_STRUCT(id_map);
2029 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2030 if (!dn || !ldb_dn_validate(dn)) {
2031 talloc_free(tmp_ctx);
2032 return false;
2034 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2035 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2036 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)));
2037 talloc_free(tmp_ctx);
2038 return false;
2040 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2041 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
2042 switch (grouptype) {
2043 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
2044 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
2045 *type = SID_NAME_ALIAS;
2046 break;
2047 case GTYPE_SECURITY_GLOBAL_GROUP:
2048 *type = SID_NAME_DOM_GRP;
2049 break;
2050 default:
2051 talloc_free(tmp_ctx);
2052 DEBUG(10, ("Could not pull groupType\n"));
2053 return false;
2056 *type = SID_NAME_DOM_GRP;
2058 ZERO_STRUCT(id_map);
2059 id_map.sid = sid;
2060 id_maps[0] = &id_map;
2061 id_maps[1] = NULL;
2063 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2064 talloc_free(tmp_ctx);
2065 if (!NT_STATUS_IS_OK(status)) {
2066 return false;
2068 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
2069 *gid = id_map.xid.id;
2070 return true;
2072 return false;
2073 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2074 *type = SID_NAME_USER;
2075 ZERO_STRUCT(id_map);
2076 id_map.sid = sid;
2077 id_maps[0] = &id_map;
2078 id_maps[1] = NULL;
2080 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2081 talloc_free(tmp_ctx);
2082 if (!NT_STATUS_IS_OK(status)) {
2083 return false;
2085 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2086 *uid = id_map.xid.id;
2087 return true;
2089 return false;
2091 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)));
2092 talloc_free(tmp_ctx);
2093 return false;
2096 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2098 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2101 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2103 return false;
2106 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2107 const char *domain, char** pwd,
2108 struct dom_sid *sid,
2109 time_t *pass_last_set_time)
2111 return false;
2114 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2115 const char* domain, const char* pwd,
2116 const struct dom_sid *sid)
2118 return false;
2121 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2122 const char *domain)
2124 return false;
2127 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2128 TALLOC_CTX *mem_ctx,
2129 uint32 *num_domains,
2130 struct trustdom_info ***domains)
2132 *num_domains = 0;
2133 *domains = NULL;
2134 return NT_STATUS_OK;
2137 static void pdb_samba4_init_methods(struct pdb_methods *m)
2139 m->name = "samba4";
2140 m->get_domain_info = pdb_samba4_get_domain_info;
2141 m->getsampwnam = pdb_samba4_getsampwnam;
2142 m->getsampwsid = pdb_samba4_getsampwsid;
2143 m->create_user = pdb_samba4_create_user;
2144 m->delete_user = pdb_samba4_delete_user;
2145 m->add_sam_account = pdb_samba4_add_sam_account;
2146 m->update_sam_account = pdb_samba4_update_sam_account;
2147 m->delete_sam_account = pdb_samba4_delete_sam_account;
2148 m->rename_sam_account = pdb_samba4_rename_sam_account;
2149 m->update_login_attempts = pdb_samba4_update_login_attempts;
2150 m->getgrsid = pdb_samba4_getgrsid;
2151 m->getgrgid = pdb_samba4_getgrgid;
2152 m->getgrnam = pdb_samba4_getgrnam;
2153 m->create_dom_group = pdb_samba4_create_dom_group;
2154 m->delete_dom_group = pdb_samba4_delete_dom_group;
2155 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2156 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2157 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2158 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2159 m->enum_group_members = pdb_samba4_enum_group_members;
2160 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2161 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2162 m->add_groupmem = pdb_samba4_add_groupmem;
2163 m->del_groupmem = pdb_samba4_del_groupmem;
2164 m->create_alias = pdb_samba4_create_alias;
2165 m->delete_alias = pdb_samba4_delete_alias;
2166 m->get_aliasinfo = pdb_default_get_aliasinfo;
2167 m->add_aliasmem = pdb_samba4_add_aliasmem;
2168 m->del_aliasmem = pdb_samba4_del_aliasmem;
2169 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2170 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2171 m->lookup_rids = pdb_samba4_lookup_rids;
2172 m->lookup_names = pdb_samba4_lookup_names;
2173 m->get_account_policy = pdb_samba4_get_account_policy;
2174 m->set_account_policy = pdb_samba4_set_account_policy;
2175 m->get_seq_num = pdb_samba4_get_seq_num;
2176 m->search_users = pdb_samba4_search_users;
2177 m->search_groups = pdb_samba4_search_groups;
2178 m->search_aliases = pdb_samba4_search_aliases;
2179 m->uid_to_sid = pdb_samba4_uid_to_sid;
2180 m->gid_to_sid = pdb_samba4_gid_to_sid;
2181 m->sid_to_id = pdb_samba4_sid_to_id;
2182 m->capabilities = pdb_samba4_capabilities;
2183 m->new_rid = pdb_samba4_new_rid;
2184 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2185 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2186 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2187 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2190 static void free_private_data(void **vp)
2192 struct pdb_samba4_state *state = talloc_get_type_abort(
2193 *vp, struct pdb_samba4_state);
2194 talloc_unlink(state, state->ldb);
2195 return;
2198 static NTSTATUS pdb_samba4_init_secrets(struct pdb_methods *m)
2200 struct pdb_domain_info *dom_info;
2201 bool ret;
2203 dom_info = pdb_samba4_get_domain_info(m, m);
2204 if (!dom_info) {
2205 return NT_STATUS_UNSUCCESSFUL;
2208 secrets_clear_domain_protection(dom_info->name);
2209 ret = secrets_store_domain_sid(dom_info->name,
2210 &dom_info->sid);
2211 if (!ret) {
2212 goto done;
2214 ret = secrets_store_domain_guid(dom_info->name,
2215 &dom_info->guid);
2216 if (!ret) {
2217 goto done;
2219 ret = secrets_mark_domain_protected(dom_info->name);
2220 if (!ret) {
2221 goto done;
2224 done:
2225 TALLOC_FREE(dom_info);
2226 if (!ret) {
2227 return NT_STATUS_UNSUCCESSFUL;
2229 return NT_STATUS_OK;
2232 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2233 const char *location)
2235 struct pdb_methods *m;
2236 struct pdb_samba4_state *state;
2237 NTSTATUS status;
2239 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2240 return status;
2243 state = talloc_zero(m, struct pdb_samba4_state);
2244 if (state == NULL) {
2245 goto nomem;
2247 m->private_data = state;
2248 m->free_private_data = free_private_data;
2249 pdb_samba4_init_methods(m);
2251 state->ev = s4_event_context_init(state);
2252 if (!state->ev) {
2253 DEBUG(0, ("s4_event_context_init failed\n"));
2254 goto nomem;
2257 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2258 if (state->lp_ctx == NULL) {
2259 DEBUG(0, ("loadparm_init_s3 failed\n"));
2260 goto nomem;
2263 if (location) {
2264 state->ldb = samdb_connect_url(state,
2265 state->ev,
2266 state->lp_ctx,
2267 system_session(state->lp_ctx),
2268 0, location);
2269 } else {
2270 state->ldb = samdb_connect(state,
2271 state->ev,
2272 state->lp_ctx,
2273 system_session(state->lp_ctx), 0);
2276 if (!state->ldb) {
2277 DEBUG(0, ("samdb_connect failed\n"));
2278 status = NT_STATUS_INTERNAL_ERROR;
2279 goto fail;
2282 state->idmap_ctx = idmap_init(state, state->ev,
2283 state->lp_ctx);
2284 if (!state->idmap_ctx) {
2285 DEBUG(0, ("idmap failed\n"));
2286 status = NT_STATUS_INTERNAL_ERROR;
2287 goto fail;
2290 status = pdb_samba4_init_secrets(m);
2291 if (!NT_STATUS_IS_OK(status)) {
2292 DEBUG(10, ("pdb_samba4_init_secrets failed!\n"));
2293 goto fail;
2296 *pdb_method = m;
2297 return NT_STATUS_OK;
2298 nomem:
2299 status = NT_STATUS_NO_MEMORY;
2300 fail:
2301 TALLOC_FREE(m);
2302 return status;
2305 NTSTATUS pdb_samba4_init(void);
2306 NTSTATUS pdb_samba4_init(void)
2308 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2309 pdb_init_samba4);