s3-utils: add capabilities to dbwrap_tool
[Samba/gebeck_regimport.git] / source3 / passdb / pdb_samba4.c
blobaf252143cdc87a21f772f0a2ba8511f877c0397f
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 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 map->nt_name = talloc_strdup(map, str);
905 if (!map->nt_name) {
906 talloc_free(tmp_ctx);
907 return NT_STATUS_NO_MEMORY;
910 str = ldb_msg_find_attr_as_string(msg, "description",
911 NULL);
912 if (str != NULL) {
913 map->comment = talloc_strdup(map, str);
914 } else {
915 map->comment = talloc_strdup(map, "");
917 if (!map->comment) {
918 talloc_free(tmp_ctx);
919 return NT_STATUS_NO_MEMORY;
922 talloc_free(tmp_ctx);
923 return NT_STATUS_OK;
926 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
927 struct dom_sid sid)
929 char *filter;
930 NTSTATUS status;
932 filter = talloc_asprintf(talloc_tos(),
933 "(&(objectsid=%s)(objectclass=group))",
934 sid_string_talloc(talloc_tos(), &sid));
935 if (filter == NULL) {
936 return NT_STATUS_NO_MEMORY;
939 status = pdb_samba4_getgrfilter(m, map, filter);
940 TALLOC_FREE(filter);
941 return status;
944 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
945 gid_t gid)
947 struct pdb_samba4_state *state = talloc_get_type_abort(
948 m->private_data, struct pdb_samba4_state);
949 NTSTATUS status;
950 struct id_map id_map;
951 struct id_map *id_maps[2];
952 TALLOC_CTX *tmp_ctx = talloc_stackframe();
953 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
955 id_map.xid.id = gid;
956 id_map.xid.type = ID_TYPE_GID;
957 id_maps[0] = &id_map;
958 id_maps[1] = NULL;
960 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
961 if (!NT_STATUS_IS_OK(status)) {
962 return status;
964 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
965 talloc_free(tmp_ctx);
966 return status;
969 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
970 const char *name)
972 char *filter;
973 NTSTATUS status;
975 filter = talloc_asprintf(talloc_tos(),
976 "(&(samaccountname=%s)(objectclass=group))",
977 name);
978 if (filter == NULL) {
979 return NT_STATUS_NO_MEMORY;
982 status = pdb_samba4_getgrfilter(m, map, filter);
983 TALLOC_FREE(filter);
984 return status;
987 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
988 TALLOC_CTX *mem_ctx, const char *name,
989 uint32 *rid)
991 struct pdb_samba4_state *state = talloc_get_type_abort(
992 m->private_data, struct pdb_samba4_state);
993 NTSTATUS status;
994 struct dom_sid *sid;
995 struct ldb_dn *dn;
996 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
997 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
999 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 talloc_free(tmp_ctx);
1002 return status;
1005 sid_peek_rid(sid, rid);
1006 talloc_free(tmp_ctx);
1007 return NT_STATUS_OK;
1010 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
1011 TALLOC_CTX *mem_ctx, uint32 rid)
1013 const char *attrs[] = { NULL };
1014 struct pdb_samba4_state *state = talloc_get_type_abort(
1015 m->private_data, struct pdb_samba4_state);
1016 struct dom_sid sid;
1017 struct ldb_message *msg;
1018 struct ldb_dn *dn;
1019 int rc;
1020 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1021 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1023 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
1025 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1026 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
1027 return NT_STATUS_INTERNAL_ERROR;
1030 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
1031 if (!dn || !ldb_dn_validate(dn)) {
1032 talloc_free(tmp_ctx);
1033 ldb_transaction_cancel(state->ldb);
1034 return NT_STATUS_NO_MEMORY;
1036 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
1037 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1038 talloc_free(tmp_ctx);
1039 ldb_transaction_cancel(state->ldb);
1040 return NT_STATUS_NO_SUCH_GROUP;
1042 rc = ldb_delete(state->ldb, dn);
1043 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1044 talloc_free(tmp_ctx);
1045 ldb_transaction_cancel(state->ldb);
1046 return NT_STATUS_NO_SUCH_GROUP;
1047 } else if (rc != LDB_SUCCESS) {
1048 DEBUG(10, ("ldb_delete failed %s\n",
1049 ldb_errstring(state->ldb)));
1050 ldb_transaction_cancel(state->ldb);
1051 return NT_STATUS_LDAP(rc);
1054 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1055 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
1056 return NT_STATUS_INTERNAL_ERROR;
1058 return NT_STATUS_OK;
1061 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
1062 GROUP_MAP *map)
1064 return NT_STATUS_NOT_IMPLEMENTED;
1067 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
1068 GROUP_MAP *map)
1070 return NT_STATUS_NOT_IMPLEMENTED;
1073 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
1074 struct dom_sid sid)
1076 return NT_STATUS_NOT_IMPLEMENTED;
1079 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
1080 const struct dom_sid *sid,
1081 enum lsa_SidType sid_name_use,
1082 GROUP_MAP ***pp_rmap,
1083 size_t *p_num_entries,
1084 bool unix_only)
1086 return NT_STATUS_NOT_IMPLEMENTED;
1089 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
1090 TALLOC_CTX *mem_ctx,
1091 const struct dom_sid *group,
1092 uint32_t **pmembers,
1093 size_t *pnum_members)
1095 unsigned int i, num_sids, num_members;
1096 struct pdb_samba4_state *state = talloc_get_type_abort(
1097 m->private_data, struct pdb_samba4_state);
1098 struct dom_sid *members_as_sids;
1099 struct dom_sid *dom_sid;
1100 uint32_t *members;
1101 struct ldb_dn *dn;
1102 NTSTATUS status;
1104 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1105 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1107 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
1108 if (!dn || !ldb_dn_validate(dn)) {
1109 return NT_STATUS_NO_MEMORY;
1112 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
1113 if (!NT_STATUS_IS_OK(status)) {
1114 talloc_free(tmp_ctx);
1115 return status;
1117 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 talloc_free(tmp_ctx);
1120 return status;
1123 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
1124 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
1125 num_members = 0;
1127 for (i = 0; i < num_sids; i++) {
1128 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
1129 continue;
1131 status = dom_sid_split_rid(NULL, &members_as_sids[i],
1132 NULL, &members[num_members]);
1133 if (!NT_STATUS_IS_OK(status)) {
1134 talloc_free(tmp_ctx);
1135 return status;
1137 num_members++;
1139 *pnum_members = num_members;
1140 return NT_STATUS_OK;
1143 /* Just convert the primary group SID into a group */
1144 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
1145 TALLOC_CTX *mem_ctx,
1146 struct samu *user,
1147 struct dom_sid **pp_sids,
1148 gid_t **pp_gids,
1149 uint32_t *p_num_groups)
1151 NTSTATUS status;
1152 size_t num_groups = 0;
1153 struct dom_sid *group_sids;
1154 gid_t *gids;
1155 TALLOC_CTX *tmp_ctx;
1157 tmp_ctx = talloc_new(mem_ctx);
1158 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1160 if (user->group_sid) {
1161 struct id_map *id_maps[2];
1162 struct id_map id_map;
1164 num_groups = 1;
1166 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1167 if (group_sids == NULL) {
1168 talloc_free(tmp_ctx);
1169 return NT_STATUS_NO_MEMORY;
1171 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1172 if (gids == NULL) {
1173 talloc_free(tmp_ctx);
1174 return NT_STATUS_NO_MEMORY;
1177 group_sids[0] = *user->group_sid;
1179 ZERO_STRUCT(id_map);
1180 id_map.sid = &group_sids[0];
1181 id_maps[0] = &id_map;
1182 id_maps[1] = NULL;
1184 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1185 if (!NT_STATUS_IS_OK(status)) {
1186 talloc_free(tmp_ctx);
1187 return status;
1189 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1190 gids[0] = id_map.xid.id;
1191 } else {
1192 DEBUG(1, (__location__
1193 "Group %s, of which %s is a member, could not be converted to a GID\n",
1194 dom_sid_string(tmp_ctx, &group_sids[0]),
1195 dom_sid_string(tmp_ctx, &user->user_sid)));
1196 talloc_free(tmp_ctx);
1197 /* We must error out, otherwise a user might
1198 * avoid a DENY acl based on a group they
1199 * missed out on */
1200 return NT_STATUS_NO_SUCH_GROUP;
1204 *pp_sids = talloc_steal(mem_ctx, group_sids);
1205 *pp_gids = talloc_steal(mem_ctx, gids);
1206 *p_num_groups = num_groups;
1207 talloc_free(tmp_ctx);
1208 return NT_STATUS_OK;
1211 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1212 TALLOC_CTX *mem_ctx,
1213 struct samu *user,
1214 struct dom_sid **pp_sids,
1215 gid_t **pp_gids,
1216 uint32_t *p_num_groups)
1218 struct pdb_samba4_state *state = talloc_get_type_abort(
1219 m->private_data, struct pdb_samba4_state);
1220 struct ldb_message *msg = pdb_samba4_get_samu_private(
1221 m, user);
1222 const char *attrs[] = { "tokenGroups", NULL};
1223 struct ldb_message *tokengroups_msg;
1224 struct ldb_message_element *tokengroups;
1225 int i, rc;
1226 NTSTATUS status;
1227 unsigned int count = 0;
1228 size_t num_groups;
1229 struct dom_sid *group_sids;
1230 gid_t *gids;
1231 TALLOC_CTX *tmp_ctx;
1233 if (msg == NULL) {
1234 /* Fake up some things here */
1235 return fake_enum_group_memberships(state,
1236 mem_ctx,
1237 user, pp_sids,
1238 pp_gids, p_num_groups);
1241 tmp_ctx = talloc_new(mem_ctx);
1242 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1244 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1246 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1247 talloc_free(tmp_ctx);
1248 return NT_STATUS_NO_SUCH_USER;
1249 } else if (rc != LDB_SUCCESS) {
1250 DEBUG(10, ("dsdb_search_one failed %s\n",
1251 ldb_errstring(state->ldb)));
1252 talloc_free(tmp_ctx);
1253 return NT_STATUS_LDAP(rc);
1256 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1258 if (tokengroups) {
1259 count = tokengroups->num_values;
1262 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1263 if (group_sids == NULL) {
1264 talloc_free(tmp_ctx);
1265 return NT_STATUS_NO_MEMORY;
1267 gids = talloc_array(tmp_ctx, gid_t, count);
1268 if (gids == NULL) {
1269 talloc_free(tmp_ctx);
1270 return NT_STATUS_NO_MEMORY;
1272 num_groups = 0;
1274 for (i=0; i<count; i++) {
1275 struct id_map *id_maps[2];
1276 struct id_map id_map;
1277 struct ldb_val *v = &tokengroups->values[i];
1278 enum ndr_err_code ndr_err
1279 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1280 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1281 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1282 talloc_free(tmp_ctx);
1283 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1286 ZERO_STRUCT(id_map);
1287 id_map.sid = &group_sids[num_groups];
1288 id_maps[0] = &id_map;
1289 id_maps[1] = NULL;
1291 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1292 if (!NT_STATUS_IS_OK(status)) {
1293 talloc_free(tmp_ctx);
1294 return status;
1296 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1297 gids[num_groups] = id_map.xid.id;
1298 } else {
1299 DEBUG(1, (__location__
1300 "Group %s, of which %s is a member, could not be converted to a GID\n",
1301 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1302 ldb_dn_get_linearized(msg->dn)));
1303 talloc_free(tmp_ctx);
1304 /* We must error out, otherwise a user might
1305 * avoid a DENY acl based on a group they
1306 * missed out on */
1307 return NT_STATUS_NO_SUCH_GROUP;
1310 num_groups += 1;
1311 if (num_groups == count) {
1312 break;
1316 *pp_sids = talloc_steal(mem_ctx, group_sids);
1317 *pp_gids = talloc_steal(mem_ctx, gids);
1318 *p_num_groups = num_groups;
1319 talloc_free(tmp_ctx);
1320 return NT_STATUS_OK;
1323 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1324 TALLOC_CTX *mem_ctx,
1325 struct samu *user)
1327 return NT_STATUS_NOT_IMPLEMENTED;
1330 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1331 TALLOC_CTX *mem_ctx,
1332 const struct dom_sid *groupsid,
1333 const struct dom_sid *membersid,
1334 int mod_op)
1336 struct pdb_samba4_state *state = talloc_get_type_abort(
1337 m->private_data, struct pdb_samba4_state);
1338 struct ldb_message *msg;
1339 int ret;
1340 struct ldb_message_element *el;
1341 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1342 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1343 msg = ldb_msg_new(tmp_ctx);
1344 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1346 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1347 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1348 talloc_free(tmp_ctx);
1349 return NT_STATUS_NO_MEMORY;
1351 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1352 if (ret != LDB_SUCCESS) {
1353 talloc_free(tmp_ctx);
1354 return NT_STATUS_NO_MEMORY;
1356 el = ldb_msg_find_element(msg, "member");
1357 el->flags = mod_op;
1359 /* No need for transactions here, the ldb auto-transaction
1360 * code will handle things for the single operation */
1361 ret = ldb_modify(state->ldb, msg);
1362 talloc_free(tmp_ctx);
1363 if (ret != LDB_SUCCESS) {
1364 DEBUG(10, ("ldb_modify failed: %s\n",
1365 ldb_errstring(state->ldb)));
1366 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1367 return NT_STATUS_MEMBER_IN_GROUP;
1369 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1370 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1372 return NT_STATUS_LDAP(ret);
1375 return NT_STATUS_OK;
1378 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1379 TALLOC_CTX *mem_ctx,
1380 uint32 grouprid, uint32 memberrid,
1381 int mod_op)
1383 struct pdb_samba4_state *state = talloc_get_type_abort(
1384 m->private_data, struct pdb_samba4_state);
1385 const struct dom_sid *dom_sid, *groupsid, *membersid;
1386 NTSTATUS status;
1387 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1388 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1390 dom_sid = samdb_domain_sid(state->ldb);
1392 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1393 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1394 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1395 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1396 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1397 talloc_free(tmp_ctx);
1398 return status;
1401 static NTSTATUS pdb_samba4_add_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_ADD);
1409 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1410 TALLOC_CTX *mem_ctx,
1411 uint32 group_rid, uint32 member_rid)
1413 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1414 LDB_FLAG_MOD_DELETE);
1417 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1418 const char *name, uint32 *rid)
1420 TALLOC_CTX *frame = talloc_stackframe();
1421 struct pdb_samba4_state *state = talloc_get_type_abort(
1422 m->private_data, struct pdb_samba4_state);
1423 struct dom_sid *sid;
1425 struct ldb_dn *dn;
1426 NTSTATUS status;
1428 /* Internally this uses transactions to ensure all the steps
1429 * happen or fail as one */
1430 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1431 if (!NT_STATUS_IS_OK(status)) {
1432 TALLOC_FREE(frame);
1435 sid_peek_rid(sid, rid);
1436 TALLOC_FREE(frame);
1437 return NT_STATUS_OK;
1440 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1441 const struct dom_sid *sid)
1443 const char *attrs[] = { NULL };
1444 struct pdb_samba4_state *state = talloc_get_type_abort(
1445 m->private_data, struct pdb_samba4_state);
1446 struct ldb_message *msg;
1447 struct ldb_dn *dn;
1448 int rc;
1449 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1450 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1452 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1453 if (!dn || !ldb_dn_validate(dn)) {
1454 talloc_free(tmp_ctx);
1455 return NT_STATUS_NO_MEMORY;
1458 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1459 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1460 return NT_STATUS_INTERNAL_ERROR;
1463 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1464 "(|(grouptype=%d)(grouptype=%d)))",
1465 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1466 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1467 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1468 talloc_free(tmp_ctx);
1469 ldb_transaction_cancel(state->ldb);
1470 return NT_STATUS_NO_SUCH_ALIAS;
1472 rc = ldb_delete(state->ldb, dn);
1473 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1474 talloc_free(tmp_ctx);
1475 ldb_transaction_cancel(state->ldb);
1476 return NT_STATUS_NO_SUCH_ALIAS;
1477 } else if (rc != LDB_SUCCESS) {
1478 DEBUG(10, ("ldb_delete failed %s\n",
1479 ldb_errstring(state->ldb)));
1480 ldb_transaction_cancel(state->ldb);
1481 return NT_STATUS_LDAP(rc);
1484 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1485 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1486 ldb_errstring(state->ldb)));
1487 return NT_STATUS_INTERNAL_ERROR;
1490 return NT_STATUS_OK;
1493 #if 0
1494 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1495 const struct dom_sid *sid,
1496 struct acct_info *info)
1498 struct pdb_samba4_state *state = talloc_get_type_abort(
1499 m->private_data, struct pdb_samba4_state);
1500 struct tldap_context *ld;
1501 const char *attrs[3] = { "objectSid", "description",
1502 "samAccountName" };
1503 struct ldb_message **msg;
1504 char *sidstr, *dn;
1505 int rc;
1506 struct tldap_mod *mods;
1507 int num_mods;
1508 bool ok;
1510 ld = pdb_samba4_ld(state);
1511 if (ld == NULL) {
1512 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1515 sidstr = sid_binstring(talloc_tos(), sid);
1516 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1518 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1519 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1520 &msg, "(&(objectSid=%s)(objectclass=group)"
1521 "(|(grouptype=%d)(grouptype=%d)))",
1522 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1523 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1524 TALLOC_FREE(sidstr)
1525 if (rc != LDB_SUCCESS) {
1526 DEBUG(10, ("ldap_search failed %s\n",
1527 ldb_errstring(state->ldb)));
1528 return NT_STATUS_LDAP(rc);
1530 switch talloc_array_length(msg) {
1531 case 0:
1532 return NT_STATUS_NO_SUCH_ALIAS;
1533 case 1:
1534 break;
1535 default:
1536 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1539 if (!tldap_entry_dn(msg[0], &dn)) {
1540 TALLOC_FREE(msg);
1541 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1544 mods = NULL;
1545 num_mods = 0;
1546 ok = true;
1548 ok &= tldap_make_mod_fmt(
1549 msg[0], msg, &num_mods, &mods, "description",
1550 "%s", info->acct_desc);
1551 ok &= tldap_make_mod_fmt(
1552 msg[0], msg, &num_mods, &mods, "samAccountName",
1553 "%s", info->acct_name);
1554 if (!ok) {
1555 TALLOC_FREE(msg);
1556 return NT_STATUS_NO_MEMORY;
1558 if (num_mods == 0) {
1559 /* no change */
1560 TALLOC_FREE(msg);
1561 return NT_STATUS_OK;
1564 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1565 TALLOC_FREE(msg);
1566 if (rc != LDB_SUCCESS) {
1567 DEBUG(10, ("ldap_modify failed: %s\n",
1568 ldb_errstring(state->ldb)));
1569 return NT_STATUS_LDAP(rc);
1571 return NT_STATUS_OK;
1573 #endif
1574 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1575 const struct dom_sid *alias,
1576 const struct dom_sid *member)
1578 NTSTATUS status;
1579 TALLOC_CTX *frame = talloc_stackframe();
1580 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1581 talloc_free(frame);
1582 return status;
1585 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1586 const struct dom_sid *alias,
1587 const struct dom_sid *member)
1589 NTSTATUS status;
1590 TALLOC_CTX *frame = talloc_stackframe();
1591 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1592 talloc_free(frame);
1593 return status;
1596 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1597 const struct dom_sid *alias,
1598 TALLOC_CTX *mem_ctx,
1599 struct dom_sid **pmembers,
1600 size_t *pnum_members)
1602 struct pdb_samba4_state *state = talloc_get_type_abort(
1603 m->private_data, struct pdb_samba4_state);
1604 struct ldb_dn *dn;
1605 unsigned int num_members;
1606 NTSTATUS status;
1607 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1608 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1610 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1611 if (!dn || !ldb_dn_validate(dn)) {
1612 return NT_STATUS_NO_MEMORY;
1615 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1616 *pnum_members = num_members;
1617 if (NT_STATUS_IS_OK(status)) {
1618 talloc_steal(mem_ctx, pmembers);
1620 talloc_free(tmp_ctx);
1621 return status;
1624 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1625 TALLOC_CTX *mem_ctx,
1626 const struct dom_sid *domain_sid,
1627 const struct dom_sid *members,
1628 size_t num_members,
1629 uint32_t **palias_rids,
1630 size_t *pnum_alias_rids)
1632 struct pdb_samba4_state *state = talloc_get_type_abort(
1633 m->private_data, struct pdb_samba4_state);
1634 uint32_t *alias_rids = NULL;
1635 size_t num_alias_rids = 0;
1636 int i;
1637 struct dom_sid *groupSIDs = NULL;
1638 unsigned int num_groupSIDs = 0;
1639 char *filter;
1640 NTSTATUS status;
1641 const char *sid_string;
1642 const char *sid_dn;
1643 DATA_BLOB sid_blob;
1645 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1646 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1648 * TODO: Get the filter right so that we only get the aliases from
1649 * either the SAM or BUILTIN
1652 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1653 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1654 if (filter == NULL) {
1655 return NT_STATUS_NO_MEMORY;
1658 for (i = 0; i < num_members; i++) {
1659 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1660 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1662 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1663 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1665 sid_blob = data_blob_string_const(sid_dn);
1667 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1668 tmp_ctx, &groupSIDs, &num_groupSIDs);
1669 if (!NT_STATUS_IS_OK(status)) {
1670 talloc_free(tmp_ctx);
1671 return status;
1675 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1676 if (alias_rids == NULL) {
1677 talloc_free(tmp_ctx);
1678 return NT_STATUS_NO_MEMORY;
1681 for (i=0; i<num_groupSIDs; i++) {
1682 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1683 &alias_rids[num_alias_rids])) {
1684 num_alias_rids++;;
1688 *palias_rids = alias_rids;
1689 *pnum_alias_rids = num_alias_rids;
1690 return NT_STATUS_OK;
1693 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1694 const struct dom_sid *domain_sid,
1695 int num_rids,
1696 uint32 *rids,
1697 const char **names,
1698 enum lsa_SidType *lsa_attrs)
1700 struct pdb_samba4_state *state = talloc_get_type_abort(
1701 m->private_data, struct pdb_samba4_state);
1702 NTSTATUS status;
1704 TALLOC_CTX *tmp_ctx;
1706 if (num_rids == 0) {
1707 return NT_STATUS_NONE_MAPPED;
1710 tmp_ctx = talloc_stackframe();
1711 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1713 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1714 talloc_free(tmp_ctx);
1715 return status;
1718 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1719 const struct dom_sid *domain_sid,
1720 int num_names,
1721 const char **pp_names,
1722 uint32 *rids,
1723 enum lsa_SidType *attrs)
1725 return NT_STATUS_NOT_IMPLEMENTED;
1728 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1729 enum pdb_policy_type type,
1730 uint32_t *value)
1732 return account_policy_get(type, value)
1733 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1736 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1737 enum pdb_policy_type type,
1738 uint32_t value)
1740 return account_policy_set(type, value)
1741 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1744 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1745 time_t *seq_num_out)
1747 struct pdb_samba4_state *state = talloc_get_type_abort(
1748 m->private_data, struct pdb_samba4_state);
1749 uint64_t seq_num;
1750 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1751 if (ret == LDB_SUCCESS) {
1752 *seq_num_out = seq_num;
1753 return NT_STATUS_OK;
1754 } else {
1755 return NT_STATUS_UNSUCCESSFUL;
1759 struct pdb_samba4_search_state {
1760 uint32_t acct_flags;
1761 struct samr_displayentry *entries;
1762 uint32_t num_entries;
1763 ssize_t array_size;
1764 uint32_t current;
1767 static bool pdb_samba4_next_entry(struct pdb_search *search,
1768 struct samr_displayentry *entry)
1770 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1771 search->private_data, struct pdb_samba4_search_state);
1773 if (state->current == state->num_entries) {
1774 return false;
1777 entry->idx = state->entries[state->current].idx;
1778 entry->rid = state->entries[state->current].rid;
1779 entry->acct_flags = state->entries[state->current].acct_flags;
1781 entry->account_name = talloc_strdup(
1782 search, state->entries[state->current].account_name);
1783 entry->fullname = talloc_strdup(
1784 search, state->entries[state->current].fullname);
1785 entry->description = talloc_strdup(
1786 search, state->entries[state->current].description);
1788 state->current += 1;
1789 return true;
1792 static void pdb_samba4_search_end(struct pdb_search *search)
1794 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1795 search->private_data, struct pdb_samba4_search_state);
1796 talloc_free(state);
1799 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1800 struct pdb_search *search,
1801 struct pdb_samba4_search_state **pstate,
1802 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1804 struct pdb_samba4_state *state = talloc_get_type_abort(
1805 m->private_data, struct pdb_samba4_state);
1806 struct pdb_samba4_search_state *sstate;
1807 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1808 "userAccountControl", "description", NULL };
1809 struct ldb_result *res;
1810 int i, rc, num_users;
1812 va_list ap;
1813 char *expression = NULL;
1815 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1816 if (!tmp_ctx) {
1817 return false;
1820 va_start(ap, exp_fmt);
1821 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1822 va_end(ap);
1824 if (!expression) {
1825 talloc_free(tmp_ctx);
1826 return LDB_ERR_OPERATIONS_ERROR;
1829 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1830 if (sstate == NULL) {
1831 talloc_free(tmp_ctx);
1832 return false;
1835 rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1836 if (rc != LDB_SUCCESS) {
1837 talloc_free(tmp_ctx);
1838 DEBUG(10, ("dsdb_search failed: %s\n",
1839 ldb_errstring(state->ldb)));
1840 return false;
1843 num_users = res->count;
1845 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1846 num_users);
1847 if (sstate->entries == NULL) {
1848 talloc_free(tmp_ctx);
1849 DEBUG(10, ("talloc failed\n"));
1850 return false;
1853 sstate->num_entries = 0;
1855 for (i=0; i<num_users; i++) {
1856 struct samr_displayentry *e;
1857 struct dom_sid *sid;
1859 e = &sstate->entries[sstate->num_entries];
1861 e->idx = sstate->num_entries;
1862 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1863 if (!sid) {
1864 talloc_free(tmp_ctx);
1865 DEBUG(10, ("Could not pull SID\n"));
1866 return false;
1868 sid_peek_rid(sid, &e->rid);
1870 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1871 res->msgs[i],
1872 ldb_get_default_basedn(state->ldb));
1873 e->account_name = ldb_msg_find_attr_as_string(
1874 res->msgs[i], "samAccountName", NULL);
1875 if (e->account_name == NULL) {
1876 talloc_free(tmp_ctx);
1877 return false;
1879 e->fullname = ldb_msg_find_attr_as_string(
1880 res->msgs[i], "displayName", "");
1881 e->description = ldb_msg_find_attr_as_string(
1882 res->msgs[i], "description", "");
1884 sstate->num_entries += 1;
1885 if (sstate->num_entries >= num_users) {
1886 break;
1889 talloc_steal(sstate->entries, res->msgs);
1890 search->private_data = talloc_steal(search, sstate);
1891 search->next_entry = pdb_samba4_next_entry;
1892 search->search_end = pdb_samba4_search_end;
1893 *pstate = sstate;
1894 talloc_free(tmp_ctx);
1895 return true;
1898 static bool pdb_samba4_search_users(struct pdb_methods *m,
1899 struct pdb_search *search,
1900 uint32 acct_flags)
1902 struct pdb_samba4_search_state *sstate;
1903 bool ret;
1905 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1906 if (!ret) {
1907 return false;
1909 sstate->acct_flags = acct_flags;
1910 return true;
1913 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1914 struct pdb_search *search)
1916 struct pdb_samba4_search_state *sstate;
1917 bool ret;
1919 ret = pdb_samba4_search_filter(m, search, &sstate,
1920 "(&(grouptype=%d)(objectclass=group))",
1921 GTYPE_SECURITY_GLOBAL_GROUP);
1922 if (!ret) {
1923 return false;
1925 sstate->acct_flags = 0;
1926 return true;
1929 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1930 struct pdb_search *search,
1931 const struct dom_sid *sid)
1933 struct pdb_samba4_search_state *sstate;
1934 bool ret;
1936 ret = pdb_samba4_search_filter(m, search, &sstate,
1937 "(&(grouptype=%d)(objectclass=group))",
1938 sid_check_is_builtin(sid)
1939 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1940 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1941 if (!ret) {
1942 return false;
1944 sstate->acct_flags = 0;
1945 return true;
1948 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1949 struct dom_sid *sid)
1951 struct pdb_samba4_state *state = talloc_get_type_abort(
1952 m->private_data, struct pdb_samba4_state);
1953 NTSTATUS status;
1954 struct id_map id_map;
1955 struct id_map *id_maps[2];
1956 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1957 if (!tmp_ctx) {
1958 return false;
1961 id_map.xid.id = uid;
1962 id_map.xid.type = ID_TYPE_UID;
1963 id_maps[0] = &id_map;
1964 id_maps[1] = NULL;
1966 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1967 if (!NT_STATUS_IS_OK(status)) {
1968 talloc_free(tmp_ctx);
1969 return false;
1971 *sid = *id_map.sid;
1972 talloc_free(tmp_ctx);
1973 return true;
1976 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1977 struct dom_sid *sid)
1979 struct pdb_samba4_state *state = talloc_get_type_abort(
1980 m->private_data, struct pdb_samba4_state);
1981 NTSTATUS status;
1982 struct id_map id_map;
1983 struct id_map *id_maps[2];
1984 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1985 if (!tmp_ctx) {
1986 return false;
1989 id_map.xid.id = gid;
1990 id_map.xid.type = ID_TYPE_GID;
1991 id_maps[0] = &id_map;
1992 id_maps[1] = NULL;
1994 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1995 if (!NT_STATUS_IS_OK(status)) {
1996 return false;
1998 *sid = *id_map.sid;
1999 talloc_free(tmp_ctx);
2000 return true;
2003 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
2004 union unid_t *id, enum lsa_SidType *type)
2006 struct pdb_samba4_state *state = talloc_get_type_abort(
2007 m->private_data, struct pdb_samba4_state);
2008 struct id_map id_map;
2009 struct id_map *id_maps[2];
2010 const char *attrs[] = { "objectClass", "groupType", NULL };
2011 struct ldb_message *msg;
2012 struct ldb_dn *dn;
2013 NTSTATUS status;
2014 int rc;
2015 TALLOC_CTX *tmp_ctx = talloc_stackframe();
2016 if (!tmp_ctx) {
2017 return false;
2020 ZERO_STRUCT(id_map);
2022 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
2023 if (!dn || !ldb_dn_validate(dn)) {
2024 talloc_free(tmp_ctx);
2025 return false;
2027 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
2028 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
2029 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)));
2030 talloc_free(tmp_ctx);
2031 return false;
2033 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
2034 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
2035 switch (grouptype) {
2036 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
2037 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
2038 *type = SID_NAME_ALIAS;
2039 break;
2040 case GTYPE_SECURITY_GLOBAL_GROUP:
2041 *type = SID_NAME_DOM_GRP;
2042 break;
2043 default:
2044 talloc_free(tmp_ctx);
2045 DEBUG(10, ("Could not pull groupType\n"));
2046 return false;
2049 *type = SID_NAME_DOM_GRP;
2051 ZERO_STRUCT(id_map);
2052 id_map.sid = sid;
2053 id_maps[0] = &id_map;
2054 id_maps[1] = NULL;
2056 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2057 talloc_free(tmp_ctx);
2058 if (!NT_STATUS_IS_OK(status)) {
2059 return false;
2061 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
2062 id->gid = id_map.xid.id;
2063 return true;
2065 return false;
2066 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
2067 *type = SID_NAME_USER;
2068 ZERO_STRUCT(id_map);
2069 id_map.sid = sid;
2070 id_maps[0] = &id_map;
2071 id_maps[1] = NULL;
2073 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
2074 talloc_free(tmp_ctx);
2075 if (!NT_STATUS_IS_OK(status)) {
2076 return false;
2078 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
2079 id->uid = id_map.xid.id;
2080 return true;
2082 return false;
2084 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)));
2085 talloc_free(tmp_ctx);
2086 return false;
2089 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
2091 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
2094 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
2096 return false;
2099 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
2100 const char *domain, char** pwd,
2101 struct dom_sid *sid,
2102 time_t *pass_last_set_time)
2104 return false;
2107 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
2108 const char* domain, const char* pwd,
2109 const struct dom_sid *sid)
2111 return false;
2114 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
2115 const char *domain)
2117 return false;
2120 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
2121 TALLOC_CTX *mem_ctx,
2122 uint32 *num_domains,
2123 struct trustdom_info ***domains)
2125 *num_domains = 0;
2126 *domains = NULL;
2127 return NT_STATUS_OK;
2130 static void pdb_samba4_init_methods(struct pdb_methods *m)
2132 m->name = "samba4";
2133 m->get_domain_info = pdb_samba4_get_domain_info;
2134 m->getsampwnam = pdb_samba4_getsampwnam;
2135 m->getsampwsid = pdb_samba4_getsampwsid;
2136 m->create_user = pdb_samba4_create_user;
2137 m->delete_user = pdb_samba4_delete_user;
2138 m->add_sam_account = pdb_samba4_add_sam_account;
2139 m->update_sam_account = pdb_samba4_update_sam_account;
2140 m->delete_sam_account = pdb_samba4_delete_sam_account;
2141 m->rename_sam_account = pdb_samba4_rename_sam_account;
2142 m->update_login_attempts = pdb_samba4_update_login_attempts;
2143 m->getgrsid = pdb_samba4_getgrsid;
2144 m->getgrgid = pdb_samba4_getgrgid;
2145 m->getgrnam = pdb_samba4_getgrnam;
2146 m->create_dom_group = pdb_samba4_create_dom_group;
2147 m->delete_dom_group = pdb_samba4_delete_dom_group;
2148 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
2149 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
2150 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
2151 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
2152 m->enum_group_members = pdb_samba4_enum_group_members;
2153 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2154 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2155 m->add_groupmem = pdb_samba4_add_groupmem;
2156 m->del_groupmem = pdb_samba4_del_groupmem;
2157 m->create_alias = pdb_samba4_create_alias;
2158 m->delete_alias = pdb_samba4_delete_alias;
2159 m->get_aliasinfo = pdb_default_get_aliasinfo;
2160 m->add_aliasmem = pdb_samba4_add_aliasmem;
2161 m->del_aliasmem = pdb_samba4_del_aliasmem;
2162 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2163 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2164 m->lookup_rids = pdb_samba4_lookup_rids;
2165 m->lookup_names = pdb_samba4_lookup_names;
2166 m->get_account_policy = pdb_samba4_get_account_policy;
2167 m->set_account_policy = pdb_samba4_set_account_policy;
2168 m->get_seq_num = pdb_samba4_get_seq_num;
2169 m->search_users = pdb_samba4_search_users;
2170 m->search_groups = pdb_samba4_search_groups;
2171 m->search_aliases = pdb_samba4_search_aliases;
2172 m->uid_to_sid = pdb_samba4_uid_to_sid;
2173 m->gid_to_sid = pdb_samba4_gid_to_sid;
2174 m->sid_to_id = pdb_samba4_sid_to_id;
2175 m->capabilities = pdb_samba4_capabilities;
2176 m->new_rid = pdb_samba4_new_rid;
2177 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2178 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2179 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2180 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2183 static void free_private_data(void **vp)
2185 struct pdb_samba4_state *state = talloc_get_type_abort(
2186 *vp, struct pdb_samba4_state);
2187 talloc_unlink(state, state->ldb);
2188 return;
2191 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2192 const char *location)
2194 struct pdb_methods *m;
2195 struct pdb_samba4_state *state;
2196 NTSTATUS status;
2198 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2199 return status;
2202 state = talloc_zero(m, struct pdb_samba4_state);
2203 if (state == NULL) {
2204 goto nomem;
2206 m->private_data = state;
2207 m->free_private_data = free_private_data;
2208 pdb_samba4_init_methods(m);
2210 state->ev = s4_event_context_init(state);
2211 if (!state->ev) {
2212 DEBUG(0, ("s4_event_context_init failed\n"));
2213 goto nomem;
2216 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2217 if (state->lp_ctx == NULL) {
2218 DEBUG(0, ("loadparm_init_s3 failed\n"));
2219 goto nomem;
2222 if (location) {
2223 state->ldb = samdb_connect_url(state,
2224 state->ev,
2225 state->lp_ctx,
2226 system_session(state->lp_ctx),
2227 0, location);
2228 } else {
2229 state->ldb = samdb_connect(state,
2230 state->ev,
2231 state->lp_ctx,
2232 system_session(state->lp_ctx), 0);
2235 if (!state->ldb) {
2236 DEBUG(0, ("samdb_connect failed\n"));
2237 status = NT_STATUS_INTERNAL_ERROR;
2238 goto fail;
2241 state->idmap_ctx = idmap_init(state, state->ev,
2242 state->lp_ctx);
2243 if (!state->idmap_ctx) {
2244 DEBUG(0, ("idmap failed\n"));
2245 status = NT_STATUS_INTERNAL_ERROR;
2246 goto fail;
2249 *pdb_method = m;
2250 return NT_STATUS_OK;
2251 nomem:
2252 status = NT_STATUS_NO_MEMORY;
2253 fail:
2254 TALLOC_FREE(m);
2255 return status;
2258 NTSTATUS pdb_samba4_init(void);
2259 NTSTATUS pdb_samba4_init(void)
2261 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2262 pdb_init_samba4);