s3-gse: fix SECRETS_AND_KEYTAB fallback in gse_krb5_get_server_keytab()
[Samba/gbeck.git] / source3 / passdb / pdb_samba4.c
blob8da9b3cf5a0254a7396ebfe8a2d264d50dc19832
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"
38 struct pdb_samba4_state {
39 struct tevent_context *ev;
40 struct ldb_context *ldb;
41 struct idmap_context *idmap_ctx;
42 struct loadparm_context *lp_ctx;
45 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
46 struct samu *sam_acct,
47 const struct dom_sid *sid);
48 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
49 const char *filter,
50 TALLOC_CTX *mem_ctx,
51 struct ldb_message **pmsg);
52 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
53 uid_t *uid, gid_t *gid, enum lsa_SidType *type);
55 static bool pdb_samba4_pull_time(struct ldb_message *msg, const char *attr,
56 time_t *ptime)
58 uint64_t tmp;
59 if (! ldb_msg_find_element(msg, attr)) {
60 return false;
62 tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
63 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
64 return true;
67 static struct pdb_domain_info *pdb_samba4_get_domain_info(
68 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
70 struct pdb_samba4_state *state = talloc_get_type_abort(
71 m->private_data, struct pdb_samba4_state);
72 struct pdb_domain_info *info;
73 struct dom_sid *domain_sid;
74 struct ldb_dn *forest_dn, *domain_dn;
75 struct ldb_result *dom_res = NULL;
76 const char *dom_attrs[] = {
77 "objectSid",
78 "objectGUID",
79 "fSMORoleOwner",
80 NULL
82 char *p;
83 int ret;
85 info = talloc(mem_ctx, struct pdb_domain_info);
86 if (info == NULL) {
87 return NULL;
90 domain_dn = ldb_get_default_basedn(state->ldb);
92 ret = ldb_search(state->ldb, info, &dom_res,
93 domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
94 if (ret != LDB_SUCCESS) {
95 goto fail;
97 if (dom_res->count != 1) {
98 goto fail;
101 info->guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");
103 domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
104 if (!domain_sid) {
105 goto fail;
107 info->sid = *domain_sid;
109 TALLOC_FREE(dom_res);
111 info->name = talloc_strdup(info, lpcfg_sam_name(state->lp_ctx));
112 info->dns_domain = ldb_dn_canonical_string(info, domain_dn);
114 if (!info->dns_domain) {
115 goto fail;
117 p = strchr(info->dns_domain, '/');
118 if (p) {
119 *p = '\0';
122 forest_dn = ldb_get_root_basedn(state->ldb);
123 if (!forest_dn) {
124 goto fail;
127 info->dns_forest = ldb_dn_canonical_string(info, forest_dn);
128 if (!info->dns_forest) {
129 goto fail;
131 p = strchr(info->dns_forest, '/');
132 if (p) {
133 *p = '\0';
136 return info;
138 fail:
139 TALLOC_FREE(dom_res);
140 TALLOC_FREE(info);
141 return NULL;
144 static struct ldb_message *pdb_samba4_get_samu_private(
145 struct pdb_methods *m, struct samu *sam)
147 struct pdb_samba4_state *state = talloc_get_type_abort(
148 m->private_data, struct pdb_samba4_state);
149 struct ldb_message *msg;
150 char *sidstr, *filter;
151 NTSTATUS status;
153 msg = (struct ldb_message *)
154 pdb_get_backend_private_data(sam, m);
156 if (msg != NULL) {
157 return talloc_get_type_abort(msg, struct ldb_message);
160 sidstr = dom_sid_string(talloc_tos(), pdb_get_user_sid(sam));
161 if (sidstr == NULL) {
162 return NULL;
165 filter = talloc_asprintf(
166 talloc_tos(), "(&(objectsid=%s)(objectclass=user))", sidstr);
167 TALLOC_FREE(sidstr);
168 if (filter == NULL) {
169 return NULL;
172 status = pdb_samba4_getsamupriv(state, filter, sam, &msg);
173 TALLOC_FREE(filter);
174 if (!NT_STATUS_IS_OK(status)) {
175 return NULL;
178 return msg;
181 static NTSTATUS pdb_samba4_init_sam_from_priv(struct pdb_methods *m,
182 struct samu *sam,
183 struct ldb_message *msg)
185 struct pdb_samba4_state *state = talloc_get_type_abort(
186 m->private_data, struct pdb_samba4_state);
187 TALLOC_CTX *frame = talloc_stackframe();
188 NTSTATUS status = NT_STATUS_INTERNAL_DB_CORRUPTION;
189 const char *str;
190 time_t tmp_time;
191 struct dom_sid *sid, group_sid;
192 uint64_t n;
193 const DATA_BLOB *blob;
195 str = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
196 if (str == NULL) {
197 DEBUG(10, ("no samAccountName\n"));
198 goto fail;
200 pdb_set_username(sam, str, PDB_SET);
202 if (pdb_samba4_pull_time(msg, "lastLogon", &tmp_time)) {
203 pdb_set_logon_time(sam, tmp_time, PDB_SET);
205 if (pdb_samba4_pull_time(msg, "lastLogoff", &tmp_time)) {
206 pdb_set_logoff_time(sam, tmp_time, PDB_SET);
208 if (pdb_samba4_pull_time(msg, "pwdLastSet", &tmp_time)) {
209 pdb_set_pass_last_set_time(sam, tmp_time, PDB_SET);
211 if (pdb_samba4_pull_time(msg, "accountExpires", &tmp_time)) {
212 pdb_set_kickoff_time(sam, tmp_time, PDB_SET);
215 str = ldb_msg_find_attr_as_string(msg, "displayName",
216 NULL);
217 if (str != NULL) {
218 pdb_set_fullname(sam, str, PDB_SET);
221 str = ldb_msg_find_attr_as_string(msg, "homeDirectory",
222 NULL);
223 if (str != NULL) {
224 pdb_set_homedir(sam, str, PDB_SET);
227 str = ldb_msg_find_attr_as_string(msg, "homeDrive", NULL);
228 if (str != NULL) {
229 pdb_set_dir_drive(sam, str, PDB_SET);
232 str = ldb_msg_find_attr_as_string(msg, "scriptPath", NULL);
233 if (str != NULL) {
234 pdb_set_logon_script(sam, str, PDB_SET);
237 str = ldb_msg_find_attr_as_string(msg, "profilePath",
238 NULL);
239 if (str != NULL) {
240 pdb_set_profile_path(sam, str, PDB_SET);
243 str = ldb_msg_find_attr_as_string(msg, "profilePath",
244 NULL);
245 if (str != NULL) {
246 pdb_set_profile_path(sam, str, PDB_SET);
249 str = ldb_msg_find_attr_as_string(msg, "comment",
250 NULL);
251 if (str != NULL) {
252 pdb_set_comment(sam, str, PDB_SET);
255 str = ldb_msg_find_attr_as_string(msg, "description",
256 NULL);
257 if (str != NULL) {
258 pdb_set_acct_desc(sam, str, PDB_SET);
261 str = ldb_msg_find_attr_as_string(msg, "userWorkstations",
262 NULL);
263 if (str != NULL) {
264 pdb_set_workstations(sam, str, PDB_SET);
267 str = ldb_msg_find_attr_as_string(msg, "userParameters",
268 NULL);
269 if (str != NULL) {
270 pdb_set_munged_dial(sam, str, PDB_SET);
273 sid = samdb_result_dom_sid(talloc_tos(), msg, "objectSid");
274 if (!sid) {
275 DEBUG(10, ("Could not pull SID\n"));
276 goto fail;
278 pdb_set_user_sid(sam, sid, PDB_SET);
280 n = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
281 if (n == 0) {
282 DEBUG(10, ("Could not pull userAccountControl\n"));
283 goto fail;
285 pdb_set_acct_ctrl(sam, ds_uf2acb(n), PDB_SET);
287 blob = ldb_msg_find_ldb_val(msg, "unicodePwd");
288 if (blob) {
289 if (blob->length != NT_HASH_LEN) {
290 DEBUG(0, ("Got NT hash of length %d, expected %d\n",
291 (int)blob->length, NT_HASH_LEN));
292 goto fail;
294 pdb_set_nt_passwd(sam, blob->data, PDB_SET);
297 blob = ldb_msg_find_ldb_val(msg, "dBCSPwd");
298 if (blob) {
299 if (blob->length != LM_HASH_LEN) {
300 DEBUG(0, ("Got LM hash of length %d, expected %d\n",
301 (int)blob->length, LM_HASH_LEN));
302 goto fail;
304 pdb_set_lanman_passwd(sam, blob->data, PDB_SET);
307 n = ldb_msg_find_attr_as_uint(msg, "primaryGroupID", 0);
308 if (n == 0) {
309 DEBUG(10, ("Could not pull primaryGroupID\n"));
310 goto fail;
312 sid_compose(&group_sid, samdb_domain_sid(state->ldb), n);
313 pdb_set_group_sid(sam, &group_sid, PDB_SET);
315 status = NT_STATUS_OK;
316 fail:
317 TALLOC_FREE(frame);
318 return status;
321 static bool pdb_samba4_add_time(struct ldb_message *msg,
322 const char *attrib, time_t t)
324 uint64_t nt_time;
326 unix_to_nt_time(&nt_time, t);
328 return ldb_msg_add_fmt(msg, attrib, "%llu", (unsigned long long) nt_time);
331 static int pdb_samba4_replace_by_sam(struct pdb_samba4_state *state,
332 bool (*need_update)(const struct samu *,
333 enum pdb_elements),
334 struct ldb_dn *dn,
335 struct samu *sam)
337 int ret = LDB_SUCCESS;
338 const char *pw;
339 struct ldb_message *msg;
340 struct ldb_request *req;
341 uint32_t dsdb_flags = 0;
342 /* TODO: All fields :-) */
344 msg = ldb_msg_new(talloc_tos());
345 if (!msg) {
346 return false;
349 msg->dn = dn;
351 /* build modify request */
352 ret = ldb_build_mod_req(&req, state->ldb, talloc_tos(), msg, NULL, NULL,
353 ldb_op_default_callback,
354 NULL);
355 if (ret != LDB_SUCCESS) {
356 talloc_free(msg);
357 return ret;
360 pw = pdb_get_plaintext_passwd(sam);
361 if (need_update(sam, PDB_PLAINTEXT_PW)) {
362 if (pw == NULL) {
363 return LDB_ERR_OPERATIONS_ERROR;
366 ret |= ldb_msg_add_string(msg, "clearTextPassword", pw);
367 } else {
368 bool changed_lm_pw = false;
369 bool changed_nt_pw = false;
370 bool changed_history = false;
371 if (need_update(sam, PDB_LMPASSWD)) {
372 struct ldb_val val;
373 val.data = pdb_get_lanman_passwd(sam);
374 if (!val.data) {
375 samdb_msg_add_delete(state->ldb, msg, msg,
376 "dBCSPwd");
377 } else {
378 val.length = LM_HASH_LEN;
379 ret |= ldb_msg_add_value(msg, "dBCSPwd", &val, NULL);
381 changed_lm_pw = true;
383 if (need_update(sam, PDB_NTPASSWD)) {
384 struct ldb_val val;
385 val.data = pdb_get_nt_passwd(sam);
386 if (!val.data) {
387 samdb_msg_add_delete(state->ldb, msg, msg,
388 "unicodePwd");
389 } else {
390 val.length = NT_HASH_LEN;
391 ret |= ldb_msg_add_value(msg, "unicodePwd", &val, NULL);
393 changed_nt_pw = true;
396 /* Try to ensure we don't get out of sync */
397 if (changed_lm_pw && !changed_nt_pw) {
398 samdb_msg_add_delete(state->ldb, msg, msg,
399 "unicodePwd");
400 } else if (changed_nt_pw && !changed_lm_pw) {
401 samdb_msg_add_delete(state->ldb, msg, msg,
402 "dBCSPwd");
404 if (changed_lm_pw || changed_nt_pw) {
405 samdb_msg_add_delete(state->ldb, msg, msg,
406 "supplementalCredentials");
410 /* If we set a plaintext password, the system will
411 * force the pwdLastSet to now(), and it isn't worth
412 * working around this for the real world use cases of
413 * pdb_samba4 */
414 if (need_update(sam, PDB_PASSLASTSET)) {
415 ret |= pdb_samba4_add_time(msg, "pwdLastSet",
416 pdb_get_pass_last_set_time(sam));
419 if (need_update(sam, PDB_PWHISTORY)) {
420 uint32_t current_hist_len;
421 const uint8_t *history = pdb_get_pw_history(sam, &current_hist_len);
423 bool invalid_history = false;
424 struct samr_Password *history_hashes = talloc_array(talloc_tos(), struct samr_Password,
425 current_hist_len);
426 if (!history) {
427 invalid_history = true;
428 } else {
429 unsigned int i;
430 static const uint8_t zeros[16];
431 /* Parse the history into the correct format */
432 for (i = 0; i < current_hist_len; i++) {
433 if (memcmp(&history[i*PW_HISTORY_ENTRY_LEN], zeros, 16) != 0) {
434 /* If the history is in the old format, with a salted hash, then we can't migrate it to AD format */
435 invalid_history = true;
436 break;
438 /* Copy out the 2nd 16 bytes of the 32 byte password history, containing the NT hash */
439 memcpy(history_hashes[i].hash,
440 &history[(i*PW_HISTORY_ENTRY_LEN) + PW_HISTORY_SALT_LEN],
441 sizeof(history_hashes[i].hash));
444 if (invalid_history) {
445 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
446 "ntPwdHistory");
448 ret |= samdb_msg_add_delete(state->ldb, msg, msg,
449 "lmPwdHistory");
450 } else {
451 ret |= samdb_msg_add_hashes(state->ldb, msg, msg,
452 "ntPwdHistory",
453 history_hashes,
454 current_hist_len);
456 changed_history = true;
458 if (changed_lm_pw || changed_nt_pw || changed_history) {
459 /* These attributes can only be modified directly by using a special control */
460 dsdb_flags = DSDB_BYPASS_PASSWORD_HASH;
464 /* PDB_USERSID is only allowed on ADD, handled in caller */
465 if (need_update(sam, PDB_GROUPSID)) {
466 const struct dom_sid *sid = pdb_get_group_sid(sam);
467 uint32_t rid;
468 NTSTATUS status = dom_sid_split_rid(NULL, sid, NULL, &rid);
469 if (!NT_STATUS_IS_OK(status)) {
470 return LDB_ERR_OPERATIONS_ERROR;
472 if (!dom_sid_in_domain(samdb_domain_sid(state->ldb), sid)) {
473 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
475 ret |= samdb_msg_add_uint(state->ldb, msg, msg, "primaryGroupID", rid);
477 if (need_update(sam, PDB_FULLNAME)) {
478 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
481 if (need_update(sam, PDB_SMBHOME)) {
482 ret |= ldb_msg_add_string(msg, "homeDirectory",
483 pdb_get_homedir(sam));
486 if (need_update(sam, PDB_PROFILE)) {
487 ret |= ldb_msg_add_string(msg, "profilePath",
488 pdb_get_profile_path(sam));
491 if (need_update(sam, PDB_DRIVE)) {
492 ret |= ldb_msg_add_string(msg, "homeDrive",
493 pdb_get_dir_drive(sam));
496 if (need_update(sam, PDB_LOGONSCRIPT)) {
497 ret |= ldb_msg_add_string(msg, "scriptPath",
498 pdb_get_logon_script(sam));
501 if (need_update(sam, PDB_KICKOFFTIME)) {
502 ret |= pdb_samba4_add_time(msg, "accountExpires",
503 pdb_get_kickoff_time(sam));
506 if (need_update(sam, PDB_USERNAME)) {
507 ret |= ldb_msg_add_string(msg, "samAccountName",
508 pdb_get_username(sam));
511 if (need_update(sam, PDB_HOURSLEN) || need_update(sam, PDB_HOURS)) {
512 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
513 ret |= ldb_msg_add_value(msg, "logonHours",
514 &hours, NULL);
517 if (need_update(sam, PDB_ACCTCTRL)) {
518 ret |= samdb_msg_add_acct_flags(state->ldb, msg, msg,
519 "userAccountControl", pdb_get_acct_ctrl(sam));
522 if (need_update(sam, PDB_COMMENT)) {
523 ret |= ldb_msg_add_string(msg, "comment",
524 pdb_get_comment(sam));
527 if (need_update(sam, PDB_ACCTDESC)) {
528 ret |= ldb_msg_add_string(msg, "description",
529 pdb_get_acct_desc(sam));
532 if (need_update(sam, PDB_WORKSTATIONS)) {
533 ret |= ldb_msg_add_string(msg, "userWorkstations",
534 pdb_get_workstations(sam));
537 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
538 if (need_update(sam, PDB_MUNGEDDIAL)) {
539 ret |= ldb_msg_add_string(msg, "userParameters",
540 pdb_get_munged_dial(sam));
543 if (need_update(sam, PDB_COUNTRY_CODE)) {
544 ret |= ldb_msg_add_fmt(msg, "countryCode",
545 "%i", (int)pdb_get_country_code(sam));
548 if (need_update(sam, PDB_CODE_PAGE)) {
549 ret |= ldb_msg_add_fmt(msg, "codePage",
550 "%i", (int)pdb_get_code_page(sam));
553 /* Not yet handled here or not meaningful for modifies on a Samba4 backend:
554 PDB_LOGONTIME,
555 PDB_LOGOFFTIME,
556 PDB_BAD_PASSWORD_TIME,
557 PDB_CANCHANGETIME, - these are calculated per policy, not stored
558 PDB_MUSTCHANGETIME, - these are calculated per policy, not stored
559 PDB_DOMAIN,
560 PDB_NTUSERNAME, - this makes no sense, and never really did
561 PDB_LOGONDIVS,
562 PDB_USERSID, - Handled in pdb_samba4_add_sam_account()
563 PDB_FIELDS_PRESENT,
564 PDB_BAD_PASSWORD_COUNT,
565 PDB_LOGON_COUNT,
566 PDB_UNKNOWN6,
567 PDB_BACKEND_PRIVATE_DATA,
570 if (ret != LDB_SUCCESS) {
571 return LDB_ERR_OPERATIONS_ERROR;
574 if (msg->num_elements == 0) {
575 /* Nothing to do, just return success */
576 return LDB_SUCCESS;
579 ret = dsdb_replace(state->ldb, msg, dsdb_flags);
581 if (ret != LDB_SUCCESS) {
582 DEBUG(0,("Failed to modify account record %s to set user attributes: %s\n",
583 ldb_dn_get_linearized(msg->dn),
584 ldb_errstring(state->ldb)));
587 return ret;
590 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
591 const char *filter,
592 TALLOC_CTX *mem_ctx,
593 struct ldb_message **msg)
595 const char * attrs[] = {
596 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
597 "sAMAccountName", "displayName", "homeDirectory",
598 "homeDrive", "scriptPath", "profilePath", "description",
599 "userWorkstations", "comment", "userParameters", "objectSid",
600 "primaryGroupID", "userAccountControl", "logonHours",
601 "badPwdCount", "logonCount", "countryCode", "codePage",
602 "unicodePwd", "dBCSPwd", NULL };
604 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
605 if (rc != LDB_SUCCESS) {
606 DEBUG(10, ("ldap_search failed %s\n",
607 ldb_errstring(state->ldb)));
608 return NT_STATUS_LDAP(rc);
611 return NT_STATUS_OK;
614 static NTSTATUS pdb_samba4_getsampwfilter(struct pdb_methods *m,
615 struct pdb_samba4_state *state,
616 struct samu *sam_acct,
617 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
619 struct ldb_message *priv;
620 NTSTATUS status;
621 va_list ap;
622 char *expression = NULL;
623 TALLOC_CTX *tmp_ctx = talloc_new(state);
624 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
626 va_start(ap, exp_fmt);
627 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
628 va_end(ap);
630 if (!expression) {
631 talloc_free(tmp_ctx);
632 return NT_STATUS_NO_MEMORY;
635 status = pdb_samba4_getsamupriv(state, expression, sam_acct, &priv);
636 talloc_free(tmp_ctx);
637 if (!NT_STATUS_IS_OK(status)) {
638 DEBUG(10, ("pdb_samba4_getsamupriv failed: %s\n",
639 nt_errstr(status)));
640 return status;
643 status = pdb_samba4_init_sam_from_priv(m, sam_acct, priv);
644 if (!NT_STATUS_IS_OK(status)) {
645 DEBUG(10, ("pdb_samba4_init_sam_from_priv failed: %s\n",
646 nt_errstr(status)));
647 TALLOC_FREE(priv);
648 return status;
651 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
652 return NT_STATUS_OK;
655 static NTSTATUS pdb_samba4_getsampwnam(struct pdb_methods *m,
656 struct samu *sam_acct,
657 const char *username)
659 struct pdb_samba4_state *state = talloc_get_type_abort(
660 m->private_data, struct pdb_samba4_state);
662 return pdb_samba4_getsampwfilter(m, state, sam_acct,
663 "(&(samaccountname=%s)(objectclass=user))",
664 username);
667 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
668 struct samu *sam_acct,
669 const struct dom_sid *sid)
671 NTSTATUS status;
672 struct pdb_samba4_state *state = talloc_get_type_abort(
673 m->private_data, struct pdb_samba4_state);
674 char *sidstr;
676 sidstr = dom_sid_string(talloc_tos(), sid);
677 NT_STATUS_HAVE_NO_MEMORY(sidstr);
679 status = pdb_samba4_getsampwfilter(m, state, sam_acct,
680 "(&(objectsid=%s)(objectclass=user))",
681 sidstr);
682 talloc_free(sidstr);
683 return status;
686 static NTSTATUS pdb_samba4_create_user(struct pdb_methods *m,
687 TALLOC_CTX *mem_ctx,
688 const char *name, uint32 acct_flags,
689 uint32 *rid)
691 struct pdb_samba4_state *state = talloc_get_type_abort(
692 m->private_data, struct pdb_samba4_state);
693 struct dom_sid *sid;
694 struct ldb_dn *dn;
695 NTSTATUS status;
696 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
697 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
699 /* Internally this uses transactions to ensure all the steps
700 * happen or fail as one */
701 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, NULL,
702 &sid, &dn);
703 if (!NT_STATUS_IS_OK(status)) {
704 talloc_free(tmp_ctx);
705 return status;
707 sid_peek_rid(sid, rid);
708 talloc_free(tmp_ctx);
709 return NT_STATUS_OK;
712 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
713 TALLOC_CTX *mem_ctx,
714 struct samu *sam)
716 struct pdb_samba4_state *state = talloc_get_type_abort(
717 m->private_data, struct pdb_samba4_state);
718 struct ldb_dn *dn;
719 int rc;
720 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
721 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
723 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
724 if (!dn || !ldb_dn_validate(dn)) {
725 talloc_free(tmp_ctx);
726 return NT_STATUS_NO_MEMORY;
728 rc = ldb_delete(state->ldb, dn);
730 if (rc != LDB_SUCCESS) {
731 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
732 ldb_errstring(state->ldb)));
733 talloc_free(tmp_ctx);
734 return NT_STATUS_LDAP(rc);
736 talloc_free(tmp_ctx);
737 return NT_STATUS_OK;
740 /* This interface takes a fully populated struct samu and places it in
741 * the database. This is not implemented at this time as we need to
742 * be careful around the creation of arbitary SIDs (ie, we must ensrue
743 * they are not left in a RID pool */
744 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
745 struct samu *sampass)
747 int ret;
748 NTSTATUS status;
749 struct ldb_dn *dn;
750 struct pdb_samba4_state *state = talloc_get_type_abort(
751 m->private_data, struct pdb_samba4_state);
752 uint32_t acb_flags = pdb_get_acct_ctrl(sampass);
753 const char *username = pdb_get_username(sampass);
754 const struct dom_sid *user_sid = pdb_get_user_sid(sampass);
755 TALLOC_CTX *tframe = talloc_stackframe();
757 acb_flags &= (ACB_NORMAL|ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST);
759 ret = ldb_transaction_start(state->ldb);
760 if (ret != LDB_SUCCESS) {
761 talloc_free(tframe);
762 return NT_STATUS_LOCK_NOT_GRANTED;
765 status = dsdb_add_user(state->ldb, talloc_tos(), username,
766 acb_flags, user_sid, NULL, &dn);
767 if (!NT_STATUS_IS_OK(status)) {
768 ldb_transaction_cancel(state->ldb);
769 talloc_free(tframe);
770 return status;
773 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_set_or_changed,
774 dn, sampass);
775 if (ret != LDB_SUCCESS) {
776 ldb_transaction_cancel(state->ldb);
777 talloc_free(tframe);
778 return dsdb_ldb_err_to_ntstatus(ret);
781 ret = ldb_transaction_commit(state->ldb);
782 if (ret != LDB_SUCCESS) {
783 DEBUG(0,("Failed to commit transaction to add and modify account record %s: %s\n",
784 ldb_dn_get_linearized(dn),
785 ldb_errstring(state->ldb)));
786 talloc_free(tframe);
787 return NT_STATUS_INTERNAL_DB_CORRUPTION;
789 talloc_free(tframe);
790 return NT_STATUS_OK;
794 * Update the Samba4 LDB with the changes from a struct samu.
796 * This takes care not to update elements that have not been changed
797 * by the caller
799 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
800 struct samu *sam)
802 struct pdb_samba4_state *state = talloc_get_type_abort(
803 m->private_data, struct pdb_samba4_state);
804 struct ldb_message *msg = pdb_samba4_get_samu_private(
805 m, sam);
806 int ret;
808 ret = pdb_samba4_replace_by_sam(state, pdb_element_is_changed, msg->dn,
809 sam);
810 return dsdb_ldb_err_to_ntstatus(ret);
813 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
814 struct samu *username)
816 NTSTATUS status;
817 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
818 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
819 status = pdb_samba4_delete_user(m, tmp_ctx, username);
820 talloc_free(tmp_ctx);
821 return status;
824 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
825 struct samu *oldname,
826 const char *newname)
828 return NT_STATUS_NOT_IMPLEMENTED;
831 /* This is not implemented, as this module is exptected to be used
832 * with auth_samba4, and this is responible for login counters etc
835 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
836 struct samu *sam_acct,
837 bool success)
839 return NT_STATUS_NOT_IMPLEMENTED;
842 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
843 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
845 struct pdb_samba4_state *state = talloc_get_type_abort(
846 m->private_data, struct pdb_samba4_state);
847 const char *attrs[] = { "objectSid", "description", "samAccountName",
848 NULL };
849 struct ldb_message *msg;
850 va_list ap;
851 char *expression = NULL;
852 struct dom_sid *sid;
853 const char *str;
854 int rc;
855 uid_t uid;
856 TALLOC_CTX *tmp_ctx = talloc_stackframe();
857 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
859 va_start(ap, exp_fmt);
860 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
861 va_end(ap);
863 if (!expression) {
864 talloc_free(tmp_ctx);
865 return NT_STATUS_NO_MEMORY;
868 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
869 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
870 talloc_free(tmp_ctx);
871 return NT_STATUS_NO_SUCH_GROUP;
872 } else if (rc != LDB_SUCCESS) {
873 talloc_free(tmp_ctx);
874 DEBUG(10, ("dsdb_search_one failed %s\n",
875 ldb_errstring(state->ldb)));
876 return NT_STATUS_LDAP(rc);
879 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
880 if (!sid) {
881 talloc_free(tmp_ctx);
882 DEBUG(10, ("Could not pull SID\n"));
883 return NT_STATUS_INTERNAL_DB_CORRUPTION;
886 map->sid = *sid;
888 if (!pdb_samba4_sid_to_id(m, sid, &uid, &map->gid, &map->sid_name_use)) {
889 talloc_free(tmp_ctx);
890 return NT_STATUS_NO_SUCH_GROUP;
892 if (map->sid_name_use == SID_NAME_USER) {
893 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
894 return NT_STATUS_INTERNAL_DB_CORRUPTION;
897 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
898 NULL);
899 if (str == NULL) {
900 talloc_free(tmp_ctx);
901 return NT_STATUS_INTERNAL_DB_CORRUPTION;
903 map->nt_name = talloc_strdup(map, str);
904 if (!map->nt_name) {
905 talloc_free(tmp_ctx);
906 return NT_STATUS_NO_MEMORY;
909 str = ldb_msg_find_attr_as_string(msg, "description",
910 NULL);
911 if (str != NULL) {
912 map->comment = talloc_strdup(map, str);
913 } else {
914 map->comment = talloc_strdup(map, "");
916 if (!map->comment) {
917 talloc_free(tmp_ctx);
918 return NT_STATUS_NO_MEMORY;
921 talloc_free(tmp_ctx);
922 return NT_STATUS_OK;
925 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
926 struct dom_sid sid)
928 char *filter;
929 NTSTATUS status;
931 filter = talloc_asprintf(talloc_tos(),
932 "(&(objectsid=%s)(objectclass=group))",
933 sid_string_talloc(talloc_tos(), &sid));
934 if (filter == NULL) {
935 return NT_STATUS_NO_MEMORY;
938 status = pdb_samba4_getgrfilter(m, map, filter);
939 TALLOC_FREE(filter);
940 return status;
943 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
944 gid_t gid)
946 struct pdb_samba4_state *state = talloc_get_type_abort(
947 m->private_data, struct pdb_samba4_state);
948 NTSTATUS status;
949 struct id_map id_map;
950 struct id_map *id_maps[2];
951 TALLOC_CTX *tmp_ctx = talloc_stackframe();
952 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
954 id_map.xid.id = gid;
955 id_map.xid.type = ID_TYPE_GID;
956 id_maps[0] = &id_map;
957 id_maps[1] = NULL;
959 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
960 if (!NT_STATUS_IS_OK(status)) {
961 return status;
963 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
964 talloc_free(tmp_ctx);
965 return status;
968 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
969 const char *name)
971 char *filter;
972 NTSTATUS status;
974 filter = talloc_asprintf(talloc_tos(),
975 "(&(samaccountname=%s)(objectclass=group))",
976 name);
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_create_dom_group(struct pdb_methods *m,
987 TALLOC_CTX *mem_ctx, const char *name,
988 uint32 *rid)
990 struct pdb_samba4_state *state = talloc_get_type_abort(
991 m->private_data, struct pdb_samba4_state);
992 NTSTATUS status;
993 struct dom_sid *sid;
994 struct ldb_dn *dn;
995 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
996 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
998 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
999 if (!NT_STATUS_IS_OK(status)) {
1000 talloc_free(tmp_ctx);
1001 return status;
1004 sid_peek_rid(sid, rid);
1005 talloc_free(tmp_ctx);
1006 return NT_STATUS_OK;
1009 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1010 TALLOC_CTX *mem_ctx, uint32 rid)
1012 const char *attrs[] = { NULL };
1013 struct pdb_samba4_state *state = talloc_get_type_abort(
1014 m->private_data, struct pdb_samba4_state);
1015 struct dom_sid sid;
1016 struct ldb_message *msg;
1017 struct ldb_dn *dn;
1018 int rc;
1019 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1020 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1022 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1024 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1025 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1026 return NT_STATUS_INTERNAL_ERROR;
1029 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1030 if (!dn || !ldb_dn_validate(dn)) {
1031 talloc_free(tmp_ctx);
1032 ldb_transaction_cancel(state->ldb);
1033 return NT_STATUS_NO_MEMORY;
1035 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1036 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1037 talloc_free(tmp_ctx);
1038 ldb_transaction_cancel(state->ldb);
1039 return NT_STATUS_NO_SUCH_GROUP;
1041 rc = ldb_delete(state->ldb, dn);
1042 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1043 talloc_free(tmp_ctx);
1044 ldb_transaction_cancel(state->ldb);
1045 return NT_STATUS_NO_SUCH_GROUP;
1046 } else if (rc != LDB_SUCCESS) {
1047 DEBUG(10, ("ldb_delete failed %s\n",
1048 ldb_errstring(state->ldb)));
1049 ldb_transaction_cancel(state->ldb);
1050 return NT_STATUS_LDAP(rc);
1053 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1054 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1055 return NT_STATUS_INTERNAL_ERROR;
1057 return NT_STATUS_OK;
1060 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1061 GROUP_MAP *map)
1063 return NT_STATUS_NOT_IMPLEMENTED;
1066 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1067 GROUP_MAP *map)
1069 return NT_STATUS_NOT_IMPLEMENTED;
1072 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1073 struct dom_sid sid)
1075 return NT_STATUS_NOT_IMPLEMENTED;
1078 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1079 const struct dom_sid *sid,
1080 enum lsa_SidType sid_name_use,
1081 GROUP_MAP ***pp_rmap,
1082 size_t *p_num_entries,
1083 bool unix_only)
1085 return NT_STATUS_NOT_IMPLEMENTED;
1088 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1089 TALLOC_CTX *mem_ctx,
1090 const struct dom_sid *group,
1091 uint32_t **pmembers,
1092 size_t *pnum_members)
1094 unsigned int i, num_sids, num_members;
1095 struct pdb_samba4_state *state = talloc_get_type_abort(
1096 m->private_data, struct pdb_samba4_state);
1097 struct dom_sid *members_as_sids;
1098 struct dom_sid *dom_sid;
1099 uint32_t *members;
1100 struct ldb_dn *dn;
1101 NTSTATUS status;
1103 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1104 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1106 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1107 if (!dn || !ldb_dn_validate(dn)) {
1108 return NT_STATUS_NO_MEMORY;
1111 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1112 if (!NT_STATUS_IS_OK(status)) {
1113 talloc_free(tmp_ctx);
1114 return status;
1116 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1117 if (!NT_STATUS_IS_OK(status)) {
1118 talloc_free(tmp_ctx);
1119 return status;
1122 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1123 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1124 num_members = 0;
1126 for (i = 0; i < num_sids; i++) {
1127 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1128 continue;
1130 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1131 NULL, &members[num_members]);
1132 if (!NT_STATUS_IS_OK(status)) {
1133 talloc_free(tmp_ctx);
1134 return status;
1136 num_members++;
1138 *pnum_members = num_members;
1139 return NT_STATUS_OK;
1142 /* Just convert the primary group SID into a group */
1143 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1144 TALLOC_CTX *mem_ctx,
1145 struct samu *user,
1146 struct dom_sid **pp_sids,
1147 gid_t **pp_gids,
1148 uint32_t *p_num_groups)
1150 NTSTATUS status;
1151 size_t num_groups = 0;
1152 struct dom_sid *group_sids;
1153 gid_t *gids;
1154 TALLOC_CTX *tmp_ctx;
1156 tmp_ctx = talloc_new(mem_ctx);
1157 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1159 if (user->group_sid) {
1160 struct id_map *id_maps[2];
1161 struct id_map id_map;
1163 num_groups = 1;
1165 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1166 if (group_sids == NULL) {
1167 talloc_free(tmp_ctx);
1168 return NT_STATUS_NO_MEMORY;
1170 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1171 if (gids == NULL) {
1172 talloc_free(tmp_ctx);
1173 return NT_STATUS_NO_MEMORY;
1176 group_sids[0] = *user->group_sid;
1178 ZERO_STRUCT(id_map);
1179 id_map.sid = &group_sids[0];
1180 id_maps[0] = &id_map;
1181 id_maps[1] = NULL;
1183 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1184 if (!NT_STATUS_IS_OK(status)) {
1185 talloc_free(tmp_ctx);
1186 return status;
1188 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1189 gids[0] = id_map.xid.id;
1190 } else {
1191 DEBUG(1, (__location__
1192 "Group %s, of which %s is a member, could not be converted to a GID\n",
1193 dom_sid_string(tmp_ctx, &group_sids[0]),
1194 dom_sid_string(tmp_ctx, &user->user_sid)));
1195 talloc_free(tmp_ctx);
1196 /* We must error out, otherwise a user might
1197 * avoid a DENY acl based on a group they
1198 * missed out on */
1199 return NT_STATUS_NO_SUCH_GROUP;
1203 *pp_sids = talloc_steal(mem_ctx, group_sids);
1204 *pp_gids = talloc_steal(mem_ctx, gids);
1205 *p_num_groups = num_groups;
1206 talloc_free(tmp_ctx);
1207 return NT_STATUS_OK;
1210 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1211 TALLOC_CTX *mem_ctx,
1212 struct samu *user,
1213 struct dom_sid **pp_sids,
1214 gid_t **pp_gids,
1215 uint32_t *p_num_groups)
1217 struct pdb_samba4_state *state = talloc_get_type_abort(
1218 m->private_data, struct pdb_samba4_state);
1219 struct ldb_message *msg = pdb_samba4_get_samu_private(
1220 m, user);
1221 const char *attrs[] = { "tokenGroups", NULL};
1222 struct ldb_message *tokengroups_msg;
1223 struct ldb_message_element *tokengroups;
1224 int i, rc;
1225 NTSTATUS status;
1226 unsigned int count = 0;
1227 size_t num_groups;
1228 struct dom_sid *group_sids;
1229 gid_t *gids;
1230 TALLOC_CTX *tmp_ctx;
1232 if (msg == NULL) {
1233 /* Fake up some things here */
1234 return fake_enum_group_memberships(state,
1235 mem_ctx,
1236 user, pp_sids,
1237 pp_gids, p_num_groups);
1240 tmp_ctx = talloc_new(mem_ctx);
1241 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1243 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1245 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1246 talloc_free(tmp_ctx);
1247 return NT_STATUS_NO_SUCH_USER;
1248 } else if (rc != LDB_SUCCESS) {
1249 DEBUG(10, ("dsdb_search_one failed %s\n",
1250 ldb_errstring(state->ldb)));
1251 talloc_free(tmp_ctx);
1252 return NT_STATUS_LDAP(rc);
1255 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1257 if (tokengroups) {
1258 count = tokengroups->num_values;
1261 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1262 if (group_sids == NULL) {
1263 talloc_free(tmp_ctx);
1264 return NT_STATUS_NO_MEMORY;
1266 gids = talloc_array(tmp_ctx, gid_t, count);
1267 if (gids == NULL) {
1268 talloc_free(tmp_ctx);
1269 return NT_STATUS_NO_MEMORY;
1271 num_groups = 0;
1273 for (i=0; i<count; i++) {
1274 struct id_map *id_maps[2];
1275 struct id_map id_map;
1276 struct ldb_val *v = &tokengroups->values[i];
1277 enum ndr_err_code ndr_err
1278 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1279 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1280 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1281 talloc_free(tmp_ctx);
1282 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1285 ZERO_STRUCT(id_map);
1286 id_map.sid = &group_sids[num_groups];
1287 id_maps[0] = &id_map;
1288 id_maps[1] = NULL;
1290 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1291 if (!NT_STATUS_IS_OK(status)) {
1292 talloc_free(tmp_ctx);
1293 return status;
1295 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1296 gids[num_groups] = id_map.xid.id;
1297 } else {
1298 DEBUG(1, (__location__
1299 "Group %s, of which %s is a member, could not be converted to a GID\n",
1300 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1301 ldb_dn_get_linearized(msg->dn)));
1302 talloc_free(tmp_ctx);
1303 /* We must error out, otherwise a user might
1304 * avoid a DENY acl based on a group they
1305 * missed out on */
1306 return NT_STATUS_NO_SUCH_GROUP;
1309 num_groups += 1;
1310 if (num_groups == count) {
1311 break;
1315 *pp_sids = talloc_steal(mem_ctx, group_sids);
1316 *pp_gids = talloc_steal(mem_ctx, gids);
1317 *p_num_groups = num_groups;
1318 talloc_free(tmp_ctx);
1319 return NT_STATUS_OK;
1322 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1323 TALLOC_CTX *mem_ctx,
1324 struct samu *user)
1326 return NT_STATUS_NOT_IMPLEMENTED;
1329 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1330 TALLOC_CTX *mem_ctx,
1331 const struct dom_sid *groupsid,
1332 const struct dom_sid *membersid,
1333 int mod_op)
1335 struct pdb_samba4_state *state = talloc_get_type_abort(
1336 m->private_data, struct pdb_samba4_state);
1337 struct ldb_message *msg;
1338 int ret;
1339 struct ldb_message_element *el;
1340 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1341 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1342 msg = ldb_msg_new(tmp_ctx);
1343 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1345 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1346 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1347 talloc_free(tmp_ctx);
1348 return NT_STATUS_NO_MEMORY;
1350 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1351 if (ret != LDB_SUCCESS) {
1352 talloc_free(tmp_ctx);
1353 return NT_STATUS_NO_MEMORY;
1355 el = ldb_msg_find_element(msg, "member");
1356 el->flags = mod_op;
1358 /* No need for transactions here, the ldb auto-transaction
1359 * code will handle things for the single operation */
1360 ret = ldb_modify(state->ldb, msg);
1361 talloc_free(tmp_ctx);
1362 if (ret != LDB_SUCCESS) {
1363 DEBUG(10, ("ldb_modify failed: %s\n",
1364 ldb_errstring(state->ldb)));
1365 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1366 return NT_STATUS_MEMBER_IN_GROUP;
1368 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1369 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1371 return NT_STATUS_LDAP(ret);
1374 return NT_STATUS_OK;
1377 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1378 TALLOC_CTX *mem_ctx,
1379 uint32 grouprid, uint32 memberrid,
1380 int mod_op)
1382 struct pdb_samba4_state *state = talloc_get_type_abort(
1383 m->private_data, struct pdb_samba4_state);
1384 const struct dom_sid *dom_sid, *groupsid, *membersid;
1385 NTSTATUS status;
1386 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1387 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1389 dom_sid = samdb_domain_sid(state->ldb);
1391 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1392 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1393 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1394 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1395 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1396 talloc_free(tmp_ctx);
1397 return status;
1400 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1401 TALLOC_CTX *mem_ctx,
1402 uint32 group_rid, uint32 member_rid)
1404 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1405 LDB_FLAG_MOD_ADD);
1408 static NTSTATUS pdb_samba4_del_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_DELETE);
1416 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1417 const char *name, uint32 *rid)
1419 TALLOC_CTX *frame = talloc_stackframe();
1420 struct pdb_samba4_state *state = talloc_get_type_abort(
1421 m->private_data, struct pdb_samba4_state);
1422 struct dom_sid *sid;
1424 struct ldb_dn *dn;
1425 NTSTATUS status;
1427 /* Internally this uses transactions to ensure all the steps
1428 * happen or fail as one */
1429 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1430 if (!NT_STATUS_IS_OK(status)) {
1431 TALLOC_FREE(frame);
1434 sid_peek_rid(sid, rid);
1435 TALLOC_FREE(frame);
1436 return NT_STATUS_OK;
1439 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1440 const struct dom_sid *sid)
1442 const char *attrs[] = { NULL };
1443 struct pdb_samba4_state *state = talloc_get_type_abort(
1444 m->private_data, struct pdb_samba4_state);
1445 struct ldb_message *msg;
1446 struct ldb_dn *dn;
1447 int rc;
1448 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1449 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1451 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1452 if (!dn || !ldb_dn_validate(dn)) {
1453 talloc_free(tmp_ctx);
1454 return NT_STATUS_NO_MEMORY;
1457 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1458 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1459 return NT_STATUS_INTERNAL_ERROR;
1462 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1463 "(|(grouptype=%d)(grouptype=%d)))",
1464 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1465 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1466 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1467 talloc_free(tmp_ctx);
1468 ldb_transaction_cancel(state->ldb);
1469 return NT_STATUS_NO_SUCH_ALIAS;
1471 rc = ldb_delete(state->ldb, dn);
1472 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1473 talloc_free(tmp_ctx);
1474 ldb_transaction_cancel(state->ldb);
1475 return NT_STATUS_NO_SUCH_ALIAS;
1476 } else if (rc != LDB_SUCCESS) {
1477 DEBUG(10, ("ldb_delete failed %s\n",
1478 ldb_errstring(state->ldb)));
1479 ldb_transaction_cancel(state->ldb);
1480 return NT_STATUS_LDAP(rc);
1483 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1484 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1485 ldb_errstring(state->ldb)));
1486 return NT_STATUS_INTERNAL_ERROR;
1489 return NT_STATUS_OK;
1492 #if 0
1493 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1494 const struct dom_sid *sid,
1495 struct acct_info *info)
1497 struct pdb_samba4_state *state = talloc_get_type_abort(
1498 m->private_data, struct pdb_samba4_state);
1499 struct tldap_context *ld;
1500 const char *attrs[3] = { "objectSid", "description",
1501 "samAccountName" };
1502 struct ldb_message **msg;
1503 char *sidstr, *dn;
1504 int rc;
1505 struct tldap_mod *mods;
1506 int num_mods;
1507 bool ok;
1509 ld = pdb_samba4_ld(state);
1510 if (ld == NULL) {
1511 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1514 sidstr = sid_binstring(talloc_tos(), sid);
1515 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1517 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1518 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1519 &msg, "(&(objectSid=%s)(objectclass=group)"
1520 "(|(grouptype=%d)(grouptype=%d)))",
1521 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1522 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1523 TALLOC_FREE(sidstr)
1524 if (rc != LDB_SUCCESS) {
1525 DEBUG(10, ("ldap_search failed %s\n",
1526 ldb_errstring(state->ldb)));
1527 return NT_STATUS_LDAP(rc);
1529 switch talloc_array_length(msg) {
1530 case 0:
1531 return NT_STATUS_NO_SUCH_ALIAS;
1532 case 1:
1533 break;
1534 default:
1535 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1538 if (!tldap_entry_dn(msg[0], &dn)) {
1539 TALLOC_FREE(msg);
1540 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1543 mods = NULL;
1544 num_mods = 0;
1545 ok = true;
1547 ok &= tldap_make_mod_fmt(
1548 msg[0], msg, &num_mods, &mods, "description",
1549 "%s", info->acct_desc);
1550 ok &= tldap_make_mod_fmt(
1551 msg[0], msg, &num_mods, &mods, "samAccountName",
1552 "%s", info->acct_name);
1553 if (!ok) {
1554 TALLOC_FREE(msg);
1555 return NT_STATUS_NO_MEMORY;
1557 if (num_mods == 0) {
1558 /* no change */
1559 TALLOC_FREE(msg);
1560 return NT_STATUS_OK;
1563 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1564 TALLOC_FREE(msg);
1565 if (rc != LDB_SUCCESS) {
1566 DEBUG(10, ("ldap_modify failed: %s\n",
1567 ldb_errstring(state->ldb)));
1568 return NT_STATUS_LDAP(rc);
1570 return NT_STATUS_OK;
1572 #endif
1573 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1574 const struct dom_sid *alias,
1575 const struct dom_sid *member)
1577 NTSTATUS status;
1578 TALLOC_CTX *frame = talloc_stackframe();
1579 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1580 talloc_free(frame);
1581 return status;
1584 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1585 const struct dom_sid *alias,
1586 const struct dom_sid *member)
1588 NTSTATUS status;
1589 TALLOC_CTX *frame = talloc_stackframe();
1590 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1591 talloc_free(frame);
1592 return status;
1595 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1596 const struct dom_sid *alias,
1597 TALLOC_CTX *mem_ctx,
1598 struct dom_sid **pmembers,
1599 size_t *pnum_members)
1601 struct pdb_samba4_state *state = talloc_get_type_abort(
1602 m->private_data, struct pdb_samba4_state);
1603 struct ldb_dn *dn;
1604 unsigned int num_members;
1605 NTSTATUS status;
1606 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1607 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1609 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1610 if (!dn || !ldb_dn_validate(dn)) {
1611 return NT_STATUS_NO_MEMORY;
1614 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1615 *pnum_members = num_members;
1616 if (NT_STATUS_IS_OK(status)) {
1617 talloc_steal(mem_ctx, pmembers);
1619 talloc_free(tmp_ctx);
1620 return status;
1623 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1624 TALLOC_CTX *mem_ctx,
1625 const struct dom_sid *domain_sid,
1626 const struct dom_sid *members,
1627 size_t num_members,
1628 uint32_t **palias_rids,
1629 size_t *pnum_alias_rids)
1631 struct pdb_samba4_state *state = talloc_get_type_abort(
1632 m->private_data, struct pdb_samba4_state);
1633 uint32_t *alias_rids = NULL;
1634 size_t num_alias_rids = 0;
1635 int i;
1636 struct dom_sid *groupSIDs = NULL;
1637 unsigned int num_groupSIDs = 0;
1638 char *filter;
1639 NTSTATUS status;
1640 const char *sid_string;
1641 const char *sid_dn;
1642 DATA_BLOB sid_blob;
1644 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1645 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1647 * TODO: Get the filter right so that we only get the aliases from
1648 * either the SAM or BUILTIN
1651 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1652 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1653 if (filter == NULL) {
1654 return NT_STATUS_NO_MEMORY;
1657 for (i = 0; i < num_members; i++) {
1658 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1659 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1661 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1662 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1664 sid_blob = data_blob_string_const(sid_dn);
1666 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1667 tmp_ctx, &groupSIDs, &num_groupSIDs);
1668 if (!NT_STATUS_IS_OK(status)) {
1669 talloc_free(tmp_ctx);
1670 return status;
1674 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1675 if (alias_rids == NULL) {
1676 talloc_free(tmp_ctx);
1677 return NT_STATUS_NO_MEMORY;
1680 for (i=0; i<num_groupSIDs; i++) {
1681 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1682 &alias_rids[num_alias_rids])) {
1683 num_alias_rids++;;
1687 *palias_rids = alias_rids;
1688 *pnum_alias_rids = num_alias_rids;
1689 return NT_STATUS_OK;
1692 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1693 const struct dom_sid *domain_sid,
1694 int num_rids,
1695 uint32 *rids,
1696 const char **names,
1697 enum lsa_SidType *lsa_attrs)
1699 struct pdb_samba4_state *state = talloc_get_type_abort(
1700 m->private_data, struct pdb_samba4_state);
1701 NTSTATUS status;
1703 TALLOC_CTX *tmp_ctx;
1705 if (num_rids == 0) {
1706 return NT_STATUS_NONE_MAPPED;
1709 tmp_ctx = talloc_stackframe();
1710 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1712 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1713 talloc_free(tmp_ctx);
1714 return status;
1717 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1718 const struct dom_sid *domain_sid,
1719 int num_names,
1720 const char **pp_names,
1721 uint32 *rids,
1722 enum lsa_SidType *attrs)
1724 return NT_STATUS_NOT_IMPLEMENTED;
1727 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1728 enum pdb_policy_type type,
1729 uint32_t *value)
1731 return account_policy_get(type, value)
1732 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1735 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1736 enum pdb_policy_type type,
1737 uint32_t value)
1739 return account_policy_set(type, value)
1740 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1743 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1744 time_t *seq_num_out)
1746 struct pdb_samba4_state *state = talloc_get_type_abort(
1747 m->private_data, struct pdb_samba4_state);
1748 uint64_t seq_num;
1749 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1750 if (ret == LDB_SUCCESS) {
1751 *seq_num_out = seq_num;
1752 return NT_STATUS_OK;
1753 } else {
1754 return NT_STATUS_UNSUCCESSFUL;
1758 struct pdb_samba4_search_state {
1759 uint32_t acct_flags;
1760 struct samr_displayentry *entries;
1761 uint32_t num_entries;
1762 ssize_t array_size;
1763 uint32_t current;
1766 static bool pdb_samba4_next_entry(struct pdb_search *search,
1767 struct samr_displayentry *entry)
1769 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1770 search->private_data, struct pdb_samba4_search_state);
1772 if (state->current == state->num_entries) {
1773 return false;
1776 entry->idx = state->entries[state->current].idx;
1777 entry->rid = state->entries[state->current].rid;
1778 entry->acct_flags = state->entries[state->current].acct_flags;
1780 entry->account_name = talloc_strdup(
1781 search, state->entries[state->current].account_name);
1782 entry->fullname = talloc_strdup(
1783 search, state->entries[state->current].fullname);
1784 entry->description = talloc_strdup(
1785 search, state->entries[state->current].description);
1787 state->current += 1;
1788 return true;
1791 static void pdb_samba4_search_end(struct pdb_search *search)
1793 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1794 search->private_data, struct pdb_samba4_search_state);
1795 talloc_free(state);
1798 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1799 struct pdb_search *search,
1800 struct pdb_samba4_search_state **pstate,
1801 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1803 struct pdb_samba4_state *state = talloc_get_type_abort(
1804 m->private_data, struct pdb_samba4_state);
1805 struct pdb_samba4_search_state *sstate;
1806 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1807 "userAccountControl", "description", NULL };
1808 struct ldb_result *res;
1809 int i, rc, num_users;
1811 va_list ap;
1812 char *expression = NULL;
1814 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1815 if (!tmp_ctx) {
1816 return false;
1819 va_start(ap, exp_fmt);
1820 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1821 va_end(ap);
1823 if (!expression) {
1824 talloc_free(tmp_ctx);
1825 return LDB_ERR_OPERATIONS_ERROR;
1828 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1829 if (sstate == NULL) {
1830 talloc_free(tmp_ctx);
1831 return false;
1834 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1835 if (rc != LDB_SUCCESS) {
1836 talloc_free(tmp_ctx);
1837 DEBUG(10, ("dsdb_search failed: %s\n",
1838 ldb_errstring(state->ldb)));
1839 return false;
1842 num_users = res->count;
1844 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1845 num_users);
1846 if (sstate->entries == NULL) {
1847 talloc_free(tmp_ctx);
1848 DEBUG(10, ("talloc failed\n"));
1849 return false;
1852 sstate->num_entries = 0;
1854 for (i=0; i<num_users; i++) {
1855 struct samr_displayentry *e;
1856 struct dom_sid *sid;
1858 e = &sstate->entries[sstate->num_entries];
1860 e->idx = sstate->num_entries;
1861 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1862 if (!sid) {
1863 talloc_free(tmp_ctx);
1864 DEBUG(10, ("Could not pull SID\n"));
1865 return false;
1867 sid_peek_rid(sid, &e->rid);
1869 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1870 res->msgs[i],
1871 ldb_get_default_basedn(state->ldb));
1872 e->account_name = ldb_msg_find_attr_as_string(
1873 res->msgs[i], "samAccountName", NULL);
1874 if (e->account_name == NULL) {
1875 talloc_free(tmp_ctx);
1876 return false;
1878 e->fullname = ldb_msg_find_attr_as_string(
1879 res->msgs[i], "displayName", "");
1880 e->description = ldb_msg_find_attr_as_string(
1881 res->msgs[i], "description", "");
1883 sstate->num_entries += 1;
1884 if (sstate->num_entries >= num_users) {
1885 break;
1888 talloc_steal(sstate->entries, res->msgs);
1889 search->private_data = talloc_steal(search, sstate);
1890 search->next_entry = pdb_samba4_next_entry;
1891 search->search_end = pdb_samba4_search_end;
1892 *pstate = sstate;
1893 talloc_free(tmp_ctx);
1894 return true;
1897 static bool pdb_samba4_search_users(struct pdb_methods *m,
1898 struct pdb_search *search,
1899 uint32 acct_flags)
1901 struct pdb_samba4_search_state *sstate;
1902 bool ret;
1904 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1905 if (!ret) {
1906 return false;
1908 sstate->acct_flags = acct_flags;
1909 return true;
1912 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1913 struct pdb_search *search)
1915 struct pdb_samba4_search_state *sstate;
1916 bool ret;
1918 ret = pdb_samba4_search_filter(m, search, &sstate,
1919 "(&(grouptype=%d)(objectclass=group))",
1920 GTYPE_SECURITY_GLOBAL_GROUP);
1921 if (!ret) {
1922 return false;
1924 sstate->acct_flags = 0;
1925 return true;
1928 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1929 struct pdb_search *search,
1930 const struct dom_sid *sid)
1932 struct pdb_samba4_search_state *sstate;
1933 bool ret;
1935 ret = pdb_samba4_search_filter(m, search, &sstate,
1936 "(&(grouptype=%d)(objectclass=group))",
1937 sid_check_is_builtin(sid)
1938 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1939 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1940 if (!ret) {
1941 return false;
1943 sstate->acct_flags = 0;
1944 return true;
1947 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1948 struct dom_sid *sid)
1950 struct pdb_samba4_state *state = talloc_get_type_abort(
1951 m->private_data, struct pdb_samba4_state);
1952 NTSTATUS status;
1953 struct id_map id_map;
1954 struct id_map *id_maps[2];
1955 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1956 if (!tmp_ctx) {
1957 return false;
1960 id_map.xid.id = uid;
1961 id_map.xid.type = ID_TYPE_UID;
1962 id_maps[0] = &id_map;
1963 id_maps[1] = NULL;
1965 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1966 if (!NT_STATUS_IS_OK(status)) {
1967 talloc_free(tmp_ctx);
1968 return false;
1970 *sid = *id_map.sid;
1971 talloc_free(tmp_ctx);
1972 return true;
1975 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1976 struct dom_sid *sid)
1978 struct pdb_samba4_state *state = talloc_get_type_abort(
1979 m->private_data, struct pdb_samba4_state);
1980 NTSTATUS status;
1981 struct id_map id_map;
1982 struct id_map *id_maps[2];
1983 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1984 if (!tmp_ctx) {
1985 return false;
1988 id_map.xid.id = gid;
1989 id_map.xid.type = ID_TYPE_GID;
1990 id_maps[0] = &id_map;
1991 id_maps[1] = NULL;
1993 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1994 if (!NT_STATUS_IS_OK(status)) {
1995 return false;
1997 *sid = *id_map.sid;
1998 talloc_free(tmp_ctx);
1999 return true;
2002 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2003 uid_t *uid, gid_t *gid, enum lsa_SidType *type)
2005 struct pdb_samba4_state *state = talloc_get_type_abort(
2006 m->private_data, struct pdb_samba4_state);
2007 struct id_map id_map;
2008 struct id_map *id_maps[2];
2009 const char *attrs[] = { "objectClass", "groupType", NULL };
2010 struct ldb_message *msg;
2011 struct ldb_dn *dn;
2012 NTSTATUS status;
2013 int rc;
2014 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2015 if (!tmp_ctx) {
2016 return false;
2019 ZERO_STRUCT(id_map);
2021 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2022 if (!dn || !ldb_dn_validate(dn)) {
2023 talloc_free(tmp_ctx);
2024 return false;
2026 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2027 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2028 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)));
2029 talloc_free(tmp_ctx);
2030 return false;
2032 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2033 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
2034 switch (grouptype) {
2035 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
2036 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
2037 *type = SID_NAME_ALIAS;
2038 break;
2039 case GTYPE_SECURITY_GLOBAL_GROUP:
2040 *type = SID_NAME_DOM_GRP;
2041 break;
2042 default:
2043 talloc_free(tmp_ctx);
2044 DEBUG(10, ("Could not pull groupType\n"));
2045 return false;
2048 *type = SID_NAME_DOM_GRP;
2050 ZERO_STRUCT(id_map);
2051 id_map.sid = sid;
2052 id_maps[0] = &id_map;
2053 id_maps[1] = NULL;
2055 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2056 talloc_free(tmp_ctx);
2057 if (!NT_STATUS_IS_OK(status)) {
2058 return false;
2060 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
2061 *gid = id_map.xid.id;
2062 return true;
2064 return false;
2065 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2066 *type = SID_NAME_USER;
2067 ZERO_STRUCT(id_map);
2068 id_map.sid = sid;
2069 id_maps[0] = &id_map;
2070 id_maps[1] = NULL;
2072 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2073 talloc_free(tmp_ctx);
2074 if (!NT_STATUS_IS_OK(status)) {
2075 return false;
2077 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2078 *uid = id_map.xid.id;
2079 return true;
2081 return false;
2083 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)));
2084 talloc_free(tmp_ctx);
2085 return false;
2088 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2090 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2093 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2095 return false;
2098 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2099 const char *domain, char** pwd,
2100 struct dom_sid *sid,
2101 time_t *pass_last_set_time)
2103 return false;
2106 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2107 const char* domain, const char* pwd,
2108 const struct dom_sid *sid)
2110 return false;
2113 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2114 const char *domain)
2116 return false;
2119 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2120 TALLOC_CTX *mem_ctx,
2121 uint32 *num_domains,
2122 struct trustdom_info ***domains)
2124 *num_domains = 0;
2125 *domains = NULL;
2126 return NT_STATUS_OK;
2129 static void pdb_samba4_init_methods(struct pdb_methods *m)
2131 m->name = "samba4";
2132 m->get_domain_info = pdb_samba4_get_domain_info;
2133 m->getsampwnam = pdb_samba4_getsampwnam;
2134 m->getsampwsid = pdb_samba4_getsampwsid;
2135 m->create_user = pdb_samba4_create_user;
2136 m->delete_user = pdb_samba4_delete_user;
2137 m->add_sam_account = pdb_samba4_add_sam_account;
2138 m->update_sam_account = pdb_samba4_update_sam_account;
2139 m->delete_sam_account = pdb_samba4_delete_sam_account;
2140 m->rename_sam_account = pdb_samba4_rename_sam_account;
2141 m->update_login_attempts = pdb_samba4_update_login_attempts;
2142 m->getgrsid = pdb_samba4_getgrsid;
2143 m->getgrgid = pdb_samba4_getgrgid;
2144 m->getgrnam = pdb_samba4_getgrnam;
2145 m->create_dom_group = pdb_samba4_create_dom_group;
2146 m->delete_dom_group = pdb_samba4_delete_dom_group;
2147 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2148 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2149 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2150 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2151 m->enum_group_members = pdb_samba4_enum_group_members;
2152 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2153 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2154 m->add_groupmem = pdb_samba4_add_groupmem;
2155 m->del_groupmem = pdb_samba4_del_groupmem;
2156 m->create_alias = pdb_samba4_create_alias;
2157 m->delete_alias = pdb_samba4_delete_alias;
2158 m->get_aliasinfo = pdb_default_get_aliasinfo;
2159 m->add_aliasmem = pdb_samba4_add_aliasmem;
2160 m->del_aliasmem = pdb_samba4_del_aliasmem;
2161 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2162 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2163 m->lookup_rids = pdb_samba4_lookup_rids;
2164 m->lookup_names = pdb_samba4_lookup_names;
2165 m->get_account_policy = pdb_samba4_get_account_policy;
2166 m->set_account_policy = pdb_samba4_set_account_policy;
2167 m->get_seq_num = pdb_samba4_get_seq_num;
2168 m->search_users = pdb_samba4_search_users;
2169 m->search_groups = pdb_samba4_search_groups;
2170 m->search_aliases = pdb_samba4_search_aliases;
2171 m->uid_to_sid = pdb_samba4_uid_to_sid;
2172 m->gid_to_sid = pdb_samba4_gid_to_sid;
2173 m->sid_to_id = pdb_samba4_sid_to_id;
2174 m->capabilities = pdb_samba4_capabilities;
2175 m->new_rid = pdb_samba4_new_rid;
2176 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2177 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2178 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2179 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2182 static void free_private_data(void **vp)
2184 struct pdb_samba4_state *state = talloc_get_type_abort(
2185 *vp, struct pdb_samba4_state);
2186 talloc_unlink(state, state->ldb);
2187 return;
2190 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2191 const char *location)
2193 struct pdb_methods *m;
2194 struct pdb_samba4_state *state;
2195 NTSTATUS status;
2197 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2198 return status;
2201 state = talloc_zero(m, struct pdb_samba4_state);
2202 if (state == NULL) {
2203 goto nomem;
2205 m->private_data = state;
2206 m->free_private_data = free_private_data;
2207 pdb_samba4_init_methods(m);
2209 state->ev = s4_event_context_init(state);
2210 if (!state->ev) {
2211 DEBUG(0, ("s4_event_context_init failed\n"));
2212 goto nomem;
2215 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2216 if (state->lp_ctx == NULL) {
2217 DEBUG(0, ("loadparm_init_s3 failed\n"));
2218 goto nomem;
2221 if (location) {
2222 state->ldb = samdb_connect_url(state,
2223 state->ev,
2224 state->lp_ctx,
2225 system_session(state->lp_ctx),
2226 0, location);
2227 } else {
2228 state->ldb = samdb_connect(state,
2229 state->ev,
2230 state->lp_ctx,
2231 system_session(state->lp_ctx), 0);
2234 if (!state->ldb) {
2235 DEBUG(0, ("samdb_connect failed\n"));
2236 status = NT_STATUS_INTERNAL_ERROR;
2237 goto fail;
2240 state->idmap_ctx = idmap_init(state, state->ev,
2241 state->lp_ctx);
2242 if (!state->idmap_ctx) {
2243 DEBUG(0, ("idmap failed\n"));
2244 status = NT_STATUS_INTERNAL_ERROR;
2245 goto fail;
2248 *pdb_method = m;
2249 return NT_STATUS_OK;
2250 nomem:
2251 status = NT_STATUS_NO_MEMORY;
2252 fail:
2253 TALLOC_FREE(m);
2254 return status;
2257 NTSTATUS pdb_samba4_init(void);
2258 NTSTATUS pdb_samba4_init(void)
2260 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2261 pdb_init_samba4);