tevent: expose tevent_context_init_ops
[Samba/gebeck_regimport.git] / source3 / passdb / pdb_samba4.c
blob22a59084d7183453ec09481743a2c84189b5ea23
1 /*
2 Unix SMB/CIFS implementation.
3 pdb glue module for samba4
4 Copyright (C) Volker Lendecke 2009-2011
5 Copyright (C) Andrew Bartlett 2010
6 Copyright (C) Matthias Dieter Wallnöfer 2009
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* This module, is a port of Volker's pdb_ads to ldb and DSDB APIs */
24 #include "includes.h"
25 #include "source3/include/passdb.h"
26 #include "source4/dsdb/samdb/samdb.h"
27 #include "ldb_errors.h"
28 #include "libcli/security/dom_sid.h"
29 #include "source4/winbind/idmap.h"
30 #include "librpc/gen_ndr/ndr_security.h"
31 #include "libds/common/flag_mapping.h"
32 #include "source4/lib/events/events.h"
33 #include "source4/auth/session.h"
34 #include "source4/auth/system_session_proto.h"
35 #include "lib/param/param.h"
36 #include "source4/dsdb/common/util.h"
37 #include "source3/include/secrets.h"
39 struct pdb_samba4_state {
40 struct tevent_context *ev;
41 struct ldb_context *ldb;
42 struct idmap_context *idmap_ctx;
43 struct loadparm_context *lp_ctx;
46 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
47 struct samu *sam_acct,
48 const struct dom_sid *sid);
49 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
50 const char *filter,
51 TALLOC_CTX *mem_ctx,
52 struct ldb_message **pmsg);
53 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
54 struct unixid *id);
56 static bool pdb_samba4_pull_time(struct ldb_message *msg, const char *attr,
57 time_t *ptime)
59 uint64_t tmp;
60 if (! ldb_msg_find_element(msg, attr)) {
61 return false;
63 tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
64 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
65 return true;
68 static struct pdb_domain_info *pdb_samba4_get_domain_info(
69 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
71 struct pdb_samba4_state *state = talloc_get_type_abort(
72 m->private_data, struct pdb_samba4_state);
73 struct pdb_domain_info *info;
74 struct dom_sid *domain_sid;
75 struct ldb_dn *forest_dn, *domain_dn;
76 struct ldb_result *dom_res = NULL;
77 const char *dom_attrs[] = {
78 "objectSid",
79 "objectGUID",
80 "fSMORoleOwner",
81 NULL
83 char *p;
84 int ret;
86 info = talloc(mem_ctx, struct pdb_domain_info);
87 if (info == NULL) {
88 return NULL;
91 domain_dn = ldb_get_default_basedn(state->ldb);
93 ret = ldb_search(state->ldb, info, &dom_res,
94 domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
95 if (ret != LDB_SUCCESS) {
96 goto fail;
98 if (dom_res->count != 1) {
99 goto fail;
102 info->guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
104 domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
105 if (!domain_sid) {
106 goto fail;
108 info->sid = *domain_sid;
110 TALLOC_FREE(dom_res);
112 info->name = talloc_strdup(info, lpcfg_sam_name(state->lp_ctx));
113 info->dns_domain = ldb_dn_canonical_string(info, domain_dn);
115 if (!info->dns_domain) {
116 goto fail;
118 p = strchr(info->dns_domain, '/');
119 if (p) {
120 *p = '\0';
123 forest_dn = ldb_get_root_basedn(state->ldb);
124 if (!forest_dn) {
125 goto fail;
128 info->dns_forest = ldb_dn_canonical_string(info, forest_dn);
129 if (!info->dns_forest) {
130 goto fail;
132 p = strchr(info->dns_forest, '/');
133 if (p) {
134 *p = '\0';
137 return info;
139 fail:
140 TALLOC_FREE(dom_res);
141 TALLOC_FREE(info);
142 return NULL;
145 static struct ldb_message *pdb_samba4_get_samu_private(
146 struct pdb_methods *m, struct samu *sam)
148 struct pdb_samba4_state *state = talloc_get_type_abort(
149 m->private_data, struct pdb_samba4_state);
150 struct ldb_message *msg;
151 char *sidstr, *filter;
152 NTSTATUS status;
154 msg = (struct ldb_message *)
155 pdb_get_backend_private_data(sam, m);
157 if (msg != NULL) {
158 return talloc_get_type_abort(msg, struct ldb_message);
161 sidstr = dom_sid_string(talloc_tos(), pdb_get_user_sid(sam));
162 if (sidstr == NULL) {
163 return NULL;
166 filter = talloc_asprintf(
167 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
168 TALLOC_FREE(sidstr);
169 if (filter == NULL) {
170 return NULL;
173 status = pdb_samba4_getsamupriv(state, filter, sam, &msg);
174 TALLOC_FREE(filter);
175 if (!NT_STATUS_IS_OK(status)) {
176 return NULL;
179 return msg;
182 static NTSTATUS pdb_samba4_init_sam_from_priv(struct pdb_methods *m,
183 struct samu *sam,
184 struct ldb_message *msg)
186 struct pdb_samba4_state *state = talloc_get_type_abort(
187 m->private_data, struct pdb_samba4_state);
188 TALLOC_CTX *frame = talloc_stackframe();
189 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
190 const char *str;
191 time_t tmp_time;
192 struct dom_sid *sid, group_sid;
193 uint64_t n;
194 const DATA_BLOB *blob;
196 str = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
197 if (str == NULL) {
198 DEBUG(10, ("no samAccountName\n"));
199 goto fail;
201 pdb_set_username(sam, str, PDB_SET);
203 if (pdb_samba4_pull_time(msg, "lastLogon", &tmp_time)) {
204 pdb_set_logon_time(sam, tmp_time, PDB_SET);
206 if (pdb_samba4_pull_time(msg, "lastLogoff", &tmp_time)) {
207 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
209 if (pdb_samba4_pull_time(msg, "pwdLastSet", &tmp_time)) {
210 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
212 if (pdb_samba4_pull_time(msg, "accountExpires", &tmp_time)) {
213 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
216 str = ldb_msg_find_attr_as_string(msg, "displayName",
217 NULL);
218 if (str != NULL) {
219 pdb_set_fullname(sam, str, PDB_SET);
222 str = ldb_msg_find_attr_as_string(msg, "homeDirectory",
223 NULL);
224 if (str != NULL) {
225 pdb_set_homedir(sam, str, PDB_SET);
228 str = ldb_msg_find_attr_as_string(msg, "homeDrive", NULL);
229 if (str != NULL) {
230 pdb_set_dir_drive(sam, str, PDB_SET);
233 str = ldb_msg_find_attr_as_string(msg, "scriptPath", NULL);
234 if (str != NULL) {
235 pdb_set_logon_script(sam, str, PDB_SET);
238 str = ldb_msg_find_attr_as_string(msg, "profilePath",
239 NULL);
240 if (str != NULL) {
241 pdb_set_profile_path(sam, str, PDB_SET);
244 str = ldb_msg_find_attr_as_string(msg, "profilePath",
245 NULL);
246 if (str != NULL) {
247 pdb_set_profile_path(sam, str, PDB_SET);
250 str = ldb_msg_find_attr_as_string(msg, "comment",
251 NULL);
252 if (str != NULL) {
253 pdb_set_comment(sam, str, PDB_SET);
256 str = ldb_msg_find_attr_as_string(msg, "description",
257 NULL);
258 if (str != NULL) {
259 pdb_set_acct_desc(sam, str, PDB_SET);
262 str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
263 NULL);
264 if (str != NULL) {
265 pdb_set_workstations(sam, str, PDB_SET);
268 str = ldb_msg_find_attr_as_string(msg, "userParameters",
269 NULL);
270 if (str != NULL) {
271 pdb_set_munged_dial(sam, str, PDB_SET);
274 sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
275 if (!sid) {
276 DEBUG(10, ("Could not pull SID\n"));
277 goto fail;
279 pdb_set_user_sid(sam, sid, PDB_SET);
281 n = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
282 if (n == 0) {
283 DEBUG(10, ("Could not pull userAccountControl\n"));
284 goto fail;
286 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
288 blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
289 if (blob) {
290 if (blob->length != NT_HASH_LEN) {
291 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
292 (int)blob->length, NT_HASH_LEN));
293 goto fail;
295 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
298 blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
299 if (blob) {
300 if (blob->length != LM_HASH_LEN) {
301 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
302 (int)blob->length, LM_HASH_LEN));
303 goto fail;
305 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
308 n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
309 if (n == 0) {
310 DEBUG(10, ("Could not pull primaryGroupID\n"));
311 goto fail;
313 sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
314 pdb_set_group_sid(sam, &group_sid, PDB_SET);
316 status = NT_STATUS_OK;
317 fail:
318 TALLOC_FREE(frame);
319 return status;
322 static bool pdb_samba4_add_time(struct ldb_message *msg,
323 const char *attrib, time_t t)
325 uint64_t nt_time;
327 unix_to_nt_time(&nt_time, t);
329 return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
332 static int pdb_samba4_replace_by_sam(struct pdb_samba4_state *state,
333 bool (*need_update)(const struct samu *,
334 enum pdb_elements),
335 struct ldb_dn *dn,
336 struct samu *sam)
338 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", "groupType",
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 struct id_map id_map;
864 struct id_map *id_maps[2];
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 (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
898 NTSTATUS status;
899 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
900 switch (grouptype) {
901 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
902 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
903 map->sid_name_use = SID_NAME_ALIAS;
904 break;
905 case GTYPE_SECURITY_GLOBAL_GROUP:
906 map->sid_name_use = SID_NAME_DOM_GRP;
907 break;
908 default:
909 talloc_free(tmp_ctx);
910 DEBUG(10, ("Could not pull groupType\n"));
911 return NT_STATUS_INTERNAL_DB_CORRUPTION;
914 map->sid_name_use = SID_NAME_DOM_GRP;
916 ZERO_STRUCT(id_map);
917 id_map.sid = sid;
918 id_maps[0] = &id_map;
919 id_maps[1] = NULL;
921 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
922 talloc_free(tmp_ctx);
923 if (!NT_STATUS_IS_OK(status)) {
924 talloc_free(tmp_ctx);
925 return status;
927 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
928 map->gid = id_map.xid.id;
929 } else {
930 DEBUG(1, (__location__ "Did not get GUID when mapping SID for %s", expression));
931 talloc_free(tmp_ctx);
932 return NT_STATUS_INTERNAL_DB_CORRUPTION;
934 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
935 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
936 talloc_free(tmp_ctx);
937 return NT_STATUS_INTERNAL_DB_CORRUPTION;
940 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
941 NULL);
942 if (str == NULL) {
943 talloc_free(tmp_ctx);
944 return NT_STATUS_INTERNAL_DB_CORRUPTION;
946 map->nt_name = talloc_strdup(map, str);
947 if (!map->nt_name) {
948 talloc_free(tmp_ctx);
949 return NT_STATUS_NO_MEMORY;
952 str = ldb_msg_find_attr_as_string(msg, "description",
953 NULL);
954 if (str != NULL) {
955 map->comment = talloc_strdup(map, str);
956 } else {
957 map->comment = talloc_strdup(map, "");
959 if (!map->comment) {
960 talloc_free(tmp_ctx);
961 return NT_STATUS_NO_MEMORY;
964 talloc_free(tmp_ctx);
965 return NT_STATUS_OK;
968 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
969 struct dom_sid sid)
971 char *filter;
972 NTSTATUS status;
974 filter = talloc_asprintf(talloc_tos(),
975 "(&(objectsid=%s)(objectclass=group))",
976 sid_string_talloc(talloc_tos(), &sid));
977 if (filter == NULL) {
978 return NT_STATUS_NO_MEMORY;
981 status = pdb_samba4_getgrfilter(m, map, filter);
982 TALLOC_FREE(filter);
983 return status;
986 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
987 gid_t gid)
989 struct pdb_samba4_state *state = talloc_get_type_abort(
990 m->private_data, struct pdb_samba4_state);
991 NTSTATUS status;
992 struct id_map id_map;
993 struct id_map *id_maps[2];
994 TALLOC_CTX *tmp_ctx = talloc_stackframe();
995 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
997 id_map.xid.id = gid;
998 id_map.xid.type = ID_TYPE_GID;
999 id_maps[0] = &id_map;
1000 id_maps[1] = NULL;
1002 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1003 if (!NT_STATUS_IS_OK(status)) {
1004 return status;
1006 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
1007 talloc_free(tmp_ctx);
1008 return status;
1011 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
1012 const char *name)
1014 char *filter;
1015 NTSTATUS status;
1017 filter = talloc_asprintf(talloc_tos(),
1018 "(&(samaccountname=%s)(objectclass=group))",
1019 name);
1020 if (filter == NULL) {
1021 return NT_STATUS_NO_MEMORY;
1024 status = pdb_samba4_getgrfilter(m, map, filter);
1025 TALLOC_FREE(filter);
1026 return status;
1029 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
1030 TALLOC_CTX *mem_ctx, const char *name,
1031 uint32 *rid)
1033 struct pdb_samba4_state *state = talloc_get_type_abort(
1034 m->private_data, struct pdb_samba4_state);
1035 NTSTATUS status;
1036 struct dom_sid *sid;
1037 struct ldb_dn *dn;
1038 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1039 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1041 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1042 if (!NT_STATUS_IS_OK(status)) {
1043 talloc_free(tmp_ctx);
1044 return status;
1047 sid_peek_rid(sid, rid);
1048 talloc_free(tmp_ctx);
1049 return NT_STATUS_OK;
1052 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1053 TALLOC_CTX *mem_ctx, uint32 rid)
1055 const char *attrs[] = { NULL };
1056 struct pdb_samba4_state *state = talloc_get_type_abort(
1057 m->private_data, struct pdb_samba4_state);
1058 struct dom_sid sid;
1059 struct ldb_message *msg;
1060 struct ldb_dn *dn;
1061 int rc;
1062 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1063 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1065 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1067 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1068 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1069 return NT_STATUS_INTERNAL_ERROR;
1072 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1073 if (!dn || !ldb_dn_validate(dn)) {
1074 talloc_free(tmp_ctx);
1075 ldb_transaction_cancel(state->ldb);
1076 return NT_STATUS_NO_MEMORY;
1078 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1079 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1080 talloc_free(tmp_ctx);
1081 ldb_transaction_cancel(state->ldb);
1082 return NT_STATUS_NO_SUCH_GROUP;
1084 rc = ldb_delete(state->ldb, dn);
1085 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1086 talloc_free(tmp_ctx);
1087 ldb_transaction_cancel(state->ldb);
1088 return NT_STATUS_NO_SUCH_GROUP;
1089 } else if (rc != LDB_SUCCESS) {
1090 DEBUG(10, ("ldb_delete failed %s\n",
1091 ldb_errstring(state->ldb)));
1092 ldb_transaction_cancel(state->ldb);
1093 return NT_STATUS_LDAP(rc);
1096 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1097 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1098 return NT_STATUS_INTERNAL_ERROR;
1100 return NT_STATUS_OK;
1103 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1104 GROUP_MAP *map)
1106 return NT_STATUS_NOT_IMPLEMENTED;
1109 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1110 GROUP_MAP *map)
1112 return NT_STATUS_NOT_IMPLEMENTED;
1115 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1116 struct dom_sid sid)
1118 return NT_STATUS_NOT_IMPLEMENTED;
1121 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1122 const struct dom_sid *sid,
1123 enum lsa_SidType sid_name_use,
1124 GROUP_MAP ***pp_rmap,
1125 size_t *p_num_entries,
1126 bool unix_only)
1128 return NT_STATUS_NOT_IMPLEMENTED;
1131 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1132 TALLOC_CTX *mem_ctx,
1133 const struct dom_sid *group,
1134 uint32_t **pmembers,
1135 size_t *pnum_members)
1137 unsigned int i, num_sids, num_members;
1138 struct pdb_samba4_state *state = talloc_get_type_abort(
1139 m->private_data, struct pdb_samba4_state);
1140 struct dom_sid *members_as_sids;
1141 struct dom_sid *dom_sid;
1142 uint32_t *members;
1143 struct ldb_dn *dn;
1144 NTSTATUS status;
1146 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1147 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1149 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1150 if (!dn || !ldb_dn_validate(dn)) {
1151 return NT_STATUS_NO_MEMORY;
1154 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1155 if (!NT_STATUS_IS_OK(status)) {
1156 talloc_free(tmp_ctx);
1157 return status;
1159 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1160 if (!NT_STATUS_IS_OK(status)) {
1161 talloc_free(tmp_ctx);
1162 return status;
1165 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1166 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1167 num_members = 0;
1169 for (i = 0; i < num_sids; i++) {
1170 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1171 continue;
1173 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1174 NULL, &members[num_members]);
1175 if (!NT_STATUS_IS_OK(status)) {
1176 talloc_free(tmp_ctx);
1177 return status;
1179 num_members++;
1181 *pnum_members = num_members;
1182 return NT_STATUS_OK;
1185 /* Just convert the primary group SID into a group */
1186 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1187 TALLOC_CTX *mem_ctx,
1188 struct samu *user,
1189 struct dom_sid **pp_sids,
1190 gid_t **pp_gids,
1191 uint32_t *p_num_groups)
1193 NTSTATUS status;
1194 size_t num_groups = 0;
1195 struct dom_sid *group_sids;
1196 gid_t *gids;
1197 TALLOC_CTX *tmp_ctx;
1199 tmp_ctx = talloc_new(mem_ctx);
1200 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1202 if (user->group_sid) {
1203 struct id_map *id_maps[2];
1204 struct id_map id_map;
1206 num_groups = 1;
1208 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1209 if (group_sids == NULL) {
1210 talloc_free(tmp_ctx);
1211 return NT_STATUS_NO_MEMORY;
1213 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1214 if (gids == NULL) {
1215 talloc_free(tmp_ctx);
1216 return NT_STATUS_NO_MEMORY;
1219 group_sids[0] = *user->group_sid;
1221 ZERO_STRUCT(id_map);
1222 id_map.sid = &group_sids[0];
1223 id_maps[0] = &id_map;
1224 id_maps[1] = NULL;
1226 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1227 if (!NT_STATUS_IS_OK(status)) {
1228 talloc_free(tmp_ctx);
1229 return status;
1231 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1232 gids[0] = id_map.xid.id;
1233 } else {
1234 DEBUG(1, (__location__
1235 "Group %s, of which %s is a member, could not be converted to a GID\n",
1236 dom_sid_string(tmp_ctx, &group_sids[0]),
1237 dom_sid_string(tmp_ctx, &user->user_sid)));
1238 talloc_free(tmp_ctx);
1239 /* We must error out, otherwise a user might
1240 * avoid a DENY acl based on a group they
1241 * missed out on */
1242 return NT_STATUS_NO_SUCH_GROUP;
1246 *pp_sids = talloc_steal(mem_ctx, group_sids);
1247 *pp_gids = talloc_steal(mem_ctx, gids);
1248 *p_num_groups = num_groups;
1249 talloc_free(tmp_ctx);
1250 return NT_STATUS_OK;
1253 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1254 TALLOC_CTX *mem_ctx,
1255 struct samu *user,
1256 struct dom_sid **pp_sids,
1257 gid_t **pp_gids,
1258 uint32_t *p_num_groups)
1260 struct pdb_samba4_state *state = talloc_get_type_abort(
1261 m->private_data, struct pdb_samba4_state);
1262 struct ldb_message *msg = pdb_samba4_get_samu_private(
1263 m, user);
1264 const char *attrs[] = { "tokenGroups", NULL};
1265 struct ldb_message *tokengroups_msg;
1266 struct ldb_message_element *tokengroups;
1267 int i, rc;
1268 NTSTATUS status;
1269 unsigned int count = 0;
1270 size_t num_groups;
1271 struct dom_sid *group_sids;
1272 gid_t *gids;
1273 TALLOC_CTX *tmp_ctx;
1275 if (msg == NULL) {
1276 /* Fake up some things here */
1277 return fake_enum_group_memberships(state,
1278 mem_ctx,
1279 user, pp_sids,
1280 pp_gids, p_num_groups);
1283 tmp_ctx = talloc_new(mem_ctx);
1284 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1286 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1288 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1289 talloc_free(tmp_ctx);
1290 return NT_STATUS_NO_SUCH_USER;
1291 } else if (rc != LDB_SUCCESS) {
1292 DEBUG(10, ("dsdb_search_one failed %s\n",
1293 ldb_errstring(state->ldb)));
1294 talloc_free(tmp_ctx);
1295 return NT_STATUS_LDAP(rc);
1298 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1300 if (tokengroups) {
1301 count = tokengroups->num_values;
1304 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1305 if (group_sids == NULL) {
1306 talloc_free(tmp_ctx);
1307 return NT_STATUS_NO_MEMORY;
1309 gids = talloc_array(tmp_ctx, gid_t, count);
1310 if (gids == NULL) {
1311 talloc_free(tmp_ctx);
1312 return NT_STATUS_NO_MEMORY;
1314 num_groups = 0;
1316 for (i=0; i<count; i++) {
1317 struct id_map *id_maps[2];
1318 struct id_map id_map;
1319 struct ldb_val *v = &tokengroups->values[i];
1320 enum ndr_err_code ndr_err
1321 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1322 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1323 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1324 talloc_free(tmp_ctx);
1325 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1328 ZERO_STRUCT(id_map);
1329 id_map.sid = &group_sids[num_groups];
1330 id_maps[0] = &id_map;
1331 id_maps[1] = NULL;
1333 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1334 if (!NT_STATUS_IS_OK(status)) {
1335 talloc_free(tmp_ctx);
1336 return status;
1338 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1339 gids[num_groups] = id_map.xid.id;
1340 } else {
1341 DEBUG(1, (__location__
1342 "Group %s, of which %s is a member, could not be converted to a GID\n",
1343 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1344 ldb_dn_get_linearized(msg->dn)));
1345 talloc_free(tmp_ctx);
1346 /* We must error out, otherwise a user might
1347 * avoid a DENY acl based on a group they
1348 * missed out on */
1349 return NT_STATUS_NO_SUCH_GROUP;
1352 num_groups += 1;
1353 if (num_groups == count) {
1354 break;
1358 *pp_sids = talloc_steal(mem_ctx, group_sids);
1359 *pp_gids = talloc_steal(mem_ctx, gids);
1360 *p_num_groups = num_groups;
1361 talloc_free(tmp_ctx);
1362 return NT_STATUS_OK;
1365 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1366 TALLOC_CTX *mem_ctx,
1367 struct samu *user)
1369 return NT_STATUS_NOT_IMPLEMENTED;
1372 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1373 TALLOC_CTX *mem_ctx,
1374 const struct dom_sid *groupsid,
1375 const struct dom_sid *membersid,
1376 int mod_op)
1378 struct pdb_samba4_state *state = talloc_get_type_abort(
1379 m->private_data, struct pdb_samba4_state);
1380 struct ldb_message *msg;
1381 int ret;
1382 struct ldb_message_element *el;
1383 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1384 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1385 msg = ldb_msg_new(tmp_ctx);
1386 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1388 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1389 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1390 talloc_free(tmp_ctx);
1391 return NT_STATUS_NO_MEMORY;
1393 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1394 if (ret != LDB_SUCCESS) {
1395 talloc_free(tmp_ctx);
1396 return NT_STATUS_NO_MEMORY;
1398 el = ldb_msg_find_element(msg, "member");
1399 el->flags = mod_op;
1401 /* No need for transactions here, the ldb auto-transaction
1402 * code will handle things for the single operation */
1403 ret = ldb_modify(state->ldb, msg);
1404 talloc_free(tmp_ctx);
1405 if (ret != LDB_SUCCESS) {
1406 DEBUG(10, ("ldb_modify failed: %s\n",
1407 ldb_errstring(state->ldb)));
1408 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1409 return NT_STATUS_MEMBER_IN_GROUP;
1411 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1412 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1414 return NT_STATUS_LDAP(ret);
1417 return NT_STATUS_OK;
1420 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1421 TALLOC_CTX *mem_ctx,
1422 uint32 grouprid, uint32 memberrid,
1423 int mod_op)
1425 struct pdb_samba4_state *state = talloc_get_type_abort(
1426 m->private_data, struct pdb_samba4_state);
1427 const struct dom_sid *dom_sid, *groupsid, *membersid;
1428 NTSTATUS status;
1429 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1430 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1432 dom_sid = samdb_domain_sid(state->ldb);
1434 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1435 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1436 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1437 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1438 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1439 talloc_free(tmp_ctx);
1440 return status;
1443 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1444 TALLOC_CTX *mem_ctx,
1445 uint32 group_rid, uint32 member_rid)
1447 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1448 LDB_FLAG_MOD_ADD);
1451 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1452 TALLOC_CTX *mem_ctx,
1453 uint32 group_rid, uint32 member_rid)
1455 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1456 LDB_FLAG_MOD_DELETE);
1459 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1460 const char *name, uint32 *rid)
1462 TALLOC_CTX *frame = talloc_stackframe();
1463 struct pdb_samba4_state *state = talloc_get_type_abort(
1464 m->private_data, struct pdb_samba4_state);
1465 struct dom_sid *sid;
1467 struct ldb_dn *dn;
1468 NTSTATUS status;
1470 /* Internally this uses transactions to ensure all the steps
1471 * happen or fail as one */
1472 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1473 if (!NT_STATUS_IS_OK(status)) {
1474 TALLOC_FREE(frame);
1477 sid_peek_rid(sid, rid);
1478 TALLOC_FREE(frame);
1479 return NT_STATUS_OK;
1482 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1483 const struct dom_sid *sid)
1485 const char *attrs[] = { NULL };
1486 struct pdb_samba4_state *state = talloc_get_type_abort(
1487 m->private_data, struct pdb_samba4_state);
1488 struct ldb_message *msg;
1489 struct ldb_dn *dn;
1490 int rc;
1491 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1492 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1494 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1495 if (!dn || !ldb_dn_validate(dn)) {
1496 talloc_free(tmp_ctx);
1497 return NT_STATUS_NO_MEMORY;
1500 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1501 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1502 return NT_STATUS_INTERNAL_ERROR;
1505 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1506 "(|(grouptype=%d)(grouptype=%d)))",
1507 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1508 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1509 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1510 talloc_free(tmp_ctx);
1511 ldb_transaction_cancel(state->ldb);
1512 return NT_STATUS_NO_SUCH_ALIAS;
1514 rc = ldb_delete(state->ldb, dn);
1515 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1516 talloc_free(tmp_ctx);
1517 ldb_transaction_cancel(state->ldb);
1518 return NT_STATUS_NO_SUCH_ALIAS;
1519 } else if (rc != LDB_SUCCESS) {
1520 DEBUG(10, ("ldb_delete failed %s\n",
1521 ldb_errstring(state->ldb)));
1522 ldb_transaction_cancel(state->ldb);
1523 return NT_STATUS_LDAP(rc);
1526 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1527 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1528 ldb_errstring(state->ldb)));
1529 return NT_STATUS_INTERNAL_ERROR;
1532 return NT_STATUS_OK;
1535 #if 0
1536 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1537 const struct dom_sid *sid,
1538 struct acct_info *info)
1540 struct pdb_samba4_state *state = talloc_get_type_abort(
1541 m->private_data, struct pdb_samba4_state);
1542 struct tldap_context *ld;
1543 const char *attrs[3] = { "objectSid", "description",
1544 "samAccountName" };
1545 struct ldb_message **msg;
1546 char *sidstr, *dn;
1547 int rc;
1548 struct tldap_mod *mods;
1549 int num_mods;
1550 bool ok;
1552 ld = pdb_samba4_ld(state);
1553 if (ld == NULL) {
1554 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1557 sidstr = sid_binstring(talloc_tos(), sid);
1558 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1560 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1561 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1562 &msg, "(&(objectSid=%s)(objectclass=group)"
1563 "(|(grouptype=%d)(grouptype=%d)))",
1564 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1565 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1566 TALLOC_FREE(sidstr)
1567 if (rc != LDB_SUCCESS) {
1568 DEBUG(10, ("ldap_search failed %s\n",
1569 ldb_errstring(state->ldb)));
1570 return NT_STATUS_LDAP(rc);
1572 switch talloc_array_length(msg) {
1573 case 0:
1574 return NT_STATUS_NO_SUCH_ALIAS;
1575 case 1:
1576 break;
1577 default:
1578 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1581 if (!tldap_entry_dn(msg[0], &dn)) {
1582 TALLOC_FREE(msg);
1583 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1586 mods = NULL;
1587 num_mods = 0;
1588 ok = true;
1590 ok &= tldap_make_mod_fmt(
1591 msg[0], msg, &num_mods, &mods, "description",
1592 "%s", info->acct_desc);
1593 ok &= tldap_make_mod_fmt(
1594 msg[0], msg, &num_mods, &mods, "samAccountName",
1595 "%s", info->acct_name);
1596 if (!ok) {
1597 TALLOC_FREE(msg);
1598 return NT_STATUS_NO_MEMORY;
1600 if (num_mods == 0) {
1601 /* no change */
1602 TALLOC_FREE(msg);
1603 return NT_STATUS_OK;
1606 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1607 TALLOC_FREE(msg);
1608 if (rc != LDB_SUCCESS) {
1609 DEBUG(10, ("ldap_modify failed: %s\n",
1610 ldb_errstring(state->ldb)));
1611 return NT_STATUS_LDAP(rc);
1613 return NT_STATUS_OK;
1615 #endif
1616 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1617 const struct dom_sid *alias,
1618 const struct dom_sid *member)
1620 NTSTATUS status;
1621 TALLOC_CTX *frame = talloc_stackframe();
1622 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1623 talloc_free(frame);
1624 return status;
1627 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1628 const struct dom_sid *alias,
1629 const struct dom_sid *member)
1631 NTSTATUS status;
1632 TALLOC_CTX *frame = talloc_stackframe();
1633 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1634 talloc_free(frame);
1635 return status;
1638 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1639 const struct dom_sid *alias,
1640 TALLOC_CTX *mem_ctx,
1641 struct dom_sid **pmembers,
1642 size_t *pnum_members)
1644 struct pdb_samba4_state *state = talloc_get_type_abort(
1645 m->private_data, struct pdb_samba4_state);
1646 struct ldb_dn *dn;
1647 unsigned int num_members;
1648 NTSTATUS status;
1649 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1650 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1652 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1653 if (!dn || !ldb_dn_validate(dn)) {
1654 return NT_STATUS_NO_MEMORY;
1657 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1658 *pnum_members = num_members;
1659 if (NT_STATUS_IS_OK(status)) {
1660 talloc_steal(mem_ctx, pmembers);
1662 talloc_free(tmp_ctx);
1663 return status;
1666 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1667 TALLOC_CTX *mem_ctx,
1668 const struct dom_sid *domain_sid,
1669 const struct dom_sid *members,
1670 size_t num_members,
1671 uint32_t **palias_rids,
1672 size_t *pnum_alias_rids)
1674 struct pdb_samba4_state *state = talloc_get_type_abort(
1675 m->private_data, struct pdb_samba4_state);
1676 uint32_t *alias_rids = NULL;
1677 size_t num_alias_rids = 0;
1678 int i;
1679 struct dom_sid *groupSIDs = NULL;
1680 unsigned int num_groupSIDs = 0;
1681 char *filter;
1682 NTSTATUS status;
1683 const char *sid_string;
1684 const char *sid_dn;
1685 DATA_BLOB sid_blob;
1687 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1688 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1690 * TODO: Get the filter right so that we only get the aliases from
1691 * either the SAM or BUILTIN
1694 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1695 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1696 if (filter == NULL) {
1697 return NT_STATUS_NO_MEMORY;
1700 for (i = 0; i < num_members; i++) {
1701 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1702 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1704 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1705 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1707 sid_blob = data_blob_string_const(sid_dn);
1709 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1710 tmp_ctx, &groupSIDs, &num_groupSIDs);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 talloc_free(tmp_ctx);
1713 return status;
1717 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1718 if (alias_rids == NULL) {
1719 talloc_free(tmp_ctx);
1720 return NT_STATUS_NO_MEMORY;
1723 for (i=0; i<num_groupSIDs; i++) {
1724 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1725 &alias_rids[num_alias_rids])) {
1726 num_alias_rids++;;
1730 *palias_rids = alias_rids;
1731 *pnum_alias_rids = num_alias_rids;
1732 return NT_STATUS_OK;
1735 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1736 const struct dom_sid *domain_sid,
1737 int num_rids,
1738 uint32 *rids,
1739 const char **names,
1740 enum lsa_SidType *lsa_attrs)
1742 struct pdb_samba4_state *state = talloc_get_type_abort(
1743 m->private_data, struct pdb_samba4_state);
1744 NTSTATUS status;
1746 TALLOC_CTX *tmp_ctx;
1748 if (num_rids == 0) {
1749 return NT_STATUS_NONE_MAPPED;
1752 tmp_ctx = talloc_stackframe();
1753 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1755 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1756 talloc_free(tmp_ctx);
1757 return status;
1760 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1761 const struct dom_sid *domain_sid,
1762 int num_names,
1763 const char **pp_names,
1764 uint32 *rids,
1765 enum lsa_SidType *attrs)
1767 return NT_STATUS_NOT_IMPLEMENTED;
1770 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1771 enum pdb_policy_type type,
1772 uint32_t *value)
1774 return account_policy_get(type, value)
1775 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1778 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1779 enum pdb_policy_type type,
1780 uint32_t value)
1782 return account_policy_set(type, value)
1783 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1786 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1787 time_t *seq_num_out)
1789 struct pdb_samba4_state *state = talloc_get_type_abort(
1790 m->private_data, struct pdb_samba4_state);
1791 uint64_t seq_num;
1792 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1793 if (ret == LDB_SUCCESS) {
1794 *seq_num_out = seq_num;
1795 return NT_STATUS_OK;
1796 } else {
1797 return NT_STATUS_UNSUCCESSFUL;
1801 struct pdb_samba4_search_state {
1802 uint32_t acct_flags;
1803 struct samr_displayentry *entries;
1804 uint32_t num_entries;
1805 ssize_t array_size;
1806 uint32_t current;
1809 static bool pdb_samba4_next_entry(struct pdb_search *search,
1810 struct samr_displayentry *entry)
1812 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1813 search->private_data, struct pdb_samba4_search_state);
1815 if (state->current == state->num_entries) {
1816 return false;
1819 entry->idx = state->entries[state->current].idx;
1820 entry->rid = state->entries[state->current].rid;
1821 entry->acct_flags = state->entries[state->current].acct_flags;
1823 entry->account_name = talloc_strdup(
1824 search, state->entries[state->current].account_name);
1825 entry->fullname = talloc_strdup(
1826 search, state->entries[state->current].fullname);
1827 entry->description = talloc_strdup(
1828 search, state->entries[state->current].description);
1830 state->current += 1;
1831 return true;
1834 static void pdb_samba4_search_end(struct pdb_search *search)
1836 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1837 search->private_data, struct pdb_samba4_search_state);
1838 talloc_free(state);
1841 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1842 struct pdb_search *search,
1843 struct pdb_samba4_search_state **pstate,
1844 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1846 struct pdb_samba4_state *state = talloc_get_type_abort(
1847 m->private_data, struct pdb_samba4_state);
1848 struct pdb_samba4_search_state *sstate;
1849 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1850 "userAccountControl", "description", NULL };
1851 struct ldb_result *res;
1852 int i, rc, num_users;
1854 va_list ap;
1855 char *expression = NULL;
1857 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1858 if (!tmp_ctx) {
1859 return false;
1862 va_start(ap, exp_fmt);
1863 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1864 va_end(ap);
1866 if (!expression) {
1867 talloc_free(tmp_ctx);
1868 return LDB_ERR_OPERATIONS_ERROR;
1871 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1872 if (sstate == NULL) {
1873 talloc_free(tmp_ctx);
1874 return false;
1877 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1878 if (rc != LDB_SUCCESS) {
1879 talloc_free(tmp_ctx);
1880 DEBUG(10, ("dsdb_search failed: %s\n",
1881 ldb_errstring(state->ldb)));
1882 return false;
1885 num_users = res->count;
1887 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1888 num_users);
1889 if (sstate->entries == NULL) {
1890 talloc_free(tmp_ctx);
1891 DEBUG(10, ("talloc failed\n"));
1892 return false;
1895 sstate->num_entries = 0;
1897 for (i=0; i<num_users; i++) {
1898 struct samr_displayentry *e;
1899 struct dom_sid *sid;
1901 e = &sstate->entries[sstate->num_entries];
1903 e->idx = sstate->num_entries;
1904 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1905 if (!sid) {
1906 talloc_free(tmp_ctx);
1907 DEBUG(10, ("Could not pull SID\n"));
1908 return false;
1910 sid_peek_rid(sid, &e->rid);
1912 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1913 res->msgs[i],
1914 ldb_get_default_basedn(state->ldb));
1915 e->account_name = ldb_msg_find_attr_as_string(
1916 res->msgs[i], "samAccountName", NULL);
1917 if (e->account_name == NULL) {
1918 talloc_free(tmp_ctx);
1919 return false;
1921 e->fullname = ldb_msg_find_attr_as_string(
1922 res->msgs[i], "displayName", "");
1923 e->description = ldb_msg_find_attr_as_string(
1924 res->msgs[i], "description", "");
1926 sstate->num_entries += 1;
1927 if (sstate->num_entries >= num_users) {
1928 break;
1931 talloc_steal(sstate->entries, res->msgs);
1932 search->private_data = talloc_steal(search, sstate);
1933 search->next_entry = pdb_samba4_next_entry;
1934 search->search_end = pdb_samba4_search_end;
1935 *pstate = sstate;
1936 talloc_free(tmp_ctx);
1937 return true;
1940 static bool pdb_samba4_search_users(struct pdb_methods *m,
1941 struct pdb_search *search,
1942 uint32 acct_flags)
1944 struct pdb_samba4_search_state *sstate;
1945 bool ret;
1947 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1948 if (!ret) {
1949 return false;
1951 sstate->acct_flags = acct_flags;
1952 return true;
1955 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1956 struct pdb_search *search)
1958 struct pdb_samba4_search_state *sstate;
1959 bool ret;
1961 ret = pdb_samba4_search_filter(m, search, &sstate,
1962 "(&(grouptype=%d)(objectclass=group))",
1963 GTYPE_SECURITY_GLOBAL_GROUP);
1964 if (!ret) {
1965 return false;
1967 sstate->acct_flags = 0;
1968 return true;
1971 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1972 struct pdb_search *search,
1973 const struct dom_sid *sid)
1975 struct pdb_samba4_search_state *sstate;
1976 bool ret;
1978 ret = pdb_samba4_search_filter(m, search, &sstate,
1979 "(&(grouptype=%d)(objectclass=group))",
1980 sid_check_is_builtin(sid)
1981 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1982 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1983 if (!ret) {
1984 return false;
1986 sstate->acct_flags = 0;
1987 return true;
1990 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1991 struct dom_sid *sid)
1993 struct pdb_samba4_state *state = talloc_get_type_abort(
1994 m->private_data, struct pdb_samba4_state);
1995 NTSTATUS status;
1996 struct id_map id_map;
1997 struct id_map *id_maps[2];
1998 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1999 if (!tmp_ctx) {
2000 return false;
2003 id_map.xid.id = uid;
2004 id_map.xid.type = ID_TYPE_UID;
2005 id_maps[0] = &id_map;
2006 id_maps[1] = NULL;
2008 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2009 if (!NT_STATUS_IS_OK(status)) {
2010 talloc_free(tmp_ctx);
2011 return false;
2013 *sid = *id_map.sid;
2014 talloc_free(tmp_ctx);
2015 return true;
2018 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
2019 struct dom_sid *sid)
2021 struct pdb_samba4_state *state = talloc_get_type_abort(
2022 m->private_data, struct pdb_samba4_state);
2023 NTSTATUS status;
2024 struct id_map id_map;
2025 struct id_map *id_maps[2];
2026 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2027 if (!tmp_ctx) {
2028 return false;
2031 id_map.xid.id = gid;
2032 id_map.xid.type = ID_TYPE_GID;
2033 id_maps[0] = &id_map;
2034 id_maps[1] = NULL;
2036 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
2037 if (!NT_STATUS_IS_OK(status)) {
2038 return false;
2040 *sid = *id_map.sid;
2041 talloc_free(tmp_ctx);
2042 return true;
2045 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2046 struct unixid *id)
2048 struct pdb_samba4_state *state = talloc_get_type_abort(
2049 m->private_data, struct pdb_samba4_state);
2050 struct id_map id_map;
2051 struct id_map *id_maps[2];
2052 const char *attrs[] = { "objectClass", NULL };
2053 struct ldb_message *msg;
2054 struct ldb_dn *dn;
2055 NTSTATUS status;
2056 int rc;
2057 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2058 if (!tmp_ctx) {
2059 return false;
2062 ZERO_STRUCT(id_map);
2064 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2065 if (!dn || !ldb_dn_validate(dn)) {
2066 talloc_free(tmp_ctx);
2067 return false;
2069 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2070 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2071 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)));
2072 talloc_free(tmp_ctx);
2073 return false;
2075 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2076 id->type = ID_TYPE_GID;
2078 ZERO_STRUCT(id_map);
2079 id_map.sid = sid;
2080 id_maps[0] = &id_map;
2081 id_maps[1] = NULL;
2083 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2084 talloc_free(tmp_ctx);
2085 if (!NT_STATUS_IS_OK(status)) {
2086 return false;
2088 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
2089 id->id = id_map.xid.id;
2090 return true;
2092 return false;
2093 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2094 id->type = ID_TYPE_UID;
2095 ZERO_STRUCT(id_map);
2096 id_map.sid = sid;
2097 id_maps[0] = &id_map;
2098 id_maps[1] = NULL;
2100 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2101 talloc_free(tmp_ctx);
2102 if (!NT_STATUS_IS_OK(status)) {
2103 return false;
2105 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2106 id->id = id_map.xid.id;
2107 return true;
2109 return false;
2111 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)));
2112 talloc_free(tmp_ctx);
2113 return false;
2116 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2118 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2121 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2123 return false;
2126 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2127 const char *domain, char** pwd,
2128 struct dom_sid *sid,
2129 time_t *pass_last_set_time)
2131 return false;
2134 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2135 const char* domain, const char* pwd,
2136 const struct dom_sid *sid)
2138 return false;
2141 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2142 const char *domain)
2144 return false;
2147 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2148 TALLOC_CTX *mem_ctx,
2149 uint32 *num_domains,
2150 struct trustdom_info ***domains)
2152 *num_domains = 0;
2153 *domains = NULL;
2154 return NT_STATUS_OK;
2157 static void pdb_samba4_init_methods(struct pdb_methods *m)
2159 m->name = "samba4";
2160 m->get_domain_info = pdb_samba4_get_domain_info;
2161 m->getsampwnam = pdb_samba4_getsampwnam;
2162 m->getsampwsid = pdb_samba4_getsampwsid;
2163 m->create_user = pdb_samba4_create_user;
2164 m->delete_user = pdb_samba4_delete_user;
2165 m->add_sam_account = pdb_samba4_add_sam_account;
2166 m->update_sam_account = pdb_samba4_update_sam_account;
2167 m->delete_sam_account = pdb_samba4_delete_sam_account;
2168 m->rename_sam_account = pdb_samba4_rename_sam_account;
2169 m->update_login_attempts = pdb_samba4_update_login_attempts;
2170 m->getgrsid = pdb_samba4_getgrsid;
2171 m->getgrgid = pdb_samba4_getgrgid;
2172 m->getgrnam = pdb_samba4_getgrnam;
2173 m->create_dom_group = pdb_samba4_create_dom_group;
2174 m->delete_dom_group = pdb_samba4_delete_dom_group;
2175 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2176 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2177 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2178 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2179 m->enum_group_members = pdb_samba4_enum_group_members;
2180 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2181 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2182 m->add_groupmem = pdb_samba4_add_groupmem;
2183 m->del_groupmem = pdb_samba4_del_groupmem;
2184 m->create_alias = pdb_samba4_create_alias;
2185 m->delete_alias = pdb_samba4_delete_alias;
2186 m->get_aliasinfo = pdb_default_get_aliasinfo;
2187 m->add_aliasmem = pdb_samba4_add_aliasmem;
2188 m->del_aliasmem = pdb_samba4_del_aliasmem;
2189 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2190 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2191 m->lookup_rids = pdb_samba4_lookup_rids;
2192 m->lookup_names = pdb_samba4_lookup_names;
2193 m->get_account_policy = pdb_samba4_get_account_policy;
2194 m->set_account_policy = pdb_samba4_set_account_policy;
2195 m->get_seq_num = pdb_samba4_get_seq_num;
2196 m->search_users = pdb_samba4_search_users;
2197 m->search_groups = pdb_samba4_search_groups;
2198 m->search_aliases = pdb_samba4_search_aliases;
2199 m->uid_to_sid = pdb_samba4_uid_to_sid;
2200 m->gid_to_sid = pdb_samba4_gid_to_sid;
2201 m->sid_to_id = pdb_samba4_sid_to_id;
2202 m->capabilities = pdb_samba4_capabilities;
2203 m->new_rid = pdb_samba4_new_rid;
2204 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2205 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2206 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2207 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2210 static void free_private_data(void **vp)
2212 struct pdb_samba4_state *state = talloc_get_type_abort(
2213 *vp, struct pdb_samba4_state);
2214 talloc_unlink(state, state->ldb);
2215 return;
2218 static NTSTATUS pdb_samba4_init_secrets(struct pdb_methods *m)
2220 struct pdb_domain_info *dom_info;
2221 bool ret;
2223 dom_info = pdb_samba4_get_domain_info(m, m);
2224 if (!dom_info) {
2225 return NT_STATUS_UNSUCCESSFUL;
2228 secrets_clear_domain_protection(dom_info->name);
2229 ret = secrets_store_domain_sid(dom_info->name,
2230 &dom_info->sid);
2231 if (!ret) {
2232 goto done;
2234 ret = secrets_store_domain_guid(dom_info->name,
2235 &dom_info->guid);
2236 if (!ret) {
2237 goto done;
2239 ret = secrets_mark_domain_protected(dom_info->name);
2240 if (!ret) {
2241 goto done;
2244 done:
2245 TALLOC_FREE(dom_info);
2246 if (!ret) {
2247 return NT_STATUS_UNSUCCESSFUL;
2249 return NT_STATUS_OK;
2252 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2253 const char *location)
2255 struct pdb_methods *m;
2256 struct pdb_samba4_state *state;
2257 NTSTATUS status;
2259 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2260 return status;
2263 state = talloc_zero(m, struct pdb_samba4_state);
2264 if (state == NULL) {
2265 goto nomem;
2267 m->private_data = state;
2268 m->free_private_data = free_private_data;
2269 pdb_samba4_init_methods(m);
2271 state->ev = s4_event_context_init(state);
2272 if (!state->ev) {
2273 DEBUG(0, ("s4_event_context_init failed\n"));
2274 goto nomem;
2277 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2278 if (state->lp_ctx == NULL) {
2279 DEBUG(0, ("loadparm_init_s3 failed\n"));
2280 goto nomem;
2283 if (location) {
2284 state->ldb = samdb_connect_url(state,
2285 state->ev,
2286 state->lp_ctx,
2287 system_session(state->lp_ctx),
2288 0, location);
2289 } else {
2290 state->ldb = samdb_connect(state,
2291 state->ev,
2292 state->lp_ctx,
2293 system_session(state->lp_ctx), 0);
2296 if (!state->ldb) {
2297 DEBUG(0, ("samdb_connect failed\n"));
2298 status = NT_STATUS_INTERNAL_ERROR;
2299 goto fail;
2302 state->idmap_ctx = idmap_init(state, state->ev,
2303 state->lp_ctx);
2304 if (!state->idmap_ctx) {
2305 DEBUG(0, ("idmap failed\n"));
2306 status = NT_STATUS_INTERNAL_ERROR;
2307 goto fail;
2310 status = pdb_samba4_init_secrets(m);
2311 if (!NT_STATUS_IS_OK(status)) {
2312 DEBUG(10, ("pdb_samba4_init_secrets failed!\n"));
2313 goto fail;
2316 *pdb_method = m;
2317 return NT_STATUS_OK;
2318 nomem:
2319 status = NT_STATUS_NO_MEMORY;
2320 fail:
2321 TALLOC_FREE(m);
2322 return status;
2325 NTSTATUS pdb_samba4_init(void);
2326 NTSTATUS pdb_samba4_init(void)
2328 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2329 pdb_init_samba4);