s3-utils/net_rpc_printer.c: print more info on write error
[Samba/gebeck_regimport.git] / source3 / passdb / pdb_samba4.c
blob5848c23de8e1dd8eea79cbc2e1beffe0c6eb7d90
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"
37 struct pdb_samba4_state {
38 struct tevent_context *ev;
39 struct ldb_context *ldb;
40 struct idmap_context *idmap_ctx;
41 struct loadparm_context *lp_ctx;
44 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
45 struct samu *sam_acct,
46 const struct dom_sid *sid);
47 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
48 const char *filter,
49 TALLOC_CTX *mem_ctx,
50 struct ldb_message **pmsg);
51 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
52 union unid_t *id, enum lsa_SidType *type);
54 static bool pdb_samba4_pull_time(struct ldb_message *msg, const char *attr,
55 time_t *ptime)
57 uint64_t tmp;
58 if (! ldb_msg_find_element(msg, attr)) {
59 return false;
61 tmp = ldb_msg_find_attr_as_uint64(msg, attr, 0);
62 *ptime = uint64s_nt_time_to_unix_abs(&tmp);
63 return true;
66 static struct pdb_domain_info *pdb_samba4_get_domain_info(
67 struct pdb_methods *m, TALLOC_CTX *mem_ctx)
69 struct pdb_samba4_state *state = talloc_get_type_abort(
70 m->private_data, struct pdb_samba4_state);
71 struct pdb_domain_info *info;
72 struct dom_sid *domain_sid;
73 struct ldb_dn *forest_dn, *domain_dn;
74 struct ldb_result *dom_res = NULL;
75 const char *dom_attrs[] = {
76 "objectSid",
77 "objectGUID",
78 "nTMixedDomain",
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 /* Like in pdb_ldap(), this will need to be a function pointer when we
332 * start to support 'adds' for migrations from samba3 passdb backends
333 * to samba4 */
334 static bool update_required(struct samu *sam, enum pdb_elements element)
336 return (IS_SAM_CHANGED(sam, element));
339 static bool pdb_samba4_init_samba4_from_sam(struct pdb_samba4_state *state,
340 struct ldb_message *existing,
341 TALLOC_CTX *mem_ctx,
342 struct ldb_message **pmods,
343 struct samu *sam)
345 int ret = LDB_SUCCESS;
346 const char *pw;
347 struct ldb_message *msg;
349 /* TODO: All fields :-) */
351 msg = ldb_msg_new(mem_ctx);
352 if (!msg) {
353 return false;
356 msg->dn = existing->dn;
358 pw = pdb_get_plaintext_passwd(sam);
359 if (update_required(sam, PDB_PLAINTEXT_PW)) {
360 if (pw == NULL) {
361 ret = LDB_ERR_OPERATIONS_ERROR;
362 goto fail;
365 ret |= ldb_msg_add_string(msg, "clearTextPassword", pw);
368 if (update_required(sam, PDB_FULLNAME)) {
369 ret |= ldb_msg_add_string(msg, "displayName", pdb_get_fullname(sam));
372 if (update_required(sam, PDB_SMBHOME)) {
373 ret |= ldb_msg_add_string(msg, "homeDirectory",
374 pdb_get_homedir(sam));
377 if (update_required(sam, PDB_PROFILE)) {
378 ret |= ldb_msg_add_string(msg, "profilePath",
379 pdb_get_profile_path(sam));
382 if (update_required(sam, PDB_DRIVE)) {
383 ret |= ldb_msg_add_string(msg, "homeDrive",
384 pdb_get_dir_drive(sam));
387 if (update_required(sam, PDB_LOGONSCRIPT)) {
388 ret |= ldb_msg_add_string(msg, "scriptPath",
389 pdb_get_logon_script(sam));
392 if (update_required(sam, PDB_KICKOFFTIME)) {
393 ret |= pdb_samba4_add_time(msg, "accountExpires",
394 pdb_get_kickoff_time(sam));
397 if (update_required(sam, PDB_USERNAME)) {
398 ret |= ldb_msg_add_string(msg, "samAccountName",
399 pdb_get_username(sam));
402 if (update_required(sam, PDB_HOURSLEN) || update_required(sam, PDB_HOURS)) {
403 struct ldb_val hours = data_blob_const(pdb_get_hours(sam), pdb_get_hours_len(sam));
404 ret |= ldb_msg_add_value(msg, "logonHours",
405 &hours, NULL);
408 if (update_required(sam, PDB_ACCTCTRL)) {
409 ret |= ldb_msg_add_fmt(msg, "userAccountControl",
410 "%d", ds_acb2uf(pdb_get_acct_ctrl(sam)));
413 if (update_required(sam, PDB_COMMENT)) {
414 ret |= ldb_msg_add_string(msg, "comment",
415 pdb_get_comment(sam));
418 if (update_required(sam, PDB_ACCTDESC)) {
419 ret |= ldb_msg_add_string(msg, "description",
420 pdb_get_acct_desc(sam));
423 if (update_required(sam, PDB_WORKSTATIONS)) {
424 ret |= ldb_msg_add_string(msg, "userWorkstations",
425 pdb_get_workstations(sam));
428 /* This will need work, it is actually a UTF8 'string' with internal NULLs, to handle TS parameters */
429 if (update_required(sam, PDB_MUNGEDDIAL)) {
430 ret |= ldb_msg_add_string(msg, "userParameters",
431 pdb_get_munged_dial(sam));
434 if (update_required(sam, PDB_COUNTRY_CODE)) {
435 ret |= ldb_msg_add_fmt(msg, "countryCode",
436 "%i", (int)pdb_get_country_code(sam));
439 if (update_required(sam, PDB_CODE_PAGE)) {
440 ret |= ldb_msg_add_fmt(msg, "codePage",
441 "%i", (int)pdb_get_code_page(sam));
444 /* Not yet handled here or not meaningful for modifies on a Samba4 backend:
445 PDB_LOGONTIME,
446 PDB_LOGOFFTIME,
447 PDB_BAD_PASSWORD_TIME,
448 PDB_CANCHANGETIME,
449 PDB_MUSTCHANGETIME,
450 PDB_DOMAIN,
451 PDB_NTUSERNAME,
452 PDB_LOGONDIVS,
453 PDB_USERSID,
454 PDB_GROUPSID,
455 PDB_PASSLASTSET,
456 PDB_FIELDS_PRESENT,
457 PDB_BAD_PASSWORD_COUNT,
458 PDB_LOGON_COUNT,
459 PDB_UNKNOWN6,
460 PDB_LMPASSWD,
461 PDB_NTPASSWD,
462 PDB_PWHISTORY,
463 PDB_BACKEND_PRIVATE_DATA,
467 *pmods = msg;
468 fail:
469 return ret == LDB_SUCCESS;
472 static NTSTATUS pdb_samba4_getsamupriv(struct pdb_samba4_state *state,
473 const char *filter,
474 TALLOC_CTX *mem_ctx,
475 struct ldb_message **msg)
477 const char * attrs[] = {
478 "lastLogon", "lastLogoff", "pwdLastSet", "accountExpires",
479 "sAMAccountName", "displayName", "homeDirectory",
480 "homeDrive", "scriptPath", "profilePath", "description",
481 "userWorkstations", "comment", "userParameters", "objectSid",
482 "primaryGroupID", "userAccountControl", "logonHours",
483 "badPwdCount", "logonCount", "countryCode", "codePage",
484 "unicodePwd", "dBCSPwd", NULL };
486 int rc = dsdb_search_one(state->ldb, mem_ctx, msg, NULL, LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
487 if (rc != LDB_SUCCESS) {
488 DEBUG(10, ("ldap_search failed %s\n",
489 ldb_errstring(state->ldb)));
490 return NT_STATUS_LDAP(rc);
493 return NT_STATUS_OK;
496 static NTSTATUS pdb_samba4_getsampwfilter(struct pdb_methods *m,
497 struct pdb_samba4_state *state,
498 struct samu *sam_acct,
499 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
501 struct ldb_message *priv;
502 NTSTATUS status;
503 va_list ap;
504 char *expression = NULL;
505 TALLOC_CTX *tmp_ctx = talloc_new(state);
506 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
508 va_start(ap, exp_fmt);
509 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
510 va_end(ap);
512 if (!expression) {
513 talloc_free(tmp_ctx);
514 return NT_STATUS_NO_MEMORY;
517 status = pdb_samba4_getsamupriv(state, expression, sam_acct, &priv);
518 talloc_free(tmp_ctx);
519 if (!NT_STATUS_IS_OK(status)) {
520 DEBUG(10, ("pdb_samba4_getsamupriv failed: %s\n",
521 nt_errstr(status)));
522 return status;
525 status = pdb_samba4_init_sam_from_priv(m, sam_acct, priv);
526 if (!NT_STATUS_IS_OK(status)) {
527 DEBUG(10, ("pdb_samba4_init_sam_from_priv failed: %s\n",
528 nt_errstr(status)));
529 TALLOC_FREE(priv);
530 return status;
533 pdb_set_backend_private_data(sam_acct, priv, NULL, m, PDB_SET);
534 return NT_STATUS_OK;
537 static NTSTATUS pdb_samba4_getsampwnam(struct pdb_methods *m,
538 struct samu *sam_acct,
539 const char *username)
541 struct pdb_samba4_state *state = talloc_get_type_abort(
542 m->private_data, struct pdb_samba4_state);
544 return pdb_samba4_getsampwfilter(m, state, sam_acct,
545 "(&(samaccountname=%s)(objectclass=user))",
546 username);
549 static NTSTATUS pdb_samba4_getsampwsid(struct pdb_methods *m,
550 struct samu *sam_acct,
551 const struct dom_sid *sid)
553 NTSTATUS status;
554 struct pdb_samba4_state *state = talloc_get_type_abort(
555 m->private_data, struct pdb_samba4_state);
556 char *sidstr;
558 sidstr = dom_sid_string(talloc_tos(), sid);
559 NT_STATUS_HAVE_NO_MEMORY(sidstr);
561 status = pdb_samba4_getsampwfilter(m, state, sam_acct,
562 "(&(objectsid=%s)(objectclass=user))",
563 sidstr);
564 talloc_free(sidstr);
565 return status;
568 static NTSTATUS pdb_samba4_create_user(struct pdb_methods *m,
569 TALLOC_CTX *mem_ctx,
570 const char *name, uint32 acct_flags,
571 uint32 *rid)
573 struct pdb_samba4_state *state = talloc_get_type_abort(
574 m->private_data, struct pdb_samba4_state);
575 struct dom_sid *sid;
576 struct ldb_dn *dn;
577 NTSTATUS status;
578 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
579 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
581 /* Internally this uses transactions to ensure all the steps
582 * happen or fail as one */
583 status = dsdb_add_user(state->ldb, tmp_ctx, name, acct_flags, &sid, &dn);
584 if (!NT_STATUS_IS_OK(status)) {
585 talloc_free(tmp_ctx);
586 return status;
588 sid_peek_rid(sid, rid);
589 talloc_free(tmp_ctx);
590 return NT_STATUS_OK;
593 static NTSTATUS pdb_samba4_delete_user(struct pdb_methods *m,
594 TALLOC_CTX *mem_ctx,
595 struct samu *sam)
597 struct pdb_samba4_state *state = talloc_get_type_abort(
598 m->private_data, struct pdb_samba4_state);
599 struct ldb_dn *dn;
600 int rc;
601 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
602 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
604 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, pdb_get_user_sid(sam)));
605 if (!dn || !ldb_dn_validate(dn)) {
606 talloc_free(tmp_ctx);
607 return NT_STATUS_NO_MEMORY;
609 rc = ldb_delete(state->ldb, dn);
611 if (rc != LDB_SUCCESS) {
612 DEBUG(10, ("ldb_delete for %s failed: %s\n", ldb_dn_get_linearized(dn),
613 ldb_errstring(state->ldb)));
614 talloc_free(tmp_ctx);
615 return NT_STATUS_LDAP(rc);
617 talloc_free(tmp_ctx);
618 return NT_STATUS_OK;
621 /* This interface takes a fully populated struct samu and places it in
622 * the database. This is not implemented at this time as we need to
623 * be careful around the creation of arbitary SIDs (ie, we must ensrue
624 * they are not left in a RID pool */
625 static NTSTATUS pdb_samba4_add_sam_account(struct pdb_methods *m,
626 struct samu *sampass)
628 return NT_STATUS_NOT_IMPLEMENTED;
632 * Update the Samba4 LDB with the changes from a struct samu.
634 * This takes care not to update elements that have not been changed
635 * by the caller
637 static NTSTATUS pdb_samba4_update_sam_account(struct pdb_methods *m,
638 struct samu *sam)
640 struct pdb_samba4_state *state = talloc_get_type_abort(
641 m->private_data, struct pdb_samba4_state);
642 struct ldb_message *msg = pdb_samba4_get_samu_private(
643 m, sam);
644 struct ldb_message *replace_msg;
645 int rc;
647 if (!pdb_samba4_init_samba4_from_sam(state, msg, talloc_tos(),
648 &replace_msg, sam)) {
649 return NT_STATUS_NO_MEMORY;
652 if (replace_msg->num_elements == 0) {
653 /* Nothing to do, just return success */
654 return NT_STATUS_OK;
657 rc = dsdb_replace(state->ldb, replace_msg, 0);
658 TALLOC_FREE(replace_msg);
659 if (rc != LDB_SUCCESS) {
660 DEBUG(10, ("dsdb_replace for %s failed: %s\n", ldb_dn_get_linearized(replace_msg->dn),
661 ldb_errstring(state->ldb)));
662 return NT_STATUS_LDAP(rc);
665 return NT_STATUS_OK;
668 static NTSTATUS pdb_samba4_delete_sam_account(struct pdb_methods *m,
669 struct samu *username)
671 NTSTATUS status;
672 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
673 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
674 status = pdb_samba4_delete_user(m, tmp_ctx, username);
675 talloc_free(tmp_ctx);
676 return status;
679 static NTSTATUS pdb_samba4_rename_sam_account(struct pdb_methods *m,
680 struct samu *oldname,
681 const char *newname)
683 return NT_STATUS_NOT_IMPLEMENTED;
686 /* This is not implemented, as this module is exptected to be used
687 * with auth_samba4, and this is responible for login counters etc
690 static NTSTATUS pdb_samba4_update_login_attempts(struct pdb_methods *m,
691 struct samu *sam_acct,
692 bool success)
694 return NT_STATUS_NOT_IMPLEMENTED;
697 static NTSTATUS pdb_samba4_getgrfilter(struct pdb_methods *m, GROUP_MAP *map,
698 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
700 struct pdb_samba4_state *state = talloc_get_type_abort(
701 m->private_data, struct pdb_samba4_state);
702 const char *attrs[] = { "objectSid", "description", "samAccountName",
703 NULL };
704 struct ldb_message *msg;
705 va_list ap;
706 char *expression = NULL;
707 struct dom_sid *sid;
708 const char *str;
709 int rc;
710 union unid_t id;
711 TALLOC_CTX *tmp_ctx = talloc_stackframe();
712 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
714 va_start(ap, exp_fmt);
715 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
716 va_end(ap);
718 if (!expression) {
719 talloc_free(tmp_ctx);
720 return NT_STATUS_NO_MEMORY;
723 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, NULL, LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
724 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
725 talloc_free(tmp_ctx);
726 return NT_STATUS_NO_SUCH_GROUP;
727 } else if (rc != LDB_SUCCESS) {
728 talloc_free(tmp_ctx);
729 DEBUG(10, ("dsdb_search_one failed %s\n",
730 ldb_errstring(state->ldb)));
731 return NT_STATUS_LDAP(rc);
734 sid = samdb_result_dom_sid(tmp_ctx, msg, "objectSid");
735 if (!sid) {
736 talloc_free(tmp_ctx);
737 DEBUG(10, ("Could not pull SID\n"));
738 return NT_STATUS_INTERNAL_DB_CORRUPTION;
741 map->sid = *sid;
743 if (!pdb_samba4_sid_to_id(m, sid, &id, &map->sid_name_use)) {
744 talloc_free(tmp_ctx);
745 return NT_STATUS_NO_SUCH_GROUP;
747 if (map->sid_name_use == SID_NAME_USER) {
748 DEBUG(1, (__location__ "Got SID_NAME_USER when searching for a group with %s", expression));
749 return NT_STATUS_INTERNAL_DB_CORRUPTION;
751 map->gid = id.gid;
753 str = ldb_msg_find_attr_as_string(msg, "samAccountName",
754 NULL);
755 if (str == NULL) {
756 talloc_free(tmp_ctx);
757 return NT_STATUS_INTERNAL_DB_CORRUPTION;
759 fstrcpy(map->nt_name, str);
761 str = ldb_msg_find_attr_as_string(msg, "description",
762 NULL);
763 if (str != NULL) {
764 fstrcpy(map->comment, str);
765 } else {
766 map->comment[0] = '\0';
769 talloc_free(tmp_ctx);
770 return NT_STATUS_OK;
773 static NTSTATUS pdb_samba4_getgrsid(struct pdb_methods *m, GROUP_MAP *map,
774 struct dom_sid sid)
776 char *filter;
777 NTSTATUS status;
779 filter = talloc_asprintf(talloc_tos(),
780 "(&(objectsid=%s)(objectclass=group))",
781 sid_string_talloc(talloc_tos(), &sid));
782 if (filter == NULL) {
783 return NT_STATUS_NO_MEMORY;
786 status = pdb_samba4_getgrfilter(m, map, filter);
787 TALLOC_FREE(filter);
788 return status;
791 static NTSTATUS pdb_samba4_getgrgid(struct pdb_methods *m, GROUP_MAP *map,
792 gid_t gid)
794 struct pdb_samba4_state *state = talloc_get_type_abort(
795 m->private_data, struct pdb_samba4_state);
796 NTSTATUS status;
797 struct id_map id_map;
798 struct id_map *id_maps[2];
799 TALLOC_CTX *tmp_ctx = talloc_stackframe();
800 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
802 id_map.xid.id = gid;
803 id_map.xid.type = ID_TYPE_GID;
804 id_maps[0] = &id_map;
805 id_maps[1] = NULL;
807 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
808 if (!NT_STATUS_IS_OK(status)) {
809 return status;
811 status = pdb_samba4_getgrsid(m, map, *id_map.sid);
812 talloc_free(tmp_ctx);
813 return status;
816 static NTSTATUS pdb_samba4_getgrnam(struct pdb_methods *m, GROUP_MAP *map,
817 const char *name)
819 char *filter;
820 NTSTATUS status;
822 filter = talloc_asprintf(talloc_tos(),
823 "(&(samaccountname=%s)(objectclass=group))",
824 name);
825 if (filter == NULL) {
826 return NT_STATUS_NO_MEMORY;
829 status = pdb_samba4_getgrfilter(m, map, filter);
830 TALLOC_FREE(filter);
831 return status;
834 static NTSTATUS pdb_samba4_create_dom_group(struct pdb_methods *m,
835 TALLOC_CTX *mem_ctx, const char *name,
836 uint32 *rid)
838 struct pdb_samba4_state *state = talloc_get_type_abort(
839 m->private_data, struct pdb_samba4_state);
840 NTSTATUS status;
841 struct dom_sid *sid;
842 struct ldb_dn *dn;
843 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
844 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
846 status = dsdb_add_domain_group(state->ldb, tmp_ctx, name, &sid, &dn);
847 if (!NT_STATUS_IS_OK(status)) {
848 talloc_free(tmp_ctx);
849 return status;
852 sid_peek_rid(sid, rid);
853 talloc_free(tmp_ctx);
854 return NT_STATUS_OK;
857 static NTSTATUS pdb_samba4_delete_dom_group(struct pdb_methods *m,
858 TALLOC_CTX *mem_ctx, uint32 rid)
860 const char *attrs[] = { NULL };
861 struct pdb_samba4_state *state = talloc_get_type_abort(
862 m->private_data, struct pdb_samba4_state);
863 struct dom_sid sid;
864 struct ldb_message *msg;
865 struct ldb_dn *dn;
866 int rc;
867 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
868 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
870 sid_compose(&sid, samdb_domain_sid(state->ldb), rid);
872 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
873 DEBUG(0, ("Unable to start transaction in pdb_samba4_delete_dom_group()\n"));
874 return NT_STATUS_INTERNAL_ERROR;
877 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, &sid));
878 if (!dn || !ldb_dn_validate(dn)) {
879 talloc_free(tmp_ctx);
880 ldb_transaction_cancel(state->ldb);
881 return NT_STATUS_NO_MEMORY;
883 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "objectclass=group");
884 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
885 talloc_free(tmp_ctx);
886 ldb_transaction_cancel(state->ldb);
887 return NT_STATUS_NO_SUCH_GROUP;
889 rc = ldb_delete(state->ldb, dn);
890 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
891 talloc_free(tmp_ctx);
892 ldb_transaction_cancel(state->ldb);
893 return NT_STATUS_NO_SUCH_GROUP;
894 } else if (rc != LDB_SUCCESS) {
895 DEBUG(10, ("ldb_delete failed %s\n",
896 ldb_errstring(state->ldb)));
897 ldb_transaction_cancel(state->ldb);
898 return NT_STATUS_LDAP(rc);
901 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
902 DEBUG(0, ("Unable to commit transaction in pdb_samba4_delete_dom_group()\n"));
903 return NT_STATUS_INTERNAL_ERROR;
905 return NT_STATUS_OK;
908 static NTSTATUS pdb_samba4_add_group_mapping_entry(struct pdb_methods *m,
909 GROUP_MAP *map)
911 return NT_STATUS_NOT_IMPLEMENTED;
914 static NTSTATUS pdb_samba4_update_group_mapping_entry(struct pdb_methods *m,
915 GROUP_MAP *map)
917 return NT_STATUS_NOT_IMPLEMENTED;
920 static NTSTATUS pdb_samba4_delete_group_mapping_entry(struct pdb_methods *m,
921 struct dom_sid sid)
923 return NT_STATUS_NOT_IMPLEMENTED;
926 static NTSTATUS pdb_samba4_enum_group_mapping(struct pdb_methods *m,
927 const struct dom_sid *sid,
928 enum lsa_SidType sid_name_use,
929 GROUP_MAP **pp_rmap,
930 size_t *p_num_entries,
931 bool unix_only)
933 return NT_STATUS_NOT_IMPLEMENTED;
936 static NTSTATUS pdb_samba4_enum_group_members(struct pdb_methods *m,
937 TALLOC_CTX *mem_ctx,
938 const struct dom_sid *group,
939 uint32_t **pmembers,
940 size_t *pnum_members)
942 unsigned int i, num_sids, num_members;
943 struct pdb_samba4_state *state = talloc_get_type_abort(
944 m->private_data, struct pdb_samba4_state);
945 struct dom_sid *members_as_sids;
946 struct dom_sid *dom_sid;
947 uint32_t *members;
948 struct ldb_dn *dn;
949 NTSTATUS status;
951 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
952 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
954 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, group));
955 if (!dn || !ldb_dn_validate(dn)) {
956 return NT_STATUS_NO_MEMORY;
959 status = dsdb_enum_group_mem(state->ldb, tmp_ctx, dn, &members_as_sids, &num_sids);
960 if (!NT_STATUS_IS_OK(status)) {
961 talloc_free(tmp_ctx);
962 return status;
964 status = dom_sid_split_rid(tmp_ctx, group, &dom_sid, NULL);
965 if (!NT_STATUS_IS_OK(status)) {
966 talloc_free(tmp_ctx);
967 return status;
970 *pmembers = members = talloc_array(mem_ctx, uint32_t, num_sids);
971 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(*pmembers, tmp_ctx);
972 num_members = 0;
974 for (i = 0; i < num_sids; i++) {
975 if (!dom_sid_in_domain(dom_sid, &members_as_sids[i])) {
976 continue;
978 status = dom_sid_split_rid(NULL, &members_as_sids[i],
979 NULL, &members[num_members]);
980 if (!NT_STATUS_IS_OK(status)) {
981 talloc_free(tmp_ctx);
982 return status;
984 num_members++;
986 *pnum_members = num_members;
987 return NT_STATUS_OK;
990 /* Just convert the primary group SID into a group */
991 static NTSTATUS fake_enum_group_memberships(struct pdb_samba4_state *state,
992 TALLOC_CTX *mem_ctx,
993 struct samu *user,
994 struct dom_sid **pp_sids,
995 gid_t **pp_gids,
996 uint32_t *p_num_groups)
998 NTSTATUS status;
999 size_t num_groups = 0;
1000 struct dom_sid *group_sids;
1001 gid_t *gids;
1002 TALLOC_CTX *tmp_ctx;
1004 tmp_ctx = talloc_new(mem_ctx);
1005 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1007 if (user->group_sid) {
1008 struct id_map *id_maps[2];
1009 struct id_map id_map;
1011 num_groups = 1;
1013 group_sids = talloc_array(tmp_ctx, struct dom_sid, num_groups);
1014 if (group_sids == NULL) {
1015 talloc_free(tmp_ctx);
1016 return NT_STATUS_NO_MEMORY;
1018 gids = talloc_array(tmp_ctx, gid_t, num_groups);
1019 if (gids == NULL) {
1020 talloc_free(tmp_ctx);
1021 return NT_STATUS_NO_MEMORY;
1024 group_sids[0] = *user->group_sid;
1026 ZERO_STRUCT(id_map);
1027 id_map.sid = &group_sids[0];
1028 id_maps[0] = &id_map;
1029 id_maps[1] = NULL;
1031 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1032 if (!NT_STATUS_IS_OK(status)) {
1033 talloc_free(tmp_ctx);
1034 return status;
1036 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1037 gids[0] = id_map.xid.id;
1038 } else {
1039 DEBUG(1, (__location__
1040 "Group %s, of which %s is a member, could not be converted to a GID\n",
1041 dom_sid_string(tmp_ctx, &group_sids[0]),
1042 dom_sid_string(tmp_ctx, &user->user_sid)));
1043 talloc_free(tmp_ctx);
1044 /* We must error out, otherwise a user might
1045 * avoid a DENY acl based on a group they
1046 * missed out on */
1047 return NT_STATUS_NO_SUCH_GROUP;
1051 *pp_sids = talloc_steal(mem_ctx, group_sids);
1052 *pp_gids = talloc_steal(mem_ctx, gids);
1053 *p_num_groups = num_groups;
1054 talloc_free(tmp_ctx);
1055 return NT_STATUS_OK;
1058 static NTSTATUS pdb_samba4_enum_group_memberships(struct pdb_methods *m,
1059 TALLOC_CTX *mem_ctx,
1060 struct samu *user,
1061 struct dom_sid **pp_sids,
1062 gid_t **pp_gids,
1063 uint32_t *p_num_groups)
1065 struct pdb_samba4_state *state = talloc_get_type_abort(
1066 m->private_data, struct pdb_samba4_state);
1067 struct ldb_message *msg = pdb_samba4_get_samu_private(
1068 m, user);
1069 const char *attrs[] = { "tokenGroups", NULL};
1070 struct ldb_message *tokengroups_msg;
1071 struct ldb_message_element *tokengroups;
1072 int i, rc;
1073 NTSTATUS status;
1074 unsigned int count = 0;
1075 size_t num_groups;
1076 struct dom_sid *group_sids;
1077 gid_t *gids;
1078 TALLOC_CTX *tmp_ctx;
1080 if (msg == NULL) {
1081 /* Fake up some things here */
1082 return fake_enum_group_memberships(state,
1083 mem_ctx,
1084 user, pp_sids,
1085 pp_gids, p_num_groups);
1088 tmp_ctx = talloc_new(mem_ctx);
1089 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1091 rc = dsdb_search_one(state->ldb, tmp_ctx, &tokengroups_msg, msg->dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1093 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1094 talloc_free(tmp_ctx);
1095 return NT_STATUS_NO_SUCH_USER;
1096 } else if (rc != LDB_SUCCESS) {
1097 DEBUG(10, ("dsdb_search_one failed %s\n",
1098 ldb_errstring(state->ldb)));
1099 talloc_free(tmp_ctx);
1100 return NT_STATUS_LDAP(rc);
1103 tokengroups = ldb_msg_find_element(tokengroups_msg, "tokenGroups");
1105 if (tokengroups) {
1106 count = tokengroups->num_values;
1109 group_sids = talloc_array(tmp_ctx, struct dom_sid, count);
1110 if (group_sids == NULL) {
1111 talloc_free(tmp_ctx);
1112 return NT_STATUS_NO_MEMORY;
1114 gids = talloc_array(tmp_ctx, gid_t, count);
1115 if (gids == NULL) {
1116 talloc_free(tmp_ctx);
1117 return NT_STATUS_NO_MEMORY;
1119 num_groups = 0;
1121 for (i=0; i<count; i++) {
1122 struct id_map *id_maps[2];
1123 struct id_map id_map;
1124 struct ldb_val *v = &tokengroups->values[i];
1125 enum ndr_err_code ndr_err
1126 = ndr_pull_struct_blob(v, group_sids, &group_sids[num_groups],
1127 (ndr_pull_flags_fn_t)ndr_pull_dom_sid);
1128 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1129 talloc_free(tmp_ctx);
1130 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1133 ZERO_STRUCT(id_map);
1134 id_map.sid = &group_sids[num_groups];
1135 id_maps[0] = &id_map;
1136 id_maps[1] = NULL;
1138 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1139 if (!NT_STATUS_IS_OK(status)) {
1140 talloc_free(tmp_ctx);
1141 return status;
1143 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1144 gids[num_groups] = id_map.xid.id;
1145 } else {
1146 DEBUG(1, (__location__
1147 "Group %s, of which %s is a member, could not be converted to a GID\n",
1148 dom_sid_string(tmp_ctx, &group_sids[num_groups]),
1149 ldb_dn_get_linearized(msg->dn)));
1150 talloc_free(tmp_ctx);
1151 /* We must error out, otherwise a user might
1152 * avoid a DENY acl based on a group they
1153 * missed out on */
1154 return NT_STATUS_NO_SUCH_GROUP;
1157 num_groups += 1;
1158 if (num_groups == count) {
1159 break;
1163 *pp_sids = talloc_steal(mem_ctx, group_sids);
1164 *pp_gids = talloc_steal(mem_ctx, gids);
1165 *p_num_groups = num_groups;
1166 talloc_free(tmp_ctx);
1167 return NT_STATUS_OK;
1170 static NTSTATUS pdb_samba4_set_unix_primary_group(struct pdb_methods *m,
1171 TALLOC_CTX *mem_ctx,
1172 struct samu *user)
1174 return NT_STATUS_NOT_IMPLEMENTED;
1177 static NTSTATUS pdb_samba4_mod_groupmem_by_sid(struct pdb_methods *m,
1178 TALLOC_CTX *mem_ctx,
1179 const struct dom_sid *groupsid,
1180 const struct dom_sid *membersid,
1181 int mod_op)
1183 struct pdb_samba4_state *state = talloc_get_type_abort(
1184 m->private_data, struct pdb_samba4_state);
1185 struct ldb_message *msg;
1186 int ret;
1187 struct ldb_message_element *el;
1188 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1189 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1190 msg = ldb_msg_new(tmp_ctx);
1191 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg, tmp_ctx);
1193 msg->dn = ldb_dn_new_fmt(msg, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, groupsid));
1194 if (!msg->dn || !ldb_dn_validate(msg->dn)) {
1195 talloc_free(tmp_ctx);
1196 return NT_STATUS_NO_MEMORY;
1198 ret = ldb_msg_add_fmt(msg, "member", "<SID=%s>", dom_sid_string(tmp_ctx, membersid));
1199 if (ret != LDB_SUCCESS) {
1200 talloc_free(tmp_ctx);
1201 return NT_STATUS_NO_MEMORY;
1203 el = ldb_msg_find_element(msg, "member");
1204 el->flags = mod_op;
1206 /* No need for transactions here, the ldb auto-transaction
1207 * code will handle things for the single operation */
1208 ret = ldb_modify(state->ldb, msg);
1209 talloc_free(tmp_ctx);
1210 if (ret != LDB_SUCCESS) {
1211 DEBUG(10, ("ldb_modify failed: %s\n",
1212 ldb_errstring(state->ldb)));
1213 if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
1214 return NT_STATUS_MEMBER_IN_GROUP;
1216 if (ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
1217 return NT_STATUS_MEMBER_NOT_IN_GROUP;
1219 return NT_STATUS_LDAP(ret);
1222 return NT_STATUS_OK;
1225 static NTSTATUS pdb_samba4_mod_groupmem(struct pdb_methods *m,
1226 TALLOC_CTX *mem_ctx,
1227 uint32 grouprid, uint32 memberrid,
1228 int mod_op)
1230 struct pdb_samba4_state *state = talloc_get_type_abort(
1231 m->private_data, struct pdb_samba4_state);
1232 const struct dom_sid *dom_sid, *groupsid, *membersid;
1233 NTSTATUS status;
1234 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1235 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1237 dom_sid = samdb_domain_sid(state->ldb);
1239 groupsid = dom_sid_add_rid(tmp_ctx, dom_sid, grouprid);
1240 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(groupsid, tmp_ctx);
1241 membersid = dom_sid_add_rid(tmp_ctx, dom_sid, memberrid);
1242 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(membersid, tmp_ctx);
1243 status = pdb_samba4_mod_groupmem_by_sid(m, tmp_ctx, groupsid, membersid, mod_op);
1244 talloc_free(tmp_ctx);
1245 return status;
1248 static NTSTATUS pdb_samba4_add_groupmem(struct pdb_methods *m,
1249 TALLOC_CTX *mem_ctx,
1250 uint32 group_rid, uint32 member_rid)
1252 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1253 LDB_FLAG_MOD_ADD);
1256 static NTSTATUS pdb_samba4_del_groupmem(struct pdb_methods *m,
1257 TALLOC_CTX *mem_ctx,
1258 uint32 group_rid, uint32 member_rid)
1260 return pdb_samba4_mod_groupmem(m, mem_ctx, group_rid, member_rid,
1261 LDB_FLAG_MOD_DELETE);
1264 static NTSTATUS pdb_samba4_create_alias(struct pdb_methods *m,
1265 const char *name, uint32 *rid)
1267 TALLOC_CTX *frame = talloc_stackframe();
1268 struct pdb_samba4_state *state = talloc_get_type_abort(
1269 m->private_data, struct pdb_samba4_state);
1270 struct dom_sid *sid;
1272 struct ldb_dn *dn;
1273 NTSTATUS status;
1275 /* Internally this uses transactions to ensure all the steps
1276 * happen or fail as one */
1277 status = dsdb_add_domain_alias(state->ldb, frame, name, &sid, &dn);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 TALLOC_FREE(frame);
1282 sid_peek_rid(sid, rid);
1283 TALLOC_FREE(frame);
1284 return NT_STATUS_OK;
1287 static NTSTATUS pdb_samba4_delete_alias(struct pdb_methods *m,
1288 const struct dom_sid *sid)
1290 const char *attrs[] = { NULL };
1291 struct pdb_samba4_state *state = talloc_get_type_abort(
1292 m->private_data, struct pdb_samba4_state);
1293 struct ldb_message *msg;
1294 struct ldb_dn *dn;
1295 int rc;
1296 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1297 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1299 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1300 if (!dn || !ldb_dn_validate(dn)) {
1301 talloc_free(tmp_ctx);
1302 return NT_STATUS_NO_MEMORY;
1305 if (ldb_transaction_start(state->ldb) != LDB_SUCCESS) {
1306 DEBUG(0, ("Failed to start transaction in dsdb_add_domain_alias(): %s\n", ldb_errstring(state->ldb)));
1307 return NT_STATUS_INTERNAL_ERROR;
1310 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, "(objectclass=group)"
1311 "(|(grouptype=%d)(grouptype=%d)))",
1312 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1313 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1314 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1315 talloc_free(tmp_ctx);
1316 ldb_transaction_cancel(state->ldb);
1317 return NT_STATUS_NO_SUCH_ALIAS;
1319 rc = ldb_delete(state->ldb, dn);
1320 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1321 talloc_free(tmp_ctx);
1322 ldb_transaction_cancel(state->ldb);
1323 return NT_STATUS_NO_SUCH_ALIAS;
1324 } else if (rc != LDB_SUCCESS) {
1325 DEBUG(10, ("ldb_delete failed %s\n",
1326 ldb_errstring(state->ldb)));
1327 ldb_transaction_cancel(state->ldb);
1328 return NT_STATUS_LDAP(rc);
1331 if (ldb_transaction_commit(state->ldb) != LDB_SUCCESS) {
1332 DEBUG(0, ("Failed to commit transaction in pdb_samba4_delete_alias(): %s\n",
1333 ldb_errstring(state->ldb)));
1334 return NT_STATUS_INTERNAL_ERROR;
1337 return NT_STATUS_OK;
1340 #if 0
1341 static NTSTATUS pdb_samba4_set_aliasinfo(struct pdb_methods *m,
1342 const struct dom_sid *sid,
1343 struct acct_info *info)
1345 struct pdb_samba4_state *state = talloc_get_type_abort(
1346 m->private_data, struct pdb_samba4_state);
1347 struct tldap_context *ld;
1348 const char *attrs[3] = { "objectSid", "description",
1349 "samAccountName" };
1350 struct ldb_message **msg;
1351 char *sidstr, *dn;
1352 int rc;
1353 struct tldap_mod *mods;
1354 int num_mods;
1355 bool ok;
1357 ld = pdb_samba4_ld(state);
1358 if (ld == NULL) {
1359 return NT_STATUS_LDAP(TLDAP_SERVER_DOWN);
1362 sidstr = sid_binstring(talloc_tos(), sid);
1363 NT_STATUS_HAVE_NO_MEMORY(sidstr);
1365 rc = pdb_samba4_search_fmt(state, state->domaindn, TLDAP_SCOPE_SUB,
1366 attrs, ARRAY_SIZE(attrs), 0, talloc_tos(),
1367 &msg, "(&(objectSid=%s)(objectclass=group)"
1368 "(|(grouptype=%d)(grouptype=%d)))",
1369 sidstr, GTYPE_SECURITY_BUILTIN_LOCAL_GROUP,
1370 GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1371 TALLOC_FREE(sidstr)
1372 if (rc != LDB_SUCCESS) {
1373 DEBUG(10, ("ldap_search failed %s\n",
1374 ldb_errstring(state->ldb)));
1375 return NT_STATUS_LDAP(rc);
1377 switch talloc_array_length(msg) {
1378 case 0:
1379 return NT_STATUS_NO_SUCH_ALIAS;
1380 case 1:
1381 break;
1382 default:
1383 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1386 if (!tldap_entry_dn(msg[0], &dn)) {
1387 TALLOC_FREE(msg);
1388 return NT_STATUS_INTERNAL_DB_CORRUPTION;
1391 mods = NULL;
1392 num_mods = 0;
1393 ok = true;
1395 ok &= tldap_make_mod_fmt(
1396 msg[0], msg, &num_mods, &mods, "description",
1397 "%s", info->acct_desc);
1398 ok &= tldap_make_mod_fmt(
1399 msg[0], msg, &num_mods, &mods, "samAccountName",
1400 "%s", info->acct_name);
1401 if (!ok) {
1402 TALLOC_FREE(msg);
1403 return NT_STATUS_NO_MEMORY;
1405 if (num_mods == 0) {
1406 /* no change */
1407 TALLOC_FREE(msg);
1408 return NT_STATUS_OK;
1411 rc = tldap_modify(ld, dn, num_mods, mods, NULL, 0, NULL, 0);
1412 TALLOC_FREE(msg);
1413 if (rc != LDB_SUCCESS) {
1414 DEBUG(10, ("ldap_modify failed: %s\n",
1415 ldb_errstring(state->ldb)));
1416 return NT_STATUS_LDAP(rc);
1418 return NT_STATUS_OK;
1420 #endif
1421 static NTSTATUS pdb_samba4_add_aliasmem(struct pdb_methods *m,
1422 const struct dom_sid *alias,
1423 const struct dom_sid *member)
1425 NTSTATUS status;
1426 TALLOC_CTX *frame = talloc_stackframe();
1427 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_ADD);
1428 talloc_free(frame);
1429 return status;
1432 static NTSTATUS pdb_samba4_del_aliasmem(struct pdb_methods *m,
1433 const struct dom_sid *alias,
1434 const struct dom_sid *member)
1436 NTSTATUS status;
1437 TALLOC_CTX *frame = talloc_stackframe();
1438 status = pdb_samba4_mod_groupmem_by_sid(m, frame, alias, member, LDB_FLAG_MOD_DELETE);
1439 talloc_free(frame);
1440 return status;
1443 static NTSTATUS pdb_samba4_enum_aliasmem(struct pdb_methods *m,
1444 const struct dom_sid *alias,
1445 TALLOC_CTX *mem_ctx,
1446 struct dom_sid **pmembers,
1447 size_t *pnum_members)
1449 struct pdb_samba4_state *state = talloc_get_type_abort(
1450 m->private_data, struct pdb_samba4_state);
1451 struct ldb_dn *dn;
1452 unsigned int num_members;
1453 NTSTATUS status;
1454 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1455 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1457 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, alias));
1458 if (!dn || !ldb_dn_validate(dn)) {
1459 return NT_STATUS_NO_MEMORY;
1462 status = dsdb_enum_group_mem(state->ldb, mem_ctx, dn, pmembers, &num_members);
1463 *pnum_members = num_members;
1464 if (NT_STATUS_IS_OK(status)) {
1465 talloc_steal(mem_ctx, pmembers);
1467 talloc_free(tmp_ctx);
1468 return status;
1471 static NTSTATUS pdb_samba4_enum_alias_memberships(struct pdb_methods *m,
1472 TALLOC_CTX *mem_ctx,
1473 const struct dom_sid *domain_sid,
1474 const struct dom_sid *members,
1475 size_t num_members,
1476 uint32_t **palias_rids,
1477 size_t *pnum_alias_rids)
1479 struct pdb_samba4_state *state = talloc_get_type_abort(
1480 m->private_data, struct pdb_samba4_state);
1481 uint32_t *alias_rids = NULL;
1482 size_t num_alias_rids = 0;
1483 int i;
1484 struct dom_sid *groupSIDs = NULL;
1485 unsigned int num_groupSIDs = 0;
1486 char *filter;
1487 NTSTATUS status;
1488 const char *sid_string;
1489 const char *sid_dn;
1490 DATA_BLOB sid_blob;
1492 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
1493 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1495 * TODO: Get the filter right so that we only get the aliases from
1496 * either the SAM or BUILTIN
1499 filter = talloc_asprintf(tmp_ctx, "(&(objectClass=group)(groupType:1.2.840.113556.1.4.803:=%u))",
1500 GROUP_TYPE_BUILTIN_LOCAL_GROUP);
1501 if (filter == NULL) {
1502 return NT_STATUS_NO_MEMORY;
1505 for (i = 0; i < num_members; i++) {
1506 sid_string = dom_sid_string(tmp_ctx, &members[i]);
1507 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_string, tmp_ctx);
1509 sid_dn = talloc_asprintf(tmp_ctx, "<SID=%s>", sid_string);
1510 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sid_dn, tmp_ctx);
1512 sid_blob = data_blob_string_const(sid_dn);
1514 status = dsdb_expand_nested_groups(state->ldb, &sid_blob, true, filter,
1515 tmp_ctx, &groupSIDs, &num_groupSIDs);
1516 if (!NT_STATUS_IS_OK(status)) {
1517 talloc_free(tmp_ctx);
1518 return status;
1522 alias_rids = talloc_array(mem_ctx, uint32_t, num_groupSIDs);
1523 if (alias_rids == NULL) {
1524 talloc_free(tmp_ctx);
1525 return NT_STATUS_NO_MEMORY;
1528 for (i=0; i<num_groupSIDs; i++) {
1529 if (sid_peek_check_rid(domain_sid, &groupSIDs[i],
1530 &alias_rids[num_alias_rids])) {
1531 num_alias_rids++;;
1535 *palias_rids = alias_rids;
1536 *pnum_alias_rids = num_alias_rids;
1537 return NT_STATUS_OK;
1540 static NTSTATUS pdb_samba4_lookup_rids(struct pdb_methods *m,
1541 const struct dom_sid *domain_sid,
1542 int num_rids,
1543 uint32 *rids,
1544 const char **names,
1545 enum lsa_SidType *lsa_attrs)
1547 struct pdb_samba4_state *state = talloc_get_type_abort(
1548 m->private_data, struct pdb_samba4_state);
1549 NTSTATUS status;
1551 TALLOC_CTX *tmp_ctx;
1553 if (num_rids == 0) {
1554 return NT_STATUS_NONE_MAPPED;
1557 tmp_ctx = talloc_stackframe();
1558 NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
1560 status = dsdb_lookup_rids(state->ldb, tmp_ctx, domain_sid, num_rids, rids, names, lsa_attrs);
1561 talloc_free(tmp_ctx);
1562 return status;
1565 static NTSTATUS pdb_samba4_lookup_names(struct pdb_methods *m,
1566 const struct dom_sid *domain_sid,
1567 int num_names,
1568 const char **pp_names,
1569 uint32 *rids,
1570 enum lsa_SidType *attrs)
1572 return NT_STATUS_NOT_IMPLEMENTED;
1575 static NTSTATUS pdb_samba4_get_account_policy(struct pdb_methods *m,
1576 enum pdb_policy_type type,
1577 uint32_t *value)
1579 return account_policy_get(type, value)
1580 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1583 static NTSTATUS pdb_samba4_set_account_policy(struct pdb_methods *m,
1584 enum pdb_policy_type type,
1585 uint32_t value)
1587 return account_policy_set(type, value)
1588 ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL;
1591 static NTSTATUS pdb_samba4_get_seq_num(struct pdb_methods *m,
1592 time_t *seq_num_out)
1594 struct pdb_samba4_state *state = talloc_get_type_abort(
1595 m->private_data, struct pdb_samba4_state);
1596 uint64_t seq_num;
1597 int ret = ldb_sequence_number(state->ldb, LDB_SEQ_HIGHEST_SEQ, &seq_num);
1598 if (ret == LDB_SUCCESS) {
1599 *seq_num_out = seq_num;
1600 return NT_STATUS_OK;
1601 } else {
1602 return NT_STATUS_UNSUCCESSFUL;
1606 struct pdb_samba4_search_state {
1607 uint32_t acct_flags;
1608 struct samr_displayentry *entries;
1609 uint32_t num_entries;
1610 ssize_t array_size;
1611 uint32_t current;
1614 static bool pdb_samba4_next_entry(struct pdb_search *search,
1615 struct samr_displayentry *entry)
1617 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1618 search->private_data, struct pdb_samba4_search_state);
1620 if (state->current == state->num_entries) {
1621 return false;
1624 entry->idx = state->entries[state->current].idx;
1625 entry->rid = state->entries[state->current].rid;
1626 entry->acct_flags = state->entries[state->current].acct_flags;
1628 entry->account_name = talloc_strdup(
1629 search, state->entries[state->current].account_name);
1630 entry->fullname = talloc_strdup(
1631 search, state->entries[state->current].fullname);
1632 entry->description = talloc_strdup(
1633 search, state->entries[state->current].description);
1635 state->current += 1;
1636 return true;
1639 static void pdb_samba4_search_end(struct pdb_search *search)
1641 struct pdb_samba4_search_state *state = talloc_get_type_abort(
1642 search->private_data, struct pdb_samba4_search_state);
1643 talloc_free(state);
1646 static bool pdb_samba4_search_filter(struct pdb_methods *m,
1647 struct pdb_search *search,
1648 struct pdb_samba4_search_state **pstate,
1649 const char *exp_fmt, ...) _PRINTF_ATTRIBUTE(4, 5)
1651 struct pdb_samba4_state *state = talloc_get_type_abort(
1652 m->private_data, struct pdb_samba4_state);
1653 struct pdb_samba4_search_state *sstate;
1654 const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
1655 "userAccountControl", "description", NULL };
1656 struct ldb_result *res;
1657 int i, rc, num_users;
1659 va_list ap;
1660 char *expression = NULL;
1662 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1663 if (!tmp_ctx) {
1664 return false;
1667 va_start(ap, exp_fmt);
1668 expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
1669 va_end(ap);
1671 if (!expression) {
1672 talloc_free(tmp_ctx);
1673 return LDB_ERR_OPERATIONS_ERROR;
1676 sstate = talloc_zero(tmp_ctx, struct pdb_samba4_search_state);
1677 if (sstate == NULL) {
1678 talloc_free(tmp_ctx);
1679 return false;
1682 rc = dsdb_search(state->ldb, tmp_ctx, &res, NULL, LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
1683 if (rc != LDB_SUCCESS) {
1684 talloc_free(tmp_ctx);
1685 DEBUG(10, ("dsdb_search failed: %s\n",
1686 ldb_errstring(state->ldb)));
1687 return false;
1690 num_users = res->count;
1692 sstate->entries = talloc_array(sstate, struct samr_displayentry,
1693 num_users);
1694 if (sstate->entries == NULL) {
1695 talloc_free(tmp_ctx);
1696 DEBUG(10, ("talloc failed\n"));
1697 return false;
1700 sstate->num_entries = 0;
1702 for (i=0; i<num_users; i++) {
1703 struct samr_displayentry *e;
1704 struct dom_sid *sid;
1706 e = &sstate->entries[sstate->num_entries];
1708 e->idx = sstate->num_entries;
1709 sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
1710 if (!sid) {
1711 talloc_free(tmp_ctx);
1712 DEBUG(10, ("Could not pull SID\n"));
1713 return false;
1715 sid_peek_rid(sid, &e->rid);
1717 e->acct_flags = samdb_result_acct_flags(state->ldb, tmp_ctx,
1718 res->msgs[i],
1719 ldb_get_default_basedn(state->ldb));
1720 e->account_name = ldb_msg_find_attr_as_string(
1721 res->msgs[i], "samAccountName", NULL);
1722 if (e->account_name == NULL) {
1723 talloc_free(tmp_ctx);
1724 return false;
1726 e->fullname = ldb_msg_find_attr_as_string(
1727 res->msgs[i], "displayName", "");
1728 e->description = ldb_msg_find_attr_as_string(
1729 res->msgs[i], "description", "");
1731 sstate->num_entries += 1;
1732 if (sstate->num_entries >= num_users) {
1733 break;
1736 talloc_steal(sstate->entries, res->msgs);
1737 search->private_data = talloc_steal(search, sstate);
1738 search->next_entry = pdb_samba4_next_entry;
1739 search->search_end = pdb_samba4_search_end;
1740 *pstate = sstate;
1741 talloc_free(tmp_ctx);
1742 return true;
1745 static bool pdb_samba4_search_users(struct pdb_methods *m,
1746 struct pdb_search *search,
1747 uint32 acct_flags)
1749 struct pdb_samba4_search_state *sstate;
1750 bool ret;
1752 ret = pdb_samba4_search_filter(m, search, &sstate, "(objectclass=user)");
1753 if (!ret) {
1754 return false;
1756 sstate->acct_flags = acct_flags;
1757 return true;
1760 static bool pdb_samba4_search_groups(struct pdb_methods *m,
1761 struct pdb_search *search)
1763 struct pdb_samba4_search_state *sstate;
1764 bool ret;
1766 ret = pdb_samba4_search_filter(m, search, &sstate,
1767 "(&(grouptype=%d)(objectclass=group))",
1768 GTYPE_SECURITY_GLOBAL_GROUP);
1769 if (!ret) {
1770 return false;
1772 sstate->acct_flags = 0;
1773 return true;
1776 static bool pdb_samba4_search_aliases(struct pdb_methods *m,
1777 struct pdb_search *search,
1778 const struct dom_sid *sid)
1780 struct pdb_samba4_search_state *sstate;
1781 bool ret;
1783 ret = pdb_samba4_search_filter(m, search, &sstate,
1784 "(&(grouptype=%d)(objectclass=group))",
1785 sid_check_is_builtin(sid)
1786 ? GTYPE_SECURITY_BUILTIN_LOCAL_GROUP
1787 : GTYPE_SECURITY_DOMAIN_LOCAL_GROUP);
1788 if (!ret) {
1789 return false;
1791 sstate->acct_flags = 0;
1792 return true;
1795 static bool pdb_samba4_uid_to_sid(struct pdb_methods *m, uid_t uid,
1796 struct dom_sid *sid)
1798 struct pdb_samba4_state *state = talloc_get_type_abort(
1799 m->private_data, struct pdb_samba4_state);
1800 NTSTATUS status;
1801 struct id_map id_map;
1802 struct id_map *id_maps[2];
1803 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1804 if (!tmp_ctx) {
1805 return false;
1808 id_map.xid.id = uid;
1809 id_map.xid.type = ID_TYPE_UID;
1810 id_maps[0] = &id_map;
1811 id_maps[1] = NULL;
1813 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1814 if (!NT_STATUS_IS_OK(status)) {
1815 talloc_free(tmp_ctx);
1816 return false;
1818 *sid = *id_map.sid;
1819 talloc_free(tmp_ctx);
1820 return true;
1823 static bool pdb_samba4_gid_to_sid(struct pdb_methods *m, gid_t gid,
1824 struct dom_sid *sid)
1826 struct pdb_samba4_state *state = talloc_get_type_abort(
1827 m->private_data, struct pdb_samba4_state);
1828 NTSTATUS status;
1829 struct id_map id_map;
1830 struct id_map *id_maps[2];
1831 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1832 if (!tmp_ctx) {
1833 return false;
1836 id_map.xid.id = gid;
1837 id_map.xid.type = ID_TYPE_GID;
1838 id_maps[0] = &id_map;
1839 id_maps[1] = NULL;
1841 status = idmap_xids_to_sids(state->idmap_ctx, tmp_ctx, id_maps);
1842 if (!NT_STATUS_IS_OK(status)) {
1843 return false;
1845 *sid = *id_map.sid;
1846 talloc_free(tmp_ctx);
1847 return true;
1850 static bool pdb_samba4_sid_to_id(struct pdb_methods *m, const struct dom_sid *sid,
1851 union unid_t *id, enum lsa_SidType *type)
1853 struct pdb_samba4_state *state = talloc_get_type_abort(
1854 m->private_data, struct pdb_samba4_state);
1855 struct id_map id_map;
1856 struct id_map *id_maps[2];
1857 const char *attrs[] = { "objectClass", "groupType", NULL };
1858 struct ldb_message *msg;
1859 struct ldb_dn *dn;
1860 NTSTATUS status;
1861 int rc;
1862 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1863 if (!tmp_ctx) {
1864 return false;
1867 ZERO_STRUCT(id_map);
1869 dn = ldb_dn_new_fmt(tmp_ctx, state->ldb, "<SID=%s>", dom_sid_string(tmp_ctx, sid));
1870 if (!dn || !ldb_dn_validate(dn)) {
1871 talloc_free(tmp_ctx);
1872 return false;
1874 rc = dsdb_search_one(state->ldb, tmp_ctx, &msg, dn, LDB_SCOPE_BASE, attrs, 0, NULL);
1875 if (rc == LDB_ERR_NO_SUCH_OBJECT) {
1876 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)));
1877 talloc_free(tmp_ctx);
1878 return false;
1880 if (samdb_find_attribute(state->ldb, msg, "objectClass", "group")) {
1881 uint32_t grouptype = ldb_msg_find_attr_as_uint(msg, "groupType", 0);
1882 switch (grouptype) {
1883 case GTYPE_SECURITY_BUILTIN_LOCAL_GROUP:
1884 case GTYPE_SECURITY_DOMAIN_LOCAL_GROUP:
1885 *type = SID_NAME_ALIAS;
1886 break;
1887 case GTYPE_SECURITY_GLOBAL_GROUP:
1888 *type = SID_NAME_DOM_GRP;
1889 break;
1890 default:
1891 talloc_free(tmp_ctx);
1892 DEBUG(10, ("Could not pull groupType\n"));
1893 return false;
1896 *type = SID_NAME_DOM_GRP;
1898 ZERO_STRUCT(id_map);
1899 id_map.sid = sid;
1900 id_maps[0] = &id_map;
1901 id_maps[1] = NULL;
1903 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1904 talloc_free(tmp_ctx);
1905 if (!NT_STATUS_IS_OK(status)) {
1906 return false;
1908 if (id_map.xid.type == ID_TYPE_GID || id_map.xid.type == ID_TYPE_BOTH) {
1909 id->gid = id_map.xid.id;
1910 return true;
1912 return false;
1913 } else if (samdb_find_attribute(state->ldb, msg, "objectClass", "user")) {
1914 *type = SID_NAME_USER;
1915 ZERO_STRUCT(id_map);
1916 id_map.sid = sid;
1917 id_maps[0] = &id_map;
1918 id_maps[1] = NULL;
1920 status = idmap_sids_to_xids(state->idmap_ctx, tmp_ctx, id_maps);
1921 talloc_free(tmp_ctx);
1922 if (!NT_STATUS_IS_OK(status)) {
1923 return false;
1925 if (id_map.xid.type == ID_TYPE_UID || id_map.xid.type == ID_TYPE_BOTH) {
1926 id->uid = id_map.xid.id;
1927 return true;
1929 return false;
1931 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)));
1932 talloc_free(tmp_ctx);
1933 return false;
1936 static uint32_t pdb_samba4_capabilities(struct pdb_methods *m)
1938 return PDB_CAP_STORE_RIDS | PDB_CAP_ADS;
1941 static bool pdb_samba4_new_rid(struct pdb_methods *m, uint32 *rid)
1943 return false;
1946 static bool pdb_samba4_get_trusteddom_pw(struct pdb_methods *m,
1947 const char *domain, char** pwd,
1948 struct dom_sid *sid,
1949 time_t *pass_last_set_time)
1951 return false;
1954 static bool pdb_samba4_set_trusteddom_pw(struct pdb_methods *m,
1955 const char* domain, const char* pwd,
1956 const struct dom_sid *sid)
1958 return false;
1961 static bool pdb_samba4_del_trusteddom_pw(struct pdb_methods *m,
1962 const char *domain)
1964 return false;
1967 static NTSTATUS pdb_samba4_enum_trusteddoms(struct pdb_methods *m,
1968 TALLOC_CTX *mem_ctx,
1969 uint32 *num_domains,
1970 struct trustdom_info ***domains)
1972 *num_domains = 0;
1973 *domains = NULL;
1974 return NT_STATUS_OK;
1977 static void pdb_samba4_init_methods(struct pdb_methods *m)
1979 m->name = "samba4";
1980 m->get_domain_info = pdb_samba4_get_domain_info;
1981 m->getsampwnam = pdb_samba4_getsampwnam;
1982 m->getsampwsid = pdb_samba4_getsampwsid;
1983 m->create_user = pdb_samba4_create_user;
1984 m->delete_user = pdb_samba4_delete_user;
1985 m->add_sam_account = pdb_samba4_add_sam_account;
1986 m->update_sam_account = pdb_samba4_update_sam_account;
1987 m->delete_sam_account = pdb_samba4_delete_sam_account;
1988 m->rename_sam_account = pdb_samba4_rename_sam_account;
1989 m->update_login_attempts = pdb_samba4_update_login_attempts;
1990 m->getgrsid = pdb_samba4_getgrsid;
1991 m->getgrgid = pdb_samba4_getgrgid;
1992 m->getgrnam = pdb_samba4_getgrnam;
1993 m->create_dom_group = pdb_samba4_create_dom_group;
1994 m->delete_dom_group = pdb_samba4_delete_dom_group;
1995 m->add_group_mapping_entry = pdb_samba4_add_group_mapping_entry;
1996 m->update_group_mapping_entry = pdb_samba4_update_group_mapping_entry;
1997 m->delete_group_mapping_entry = pdb_samba4_delete_group_mapping_entry;
1998 m->enum_group_mapping = pdb_samba4_enum_group_mapping;
1999 m->enum_group_members = pdb_samba4_enum_group_members;
2000 m->enum_group_memberships = pdb_samba4_enum_group_memberships;
2001 m->set_unix_primary_group = pdb_samba4_set_unix_primary_group;
2002 m->add_groupmem = pdb_samba4_add_groupmem;
2003 m->del_groupmem = pdb_samba4_del_groupmem;
2004 m->create_alias = pdb_samba4_create_alias;
2005 m->delete_alias = pdb_samba4_delete_alias;
2006 m->get_aliasinfo = pdb_default_get_aliasinfo;
2007 m->add_aliasmem = pdb_samba4_add_aliasmem;
2008 m->del_aliasmem = pdb_samba4_del_aliasmem;
2009 m->enum_aliasmem = pdb_samba4_enum_aliasmem;
2010 m->enum_alias_memberships = pdb_samba4_enum_alias_memberships;
2011 m->lookup_rids = pdb_samba4_lookup_rids;
2012 m->lookup_names = pdb_samba4_lookup_names;
2013 m->get_account_policy = pdb_samba4_get_account_policy;
2014 m->set_account_policy = pdb_samba4_set_account_policy;
2015 m->get_seq_num = pdb_samba4_get_seq_num;
2016 m->search_users = pdb_samba4_search_users;
2017 m->search_groups = pdb_samba4_search_groups;
2018 m->search_aliases = pdb_samba4_search_aliases;
2019 m->uid_to_sid = pdb_samba4_uid_to_sid;
2020 m->gid_to_sid = pdb_samba4_gid_to_sid;
2021 m->sid_to_id = pdb_samba4_sid_to_id;
2022 m->capabilities = pdb_samba4_capabilities;
2023 m->new_rid = pdb_samba4_new_rid;
2024 m->get_trusteddom_pw = pdb_samba4_get_trusteddom_pw;
2025 m->set_trusteddom_pw = pdb_samba4_set_trusteddom_pw;
2026 m->del_trusteddom_pw = pdb_samba4_del_trusteddom_pw;
2027 m->enum_trusteddoms = pdb_samba4_enum_trusteddoms;
2030 static void free_private_data(void **vp)
2032 struct pdb_samba4_state *state = talloc_get_type_abort(
2033 *vp, struct pdb_samba4_state);
2034 talloc_unlink(state, state->ldb);
2035 return;
2038 static NTSTATUS pdb_init_samba4(struct pdb_methods **pdb_method,
2039 const char *location)
2041 struct pdb_methods *m;
2042 struct pdb_samba4_state *state;
2043 NTSTATUS status;
2045 if ( !NT_STATUS_IS_OK(status = make_pdb_method( &m )) ) {
2046 return status;
2049 state = talloc_zero(m, struct pdb_samba4_state);
2050 if (state == NULL) {
2051 goto nomem;
2053 m->private_data = state;
2054 m->free_private_data = free_private_data;
2055 pdb_samba4_init_methods(m);
2057 state->ev = s4_event_context_init(state);
2058 if (!state->ev) {
2059 DEBUG(10, ("s4_event_context_init failed\n"));
2060 goto fail;
2063 state->lp_ctx = loadparm_init_s3(state, loadparm_s3_context());
2064 if (state->lp_ctx == NULL) {
2065 DEBUG(10, ("loadparm_init_s3 failed\n"));
2066 goto fail;
2069 state->ldb = samdb_connect(state,
2070 state->ev,
2071 state->lp_ctx,
2072 system_session(state->lp_ctx), 0);
2074 if (!state->ldb) {
2075 DEBUG(10, ("samdb_connect failed\n"));
2076 goto fail;
2079 state->idmap_ctx = idmap_init(state, state->ev,
2080 state->lp_ctx);
2081 if (!state->idmap_ctx) {
2082 DEBUG(10, ("samdb_connect failed\n"));
2083 goto fail;
2086 *pdb_method = m;
2087 return NT_STATUS_OK;
2088 nomem:
2089 status = NT_STATUS_NO_MEMORY;
2090 fail:
2091 TALLOC_FREE(m);
2092 return status;
2095 NTSTATUS pdb_samba4_init(void);
2096 NTSTATUS pdb_samba4_init(void)
2098 return smb_register_passdb(PASSDB_INTERFACE_VERSION, "samba4",
2099 pdb_init_samba4);