s3-pdb_samba4: Remove unused attribute from domain search
[Samba.git] / source3 / passdb / pdb_samba4.c
blob01463041e325e7b0791ed1343b986d8beeb68531
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 "source4/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 union unid_t *id, 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 union unid_t id;
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, &id, &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;
896 map->gid = id.gid;
898 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
899 NULL);
900 if (str == NULL) {
901 talloc_free(tmp_ctx);
902 return NT_STATUS_INTERNAL_DB_CORRUPTION;
904 fstrcpy(map->nt_name, str);
906 str = ldb_msg_find_attr_as_string(msg, "description",
907 NULL);
908 if (str != NULL) {
909 fstrcpy(map->comment, str);
910 } else {
911 map->comment[0] = '\0';
914 talloc_free(tmp_ctx);
915 return NT_STATUS_OK;
918 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
919 struct dom_sid sid)
921 char *filter;
922 NTSTATUS status;
924 filter = talloc_asprintf(talloc_tos(),
925 "(&(objectsid=%s)(objectclass=group))",
926 sid_string_talloc(talloc_tos(), &sid));
927 if (filter == NULL) {
928 return NT_STATUS_NO_MEMORY;
931 status = pdb_samba4_getgrfilter(m, map, filter);
932 TALLOC_FREE(filter);
933 return status;
936 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
937 gid_t gid)
939 struct pdb_samba4_state *state = talloc_get_type_abort(
940 m->private_data, struct pdb_samba4_state);
941 NTSTATUS status;
942 struct id_map id_map;
943 struct id_map *id_maps[2];
944 TALLOC_CTX *tmp_ctx = talloc_stackframe();
945 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
947 id_map.xid.id = gid;
948 id_map.xid.type = ID_TYPE_GID;
949 id_maps[0] = &id_map;
950 id_maps[1] = NULL;
952 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
953 if (!NT_STATUS_IS_OK(status)) {
954 return status;
956 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
957 talloc_free(tmp_ctx);
958 return status;
961 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
962 const char *name)
964 char *filter;
965 NTSTATUS status;
967 filter = talloc_asprintf(talloc_tos(),
968 "(&(samaccountname=%s)(objectclass=group))",
969 name);
970 if (filter == NULL) {
971 return NT_STATUS_NO_MEMORY;
974 status = pdb_samba4_getgrfilter(m, map, filter);
975 TALLOC_FREE(filter);
976 return status;
979 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
980 TALLOC_CTX *mem_ctx, const char *name,
981 uint32 *rid)
983 struct pdb_samba4_state *state = talloc_get_type_abort(
984 m->private_data, struct pdb_samba4_state);
985 NTSTATUS status;
986 struct dom_sid *sid;
987 struct ldb_dn *dn;
988 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
989 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
991 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
992 if (!NT_STATUS_IS_OK(status)) {
993 talloc_free(tmp_ctx);
994 return status;
997 sid_peek_rid(sid, rid);
998 talloc_free(tmp_ctx);
999 return NT_STATUS_OK;
1002 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1003 TALLOC_CTX *mem_ctx, uint32 rid)
1005 const char *attrs[] = { NULL };
1006 struct pdb_samba4_state *state = talloc_get_type_abort(
1007 m->private_data, struct pdb_samba4_state);
1008 struct dom_sid sid;
1009 struct ldb_message *msg;
1010 struct ldb_dn *dn;
1011 int rc;
1012 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1013 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1015 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1017 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1018 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1019 return NT_STATUS_INTERNAL_ERROR;
1022 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1023 if (!dn || !ldb_dn_validate(dn)) {
1024 talloc_free(tmp_ctx);
1025 ldb_transaction_cancel(state->ldb);
1026 return NT_STATUS_NO_MEMORY;
1028 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1029 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1030 talloc_free(tmp_ctx);
1031 ldb_transaction_cancel(state->ldb);
1032 return NT_STATUS_NO_SUCH_GROUP;
1034 rc = ldb_delete(state->ldb, dn);
1035 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1036 talloc_free(tmp_ctx);
1037 ldb_transaction_cancel(state->ldb);
1038 return NT_STATUS_NO_SUCH_GROUP;
1039 } else if (rc != LDB_SUCCESS) {
1040 DEBUG(10, ("ldb_delete failed %s\n",
1041 ldb_errstring(state->ldb)));
1042 ldb_transaction_cancel(state->ldb);
1043 return NT_STATUS_LDAP(rc);
1046 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1047 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1048 return NT_STATUS_INTERNAL_ERROR;
1050 return NT_STATUS_OK;
1053 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1054 GROUP_MAP *map)
1056 return NT_STATUS_NOT_IMPLEMENTED;
1059 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1060 GROUP_MAP *map)
1062 return NT_STATUS_NOT_IMPLEMENTED;
1065 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1066 struct dom_sid sid)
1068 return NT_STATUS_NOT_IMPLEMENTED;
1071 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1072 const struct dom_sid *sid,
1073 enum lsa_SidType sid_name_use,
1074 GROUP_MAP **pp_rmap,
1075 size_t *p_num_entries,
1076 bool unix_only)
1078 return NT_STATUS_NOT_IMPLEMENTED;
1081 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1082 TALLOC_CTX *mem_ctx,
1083 const struct dom_sid *group,
1084 uint32_t **pmembers,
1085 size_t *pnum_members)
1087 unsigned int i, num_sids, num_members;
1088 struct pdb_samba4_state *state = talloc_get_type_abort(
1089 m->private_data, struct pdb_samba4_state);
1090 struct dom_sid *members_as_sids;
1091 struct dom_sid *dom_sid;
1092 uint32_t *members;
1093 struct ldb_dn *dn;
1094 NTSTATUS status;
1096 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1097 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1099 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1100 if (!dn || !ldb_dn_validate(dn)) {
1101 return NT_STATUS_NO_MEMORY;
1104 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1105 if (!NT_STATUS_IS_OK(status)) {
1106 talloc_free(tmp_ctx);
1107 return status;
1109 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1110 if (!NT_STATUS_IS_OK(status)) {
1111 talloc_free(tmp_ctx);
1112 return status;
1115 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1116 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1117 num_members = 0;
1119 for (i = 0; i < num_sids; i++) {
1120 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1121 continue;
1123 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1124 NULL, &members[num_members]);
1125 if (!NT_STATUS_IS_OK(status)) {
1126 talloc_free(tmp_ctx);
1127 return status;
1129 num_members++;
1131 *pnum_members = num_members;
1132 return NT_STATUS_OK;
1135 /* Just convert the primary group SID into a group */
1136 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1137 TALLOC_CTX *mem_ctx,
1138 struct samu *user,
1139 struct dom_sid **pp_sids,
1140 gid_t **pp_gids,
1141 uint32_t *p_num_groups)
1143 NTSTATUS status;
1144 size_t num_groups = 0;
1145 struct dom_sid *group_sids;
1146 gid_t *gids;
1147 TALLOC_CTX *tmp_ctx;
1149 tmp_ctx = talloc_new(mem_ctx);
1150 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1152 if (user->group_sid) {
1153 struct id_map *id_maps[2];
1154 struct id_map id_map;
1156 num_groups = 1;
1158 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1159 if (group_sids == NULL) {
1160 talloc_free(tmp_ctx);
1161 return NT_STATUS_NO_MEMORY;
1163 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1164 if (gids == NULL) {
1165 talloc_free(tmp_ctx);
1166 return NT_STATUS_NO_MEMORY;
1169 group_sids[0] = *user->group_sid;
1171 ZERO_STRUCT(id_map);
1172 id_map.sid = &group_sids[0];
1173 id_maps[0] = &id_map;
1174 id_maps[1] = NULL;
1176 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1177 if (!NT_STATUS_IS_OK(status)) {
1178 talloc_free(tmp_ctx);
1179 return status;
1181 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1182 gids[0] = id_map.xid.id;
1183 } else {
1184 DEBUG(1, (__location__
1185 "Group %s, of which %s is a member, could not be converted to a GID\n",
1186 dom_sid_string(tmp_ctx, &group_sids[0]),
1187 dom_sid_string(tmp_ctx, &user->user_sid)));
1188 talloc_free(tmp_ctx);
1189 /* We must error out, otherwise a user might
1190 * avoid a DENY acl based on a group they
1191 * missed out on */
1192 return NT_STATUS_NO_SUCH_GROUP;
1196 *pp_sids = talloc_steal(mem_ctx, group_sids);
1197 *pp_gids = talloc_steal(mem_ctx, gids);
1198 *p_num_groups = num_groups;
1199 talloc_free(tmp_ctx);
1200 return NT_STATUS_OK;
1203 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1204 TALLOC_CTX *mem_ctx,
1205 struct samu *user,
1206 struct dom_sid **pp_sids,
1207 gid_t **pp_gids,
1208 uint32_t *p_num_groups)
1210 struct pdb_samba4_state *state = talloc_get_type_abort(
1211 m->private_data, struct pdb_samba4_state);
1212 struct ldb_message *msg = pdb_samba4_get_samu_private(
1213 m, user);
1214 const char *attrs[] = { "tokenGroups", NULL};
1215 struct ldb_message *tokengroups_msg;
1216 struct ldb_message_element *tokengroups;
1217 int i, rc;
1218 NTSTATUS status;
1219 unsigned int count = 0;
1220 size_t num_groups;
1221 struct dom_sid *group_sids;
1222 gid_t *gids;
1223 TALLOC_CTX *tmp_ctx;
1225 if (msg == NULL) {
1226 /* Fake up some things here */
1227 return fake_enum_group_memberships(state,
1228 mem_ctx,
1229 user, pp_sids,
1230 pp_gids, p_num_groups);
1233 tmp_ctx = talloc_new(mem_ctx);
1234 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1236 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1238 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1239 talloc_free(tmp_ctx);
1240 return NT_STATUS_NO_SUCH_USER;
1241 } else if (rc != LDB_SUCCESS) {
1242 DEBUG(10, ("dsdb_search_one failed %s\n",
1243 ldb_errstring(state->ldb)));
1244 talloc_free(tmp_ctx);
1245 return NT_STATUS_LDAP(rc);
1248 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1250 if (tokengroups) {
1251 count = tokengroups->num_values;
1254 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1255 if (group_sids == NULL) {
1256 talloc_free(tmp_ctx);
1257 return NT_STATUS_NO_MEMORY;
1259 gids = talloc_array(tmp_ctx, gid_t, count);
1260 if (gids == NULL) {
1261 talloc_free(tmp_ctx);
1262 return NT_STATUS_NO_MEMORY;
1264 num_groups = 0;
1266 for (i=0; i<count; i++) {
1267 struct id_map *id_maps[2];
1268 struct id_map id_map;
1269 struct ldb_val *v = &tokengroups->values[i];
1270 enum ndr_err_code ndr_err
1271 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1272 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1273 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1274 talloc_free(tmp_ctx);
1275 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1278 ZERO_STRUCT(id_map);
1279 id_map.sid = &group_sids[num_groups];
1280 id_maps[0] = &id_map;
1281 id_maps[1] = NULL;
1283 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1284 if (!NT_STATUS_IS_OK(status)) {
1285 talloc_free(tmp_ctx);
1286 return status;
1288 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1289 gids[num_groups] = id_map.xid.id;
1290 } else {
1291 DEBUG(1, (__location__
1292 "Group %s, of which %s is a member, could not be converted to a GID\n",
1293 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1294 ldb_dn_get_linearized(msg->dn)));
1295 talloc_free(tmp_ctx);
1296 /* We must error out, otherwise a user might
1297 * avoid a DENY acl based on a group they
1298 * missed out on */
1299 return NT_STATUS_NO_SUCH_GROUP;
1302 num_groups += 1;
1303 if (num_groups == count) {
1304 break;
1308 *pp_sids = talloc_steal(mem_ctx, group_sids);
1309 *pp_gids = talloc_steal(mem_ctx, gids);
1310 *p_num_groups = num_groups;
1311 talloc_free(tmp_ctx);
1312 return NT_STATUS_OK;
1315 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1316 TALLOC_CTX *mem_ctx,
1317 struct samu *user)
1319 return NT_STATUS_NOT_IMPLEMENTED;
1322 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1323 TALLOC_CTX *mem_ctx,
1324 const struct dom_sid *groupsid,
1325 const struct dom_sid *membersid,
1326 int mod_op)
1328 struct pdb_samba4_state *state = talloc_get_type_abort(
1329 m->private_data, struct pdb_samba4_state);
1330 struct ldb_message *msg;
1331 int ret;
1332 struct ldb_message_element *el;
1333 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1334 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1335 msg = ldb_msg_new(tmp_ctx);
1336 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1338 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1339 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1340 talloc_free(tmp_ctx);
1341 return NT_STATUS_NO_MEMORY;
1343 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1344 if (ret != LDB_SUCCESS) {
1345 talloc_free(tmp_ctx);
1346 return NT_STATUS_NO_MEMORY;
1348 el = ldb_msg_find_element(msg, "member");
1349 el->flags = mod_op;
1351 /* No need for transactions here, the ldb auto-transaction
1352 * code will handle things for the single operation */
1353 ret = ldb_modify(state->ldb, msg);
1354 talloc_free(tmp_ctx);
1355 if (ret != LDB_SUCCESS) {
1356 DEBUG(10, ("ldb_modify failed: %s\n",
1357 ldb_errstring(state->ldb)));
1358 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1359 return NT_STATUS_MEMBER_IN_GROUP;
1361 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1362 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1364 return NT_STATUS_LDAP(ret);
1367 return NT_STATUS_OK;
1370 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1371 TALLOC_CTX *mem_ctx,
1372 uint32 grouprid, uint32 memberrid,
1373 int mod_op)
1375 struct pdb_samba4_state *state = talloc_get_type_abort(
1376 m->private_data, struct pdb_samba4_state);
1377 const struct dom_sid *dom_sid, *groupsid, *membersid;
1378 NTSTATUS status;
1379 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1380 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1382 dom_sid = samdb_domain_sid(state->ldb);
1384 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1385 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1386 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1387 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1388 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1389 talloc_free(tmp_ctx);
1390 return status;
1393 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1394 TALLOC_CTX *mem_ctx,
1395 uint32 group_rid, uint32 member_rid)
1397 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1398 LDB_FLAG_MOD_ADD);
1401 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1402 TALLOC_CTX *mem_ctx,
1403 uint32 group_rid, uint32 member_rid)
1405 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1406 LDB_FLAG_MOD_DELETE);
1409 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1410 const char *name, uint32 *rid)
1412 TALLOC_CTX *frame = talloc_stackframe();
1413 struct pdb_samba4_state *state = talloc_get_type_abort(
1414 m->private_data, struct pdb_samba4_state);
1415 struct dom_sid *sid;
1417 struct ldb_dn *dn;
1418 NTSTATUS status;
1420 /* Internally this uses transactions to ensure all the steps
1421 * happen or fail as one */
1422 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1423 if (!NT_STATUS_IS_OK(status)) {
1424 TALLOC_FREE(frame);
1427 sid_peek_rid(sid, rid);
1428 TALLOC_FREE(frame);
1429 return NT_STATUS_OK;
1432 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1433 const struct dom_sid *sid)
1435 const char *attrs[] = { NULL };
1436 struct pdb_samba4_state *state = talloc_get_type_abort(
1437 m->private_data, struct pdb_samba4_state);
1438 struct ldb_message *msg;
1439 struct ldb_dn *dn;
1440 int rc;
1441 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1442 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1444 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1445 if (!dn || !ldb_dn_validate(dn)) {
1446 talloc_free(tmp_ctx);
1447 return NT_STATUS_NO_MEMORY;
1450 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1451 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1452 return NT_STATUS_INTERNAL_ERROR;
1455 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1456 "(|(grouptype=%d)(grouptype=%d)))",
1457 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1458 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1459 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1460 talloc_free(tmp_ctx);
1461 ldb_transaction_cancel(state->ldb);
1462 return NT_STATUS_NO_SUCH_ALIAS;
1464 rc = ldb_delete(state->ldb, dn);
1465 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1466 talloc_free(tmp_ctx);
1467 ldb_transaction_cancel(state->ldb);
1468 return NT_STATUS_NO_SUCH_ALIAS;
1469 } else if (rc != LDB_SUCCESS) {
1470 DEBUG(10, ("ldb_delete failed %s\n",
1471 ldb_errstring(state->ldb)));
1472 ldb_transaction_cancel(state->ldb);
1473 return NT_STATUS_LDAP(rc);
1476 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1477 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1478 ldb_errstring(state->ldb)));
1479 return NT_STATUS_INTERNAL_ERROR;
1482 return NT_STATUS_OK;
1485 #if 0
1486 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1487 const struct dom_sid *sid,
1488 struct acct_info *info)
1490 struct pdb_samba4_state *state = talloc_get_type_abort(
1491 m->private_data, struct pdb_samba4_state);
1492 struct tldap_context *ld;
1493 const char *attrs[3] = { "objectSid", "description",
1494 "samAccountName" };
1495 struct ldb_message **msg;
1496 char *sidstr, *dn;
1497 int rc;
1498 struct tldap_mod *mods;
1499 int num_mods;
1500 bool ok;
1502 ld = pdb_samba4_ld(state);
1503 if (ld == NULL) {
1504 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1507 sidstr = sid_binstring(talloc_tos(), sid);
1508 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1510 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1511 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1512 &msg, "(&(objectSid=%s)(objectclass=group)"
1513 "(|(grouptype=%d)(grouptype=%d)))",
1514 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1515 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1516 TALLOC_FREE(sidstr)
1517 if (rc != LDB_SUCCESS) {
1518 DEBUG(10, ("ldap_search failed %s\n",
1519 ldb_errstring(state->ldb)));
1520 return NT_STATUS_LDAP(rc);
1522 switch talloc_array_length(msg) {
1523 case 0:
1524 return NT_STATUS_NO_SUCH_ALIAS;
1525 case 1:
1526 break;
1527 default:
1528 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1531 if (!tldap_entry_dn(msg[0], &dn)) {
1532 TALLOC_FREE(msg);
1533 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1536 mods = NULL;
1537 num_mods = 0;
1538 ok = true;
1540 ok &= tldap_make_mod_fmt(
1541 msg[0], msg, &num_mods, &mods, "description",
1542 "%s", info->acct_desc);
1543 ok &= tldap_make_mod_fmt(
1544 msg[0], msg, &num_mods, &mods, "samAccountName",
1545 "%s", info->acct_name);
1546 if (!ok) {
1547 TALLOC_FREE(msg);
1548 return NT_STATUS_NO_MEMORY;
1550 if (num_mods == 0) {
1551 /* no change */
1552 TALLOC_FREE(msg);
1553 return NT_STATUS_OK;
1556 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1557 TALLOC_FREE(msg);
1558 if (rc != LDB_SUCCESS) {
1559 DEBUG(10, ("ldap_modify failed: %s\n",
1560 ldb_errstring(state->ldb)));
1561 return NT_STATUS_LDAP(rc);
1563 return NT_STATUS_OK;
1565 #endif
1566 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1567 const struct dom_sid *alias,
1568 const struct dom_sid *member)
1570 NTSTATUS status;
1571 TALLOC_CTX *frame = talloc_stackframe();
1572 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1573 talloc_free(frame);
1574 return status;
1577 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1578 const struct dom_sid *alias,
1579 const struct dom_sid *member)
1581 NTSTATUS status;
1582 TALLOC_CTX *frame = talloc_stackframe();
1583 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1584 talloc_free(frame);
1585 return status;
1588 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1589 const struct dom_sid *alias,
1590 TALLOC_CTX *mem_ctx,
1591 struct dom_sid **pmembers,
1592 size_t *pnum_members)
1594 struct pdb_samba4_state *state = talloc_get_type_abort(
1595 m->private_data, struct pdb_samba4_state);
1596 struct ldb_dn *dn;
1597 unsigned int num_members;
1598 NTSTATUS status;
1599 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1600 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1602 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1603 if (!dn || !ldb_dn_validate(dn)) {
1604 return NT_STATUS_NO_MEMORY;
1607 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1608 *pnum_members = num_members;
1609 if (NT_STATUS_IS_OK(status)) {
1610 talloc_steal(mem_ctx, pmembers);
1612 talloc_free(tmp_ctx);
1613 return status;
1616 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1617 TALLOC_CTX *mem_ctx,
1618 const struct dom_sid *domain_sid,
1619 const struct dom_sid *members,
1620 size_t num_members,
1621 uint32_t **palias_rids,
1622 size_t *pnum_alias_rids)
1624 struct pdb_samba4_state *state = talloc_get_type_abort(
1625 m->private_data, struct pdb_samba4_state);
1626 uint32_t *alias_rids = NULL;
1627 size_t num_alias_rids = 0;
1628 int i;
1629 struct dom_sid *groupSIDs = NULL;
1630 unsigned int num_groupSIDs = 0;
1631 char *filter;
1632 NTSTATUS status;
1633 const char *sid_string;
1634 const char *sid_dn;
1635 DATA_BLOB sid_blob;
1637 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1638 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1640 * TODO: Get the filter right so that we only get the aliases from
1641 * either the SAM or BUILTIN
1644 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1645 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1646 if (filter == NULL) {
1647 return NT_STATUS_NO_MEMORY;
1650 for (i = 0; i < num_members; i++) {
1651 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1652 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1654 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1655 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1657 sid_blob = data_blob_string_const(sid_dn);
1659 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1660 tmp_ctx, &groupSIDs, &num_groupSIDs);
1661 if (!NT_STATUS_IS_OK(status)) {
1662 talloc_free(tmp_ctx);
1663 return status;
1667 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1668 if (alias_rids == NULL) {
1669 talloc_free(tmp_ctx);
1670 return NT_STATUS_NO_MEMORY;
1673 for (i=0; i<num_groupSIDs; i++) {
1674 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1675 &alias_rids[num_alias_rids])) {
1676 num_alias_rids++;;
1680 *palias_rids = alias_rids;
1681 *pnum_alias_rids = num_alias_rids;
1682 return NT_STATUS_OK;
1685 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1686 const struct dom_sid *domain_sid,
1687 int num_rids,
1688 uint32 *rids,
1689 const char **names,
1690 enum lsa_SidType *lsa_attrs)
1692 struct pdb_samba4_state *state = talloc_get_type_abort(
1693 m->private_data, struct pdb_samba4_state);
1694 NTSTATUS status;
1696 TALLOC_CTX *tmp_ctx;
1698 if (num_rids == 0) {
1699 return NT_STATUS_NONE_MAPPED;
1702 tmp_ctx = talloc_stackframe();
1703 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1705 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1706 talloc_free(tmp_ctx);
1707 return status;
1710 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1711 const struct dom_sid *domain_sid,
1712 int num_names,
1713 const char **pp_names,
1714 uint32 *rids,
1715 enum lsa_SidType *attrs)
1717 return NT_STATUS_NOT_IMPLEMENTED;
1720 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1721 enum pdb_policy_type type,
1722 uint32_t *value)
1724 return account_policy_get(type, value)
1725 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1728 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1729 enum pdb_policy_type type,
1730 uint32_t value)
1732 return account_policy_set(type, value)
1733 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1736 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1737 time_t *seq_num_out)
1739 struct pdb_samba4_state *state = talloc_get_type_abort(
1740 m->private_data, struct pdb_samba4_state);
1741 uint64_t seq_num;
1742 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1743 if (ret == LDB_SUCCESS) {
1744 *seq_num_out = seq_num;
1745 return NT_STATUS_OK;
1746 } else {
1747 return NT_STATUS_UNSUCCESSFUL;
1751 struct pdb_samba4_search_state {
1752 uint32_t acct_flags;
1753 struct samr_displayentry *entries;
1754 uint32_t num_entries;
1755 ssize_t array_size;
1756 uint32_t current;
1759 static bool pdb_samba4_next_entry(struct pdb_search *search,
1760 struct samr_displayentry *entry)
1762 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1763 search->private_data, struct pdb_samba4_search_state);
1765 if (state->current == state->num_entries) {
1766 return false;
1769 entry->idx = state->entries[state->current].idx;
1770 entry->rid = state->entries[state->current].rid;
1771 entry->acct_flags = state->entries[state->current].acct_flags;
1773 entry->account_name = talloc_strdup(
1774 search, state->entries[state->current].account_name);
1775 entry->fullname = talloc_strdup(
1776 search, state->entries[state->current].fullname);
1777 entry->description = talloc_strdup(
1778 search, state->entries[state->current].description);
1780 state->current += 1;
1781 return true;
1784 static void pdb_samba4_search_end(struct pdb_search *search)
1786 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1787 search->private_data, struct pdb_samba4_search_state);
1788 talloc_free(state);
1791 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1792 struct pdb_search *search,
1793 struct pdb_samba4_search_state **pstate,
1794 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1796 struct pdb_samba4_state *state = talloc_get_type_abort(
1797 m->private_data, struct pdb_samba4_state);
1798 struct pdb_samba4_search_state *sstate;
1799 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1800 "userAccountControl", "description", NULL };
1801 struct ldb_result *res;
1802 int i, rc, num_users;
1804 va_list ap;
1805 char *expression = NULL;
1807 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1808 if (!tmp_ctx) {
1809 return false;
1812 va_start(ap, exp_fmt);
1813 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1814 va_end(ap);
1816 if (!expression) {
1817 talloc_free(tmp_ctx);
1818 return LDB_ERR_OPERATIONS_ERROR;
1821 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1822 if (sstate == NULL) {
1823 talloc_free(tmp_ctx);
1824 return false;
1827 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1828 if (rc != LDB_SUCCESS) {
1829 talloc_free(tmp_ctx);
1830 DEBUG(10, ("dsdb_search failed: %s\n",
1831 ldb_errstring(state->ldb)));
1832 return false;
1835 num_users = res->count;
1837 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1838 num_users);
1839 if (sstate->entries == NULL) {
1840 talloc_free(tmp_ctx);
1841 DEBUG(10, ("talloc failed\n"));
1842 return false;
1845 sstate->num_entries = 0;
1847 for (i=0; i<num_users; i++) {
1848 struct samr_displayentry *e;
1849 struct dom_sid *sid;
1851 e = &sstate->entries[sstate->num_entries];
1853 e->idx = sstate->num_entries;
1854 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1855 if (!sid) {
1856 talloc_free(tmp_ctx);
1857 DEBUG(10, ("Could not pull SID\n"));
1858 return false;
1860 sid_peek_rid(sid, &e->rid);
1862 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1863 res->msgs[i],
1864 ldb_get_default_basedn(state->ldb));
1865 e->account_name = ldb_msg_find_attr_as_string(
1866 res->msgs[i], "samAccountName", NULL);
1867 if (e->account_name == NULL) {
1868 talloc_free(tmp_ctx);
1869 return false;
1871 e->fullname = ldb_msg_find_attr_as_string(
1872 res->msgs[i], "displayName", "");
1873 e->description = ldb_msg_find_attr_as_string(
1874 res->msgs[i], "description", "");
1876 sstate->num_entries += 1;
1877 if (sstate->num_entries >= num_users) {
1878 break;
1881 talloc_steal(sstate->entries, res->msgs);
1882 search->private_data = talloc_steal(search, sstate);
1883 search->next_entry = pdb_samba4_next_entry;
1884 search->search_end = pdb_samba4_search_end;
1885 *pstate = sstate;
1886 talloc_free(tmp_ctx);
1887 return true;
1890 static bool pdb_samba4_search_users(struct pdb_methods *m,
1891 struct pdb_search *search,
1892 uint32 acct_flags)
1894 struct pdb_samba4_search_state *sstate;
1895 bool ret;
1897 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1898 if (!ret) {
1899 return false;
1901 sstate->acct_flags = acct_flags;
1902 return true;
1905 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1906 struct pdb_search *search)
1908 struct pdb_samba4_search_state *sstate;
1909 bool ret;
1911 ret = pdb_samba4_search_filter(m, search, &sstate,
1912 "(&(grouptype=%d)(objectclass=group))",
1913 GTYPE_SECURITY_GLOBAL_GROUP);
1914 if (!ret) {
1915 return false;
1917 sstate->acct_flags = 0;
1918 return true;
1921 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1922 struct pdb_search *search,
1923 const struct dom_sid *sid)
1925 struct pdb_samba4_search_state *sstate;
1926 bool ret;
1928 ret = pdb_samba4_search_filter(m, search, &sstate,
1929 "(&(grouptype=%d)(objectclass=group))",
1930 sid_check_is_builtin(sid)
1931 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1932 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1933 if (!ret) {
1934 return false;
1936 sstate->acct_flags = 0;
1937 return true;
1940 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1941 struct dom_sid *sid)
1943 struct pdb_samba4_state *state = talloc_get_type_abort(
1944 m->private_data, struct pdb_samba4_state);
1945 NTSTATUS status;
1946 struct id_map id_map;
1947 struct id_map *id_maps[2];
1948 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1949 if (!tmp_ctx) {
1950 return false;
1953 id_map.xid.id = uid;
1954 id_map.xid.type = ID_TYPE_UID;
1955 id_maps[0] = &id_map;
1956 id_maps[1] = NULL;
1958 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1959 if (!NT_STATUS_IS_OK(status)) {
1960 talloc_free(tmp_ctx);
1961 return false;
1963 *sid = *id_map.sid;
1964 talloc_free(tmp_ctx);
1965 return true;
1968 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1969 struct dom_sid *sid)
1971 struct pdb_samba4_state *state = talloc_get_type_abort(
1972 m->private_data, struct pdb_samba4_state);
1973 NTSTATUS status;
1974 struct id_map id_map;
1975 struct id_map *id_maps[2];
1976 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1977 if (!tmp_ctx) {
1978 return false;
1981 id_map.xid.id = gid;
1982 id_map.xid.type = ID_TYPE_GID;
1983 id_maps[0] = &id_map;
1984 id_maps[1] = NULL;
1986 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1987 if (!NT_STATUS_IS_OK(status)) {
1988 return false;
1990 *sid = *id_map.sid;
1991 talloc_free(tmp_ctx);
1992 return true;
1995 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
1996 union unid_t *id, enum lsa_SidType *type)
1998 struct pdb_samba4_state *state = talloc_get_type_abort(
1999 m->private_data, struct pdb_samba4_state);
2000 struct id_map id_map;
2001 struct id_map *id_maps[2];
2002 const char *attrs[] = { "objectClass", "groupType", NULL };
2003 struct ldb_message *msg;
2004 struct ldb_dn *dn;
2005 NTSTATUS status;
2006 int rc;
2007 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2008 if (!tmp_ctx) {
2009 return false;
2012 ZERO_STRUCT(id_map);
2014 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2015 if (!dn || !ldb_dn_validate(dn)) {
2016 talloc_free(tmp_ctx);
2017 return false;
2019 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2020 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2021 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)));
2022 talloc_free(tmp_ctx);
2023 return false;
2025 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2026 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
2027 switch (grouptype) {
2028 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
2029 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
2030 *type = SID_NAME_ALIAS;
2031 break;
2032 case GTYPE_SECURITY_GLOBAL_GROUP:
2033 *type = SID_NAME_DOM_GRP;
2034 break;
2035 default:
2036 talloc_free(tmp_ctx);
2037 DEBUG(10, ("Could not pull groupType\n"));
2038 return false;
2041 *type = SID_NAME_DOM_GRP;
2043 ZERO_STRUCT(id_map);
2044 id_map.sid = sid;
2045 id_maps[0] = &id_map;
2046 id_maps[1] = NULL;
2048 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2049 talloc_free(tmp_ctx);
2050 if (!NT_STATUS_IS_OK(status)) {
2051 return false;
2053 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
2054 id->gid = id_map.xid.id;
2055 return true;
2057 return false;
2058 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2059 *type = SID_NAME_USER;
2060 ZERO_STRUCT(id_map);
2061 id_map.sid = sid;
2062 id_maps[0] = &id_map;
2063 id_maps[1] = NULL;
2065 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2066 talloc_free(tmp_ctx);
2067 if (!NT_STATUS_IS_OK(status)) {
2068 return false;
2070 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2071 id->uid = id_map.xid.id;
2072 return true;
2074 return false;
2076 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)));
2077 talloc_free(tmp_ctx);
2078 return false;
2081 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2083 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2086 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2088 return false;
2091 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2092 const char *domain, char** pwd,
2093 struct dom_sid *sid,
2094 time_t *pass_last_set_time)
2096 return false;
2099 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2100 const char* domain, const char* pwd,
2101 const struct dom_sid *sid)
2103 return false;
2106 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2107 const char *domain)
2109 return false;
2112 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2113 TALLOC_CTX *mem_ctx,
2114 uint32 *num_domains,
2115 struct trustdom_info ***domains)
2117 *num_domains = 0;
2118 *domains = NULL;
2119 return NT_STATUS_OK;
2122 static void pdb_samba4_init_methods(struct pdb_methods *m)
2124 m->name = "samba4";
2125 m->get_domain_info = pdb_samba4_get_domain_info;
2126 m->getsampwnam = pdb_samba4_getsampwnam;
2127 m->getsampwsid = pdb_samba4_getsampwsid;
2128 m->create_user = pdb_samba4_create_user;
2129 m->delete_user = pdb_samba4_delete_user;
2130 m->add_sam_account = pdb_samba4_add_sam_account;
2131 m->update_sam_account = pdb_samba4_update_sam_account;
2132 m->delete_sam_account = pdb_samba4_delete_sam_account;
2133 m->rename_sam_account = pdb_samba4_rename_sam_account;
2134 m->update_login_attempts = pdb_samba4_update_login_attempts;
2135 m->getgrsid = pdb_samba4_getgrsid;
2136 m->getgrgid = pdb_samba4_getgrgid;
2137 m->getgrnam = pdb_samba4_getgrnam;
2138 m->create_dom_group = pdb_samba4_create_dom_group;
2139 m->delete_dom_group = pdb_samba4_delete_dom_group;
2140 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2141 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2142 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2143 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2144 m->enum_group_members = pdb_samba4_enum_group_members;
2145 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2146 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2147 m->add_groupmem = pdb_samba4_add_groupmem;
2148 m->del_groupmem = pdb_samba4_del_groupmem;
2149 m->create_alias = pdb_samba4_create_alias;
2150 m->delete_alias = pdb_samba4_delete_alias;
2151 m->get_aliasinfo = pdb_default_get_aliasinfo;
2152 m->add_aliasmem = pdb_samba4_add_aliasmem;
2153 m->del_aliasmem = pdb_samba4_del_aliasmem;
2154 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2155 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2156 m->lookup_rids = pdb_samba4_lookup_rids;
2157 m->lookup_names = pdb_samba4_lookup_names;
2158 m->get_account_policy = pdb_samba4_get_account_policy;
2159 m->set_account_policy = pdb_samba4_set_account_policy;
2160 m->get_seq_num = pdb_samba4_get_seq_num;
2161 m->search_users = pdb_samba4_search_users;
2162 m->search_groups = pdb_samba4_search_groups;
2163 m->search_aliases = pdb_samba4_search_aliases;
2164 m->uid_to_sid = pdb_samba4_uid_to_sid;
2165 m->gid_to_sid = pdb_samba4_gid_to_sid;
2166 m->sid_to_id = pdb_samba4_sid_to_id;
2167 m->capabilities = pdb_samba4_capabilities;
2168 m->new_rid = pdb_samba4_new_rid;
2169 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2170 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2171 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2172 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2175 static void free_private_data(void **vp)
2177 struct pdb_samba4_state *state = talloc_get_type_abort(
2178 *vp, struct pdb_samba4_state);
2179 talloc_unlink(state, state->ldb);
2180 return;
2183 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2184 const char *location)
2186 struct pdb_methods *m;
2187 struct pdb_samba4_state *state;
2188 NTSTATUS status;
2190 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2191 return status;
2194 state = talloc_zero(m, struct pdb_samba4_state);
2195 if (state == NULL) {
2196 goto nomem;
2198 m->private_data = state;
2199 m->free_private_data = free_private_data;
2200 pdb_samba4_init_methods(m);
2202 state->ev = s4_event_context_init(state);
2203 if (!state->ev) {
2204 DEBUG(0, ("s4_event_context_init failed\n"));
2205 goto nomem;
2208 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2209 if (state->lp_ctx == NULL) {
2210 DEBUG(0, ("loadparm_init_s3 failed\n"));
2211 goto nomem;
2214 if (location) {
2215 state->ldb = samdb_connect_url(state,
2216 state->ev,
2217 state->lp_ctx,
2218 system_session(state->lp_ctx),
2219 0, location);
2220 } else {
2221 state->ldb = samdb_connect(state,
2222 state->ev,
2223 state->lp_ctx,
2224 system_session(state->lp_ctx), 0);
2227 if (!state->ldb) {
2228 DEBUG(0, ("samdb_connect failed\n"));
2229 status = NT_STATUS_INTERNAL_ERROR;
2230 goto fail;
2233 state->idmap_ctx = idmap_init(state, state->ev,
2234 state->lp_ctx);
2235 if (!state->idmap_ctx) {
2236 DEBUG(0, ("idmap failed\n"));
2237 status = NT_STATUS_INTERNAL_ERROR;
2238 goto fail;
2241 *pdb_method = m;
2242 return NT_STATUS_OK;
2243 nomem:
2244 status = NT_STATUS_NO_MEMORY;
2245 fail:
2246 TALLOC_FREE(m);
2247 return status;
2250 NTSTATUS pdb_samba4_init(void);
2251 NTSTATUS pdb_samba4_init(void)
2253 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2254 pdb_init_samba4);