From 7202dcdcc06080f0227b82993b446bda4c0782df Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 18 Feb 2010 10:54:53 +1100 Subject: s4:param Modify secrets_get_domain_sid to give more useful errors This also moves the calls to secrets_get_domain_sid back into winbind_task_init(), so that we can terminate with a much more detailed error message. (The previous message was simply NT_STATUS_CANT_ACCESS_DOMAIN_INFO). Andrew Bartlett --- source4/param/secrets.c | 43 ++++++++++++------------------- source4/param/secrets.h | 6 ++++- source4/winbind/config.mk | 1 - source4/winbind/wb_server.c | 39 ++++++++++++++++++++++++---- source4/winbind/wb_setup_domains.c | 53 -------------------------------------- 5 files changed, 55 insertions(+), 87 deletions(-) delete mode 100644 source4/winbind/wb_setup_domains.c diff --git a/source4/param/secrets.c b/source4/param/secrets.c index f21be822a2..18a0800779 100644 --- a/source4/param/secrets.c +++ b/source4/param/secrets.c @@ -31,6 +31,9 @@ #include "../lib/util/util_tdb.h" #include "../lib/util/util_ldb.h" #include "librpc/gen_ndr/ndr_security.h" +#include "dsdb/samdb/samdb.h" +#include "dsdb/common/util.h" +#include "dsdb/common/proto.h" /** * Use a TDB to store an incrementing random seed. @@ -138,15 +141,17 @@ struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx, struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx, - const char *domain) + const char *domain, + char **errstring) { struct ldb_context *ldb; - struct ldb_message **msgs; + struct ldb_message *msg; int ldb_ret; const char *attrs[] = { "objectSid", NULL }; struct dom_sid *result = NULL; const struct ldb_val *v; enum ndr_err_code ndr_err; + *errstring = NULL; ldb = secrets_db_connect(mem_ctx, ev_ctx, lp_ctx); if (ldb == NULL) { @@ -154,35 +159,18 @@ struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx, return NULL; } - ldb_ret = gendb_search(ldb, ldb, - ldb_dn_new(mem_ctx, ldb, SECRETS_PRIMARY_DOMAIN_DN), - &msgs, attrs, - SECRETS_PRIMARY_DOMAIN_FILTER, domain); + ldb_ret = dsdb_search_one(ldb, ldb, &msg, + ldb_dn_new(mem_ctx, ldb, SECRETS_PRIMARY_DOMAIN_DN), + LDB_SCOPE_ONELEVEL, + attrs, 0, SECRETS_PRIMARY_DOMAIN_FILTER, domain); - if (ldb_ret == -1) { - DEBUG(5, ("Error searching for domain SID for %s: %s", - domain, ldb_errstring(ldb))); - talloc_free(ldb); - return NULL; - } - - if (ldb_ret == 0) { - DEBUG(5, ("Did not find domain record for %s\n", domain)); - talloc_free(ldb); + if (ldb_ret != LDB_SUCCESS) { + *errstring = talloc_asprintf(mem_ctx, "Failed to find record for %s in secrets.ldb: %s: %s", domain, ldb_strerror(ldb_ret), ldb_errstring(ldb)); return NULL; } - - if (ldb_ret > 1) { - DEBUG(5, ("Found more than one (%d) domain records for %s\n", - ldb_ret, domain)); - talloc_free(ldb); - return NULL; - } - - v = ldb_msg_find_ldb_val(msgs[0], "objectSid"); + v = ldb_msg_find_ldb_val(msg, "objectSid"); if (v == NULL) { - DEBUG(0, ("Domain object for %s does not contain a SID!\n", - domain)); + *errstring = talloc_asprintf(mem_ctx, "Failed to find a SID on record for %s in secrets.ldb", domain); return NULL; } result = talloc(mem_ctx, struct dom_sid); @@ -194,6 +182,7 @@ struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx, ndr_err = ndr_pull_struct_blob(v, result, NULL, result, (ndr_pull_flags_fn_t)ndr_pull_dom_sid); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + *errstring = talloc_asprintf(mem_ctx, "Failed to parse SID on record for %s in secrets.ldb", domain); talloc_free(result); talloc_free(ldb); return NULL; diff --git a/source4/param/secrets.h b/source4/param/secrets.h index caffa50733..c3227dfbcb 100644 --- a/source4/param/secrets.h +++ b/source4/param/secrets.h @@ -40,7 +40,11 @@ struct loadparm_context; struct tevent_context; struct tdb_wrap *secrets_init(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); struct ldb_context *secrets_db_connect(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx); -struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx, const char *domain); +struct dom_sid *secrets_get_domain_sid(TALLOC_CTX *mem_ctx, + struct tevent_context *ev_ctx, + struct loadparm_context *lp_ctx, + const char *domain, + char **errstring); #endif /* _SECRETS_H */ diff --git a/source4/winbind/config.mk b/source4/winbind/config.mk index 16c1652fe4..17cbd956e4 100644 --- a/source4/winbind/config.mk +++ b/source4/winbind/config.mk @@ -20,7 +20,6 @@ PRIVATE_DEPENDENCIES = \ WINBIND_OBJ_FILES = $(addprefix $(winbindsrcdir)/, \ wb_server.o \ - wb_setup_domains.o \ wb_irpc.o \ wb_samba3_protocol.o \ wb_samba3_cmd.o \ diff --git a/source4/winbind/wb_server.c b/source4/winbind/wb_server.c index fdf8deaa2c..03a443ac16 100644 --- a/source4/winbind/wb_server.c +++ b/source4/winbind/wb_server.c @@ -2,8 +2,9 @@ Unix SMB/CIFS implementation. Main winbindd server routines - Copyright (C) Stefan Metzmacher 2005 + Copyright (C) Stefan Metzmacher 2005-2008 Copyright (C) Andrew Tridgell 2005 + Copyright (C) Andrew Bartlett 2010 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +27,7 @@ #include "lib/tsocket/tsocket.h" #include "libcli/util/tstream.h" #include "param/param.h" +#include "param/secrets.h" void wbsrv_terminate_connection(struct wbsrv_connection *wbconn, const char *reason) { @@ -195,6 +197,8 @@ static void winbind_task_init(struct task_server *task) NTSTATUS status; struct wbsrv_service *service; struct wbsrv_listen_socket *listen_socket; + char *errstring; + struct dom_sid *primary_sid; task_server_set_title(task, "task[winbind]"); @@ -226,11 +230,36 @@ static void winbind_task_init(struct task_server *task) if (!service) goto nomem; service->task = task; - status = wbsrv_setup_domains(service); - if (!NT_STATUS_IS_OK(status)) { - task_server_terminate(task, nt_errstr(status), true); - return; + + /* Find the primary SID, depending if we are a standalone + * server (what good is winbind in this case, but anyway...), + * or are in a domain as a member or a DC */ + switch (lp_server_role(service->task->lp_ctx)) { + case ROLE_STANDALONE: + primary_sid = secrets_get_domain_sid(service, + service->task->event_ctx, + service->task->lp_ctx, + lp_netbios_name(service->task->lp_ctx), &errstring); + if (!primary_sid) { + char *message = talloc_asprintf(task, "Cannot start Winbind (standalone configuration): %s", errstring); + task_server_terminate(task, message, true); + return; + } + break; + case ROLE_DOMAIN_MEMBER: + case ROLE_DOMAIN_CONTROLLER: + primary_sid = secrets_get_domain_sid(service, + service->task->event_ctx, + service->task->lp_ctx, + lp_workgroup(service->task->lp_ctx), &errstring); + if (!primary_sid) { + char *message = talloc_asprintf(task, "Cannot start Winbind (domain configuration): %s", errstring); + task_server_terminate(task, message, true); + return; + } + break; } + service->primary_sid = primary_sid; service->idmap_ctx = idmap_init(service, task->event_ctx, task->lp_ctx); if (service->idmap_ctx == NULL) { diff --git a/source4/winbind/wb_setup_domains.c b/source4/winbind/wb_setup_domains.c deleted file mode 100644 index 5ce6500d4d..0000000000 --- a/source4/winbind/wb_setup_domains.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Copyright (C) Stefan Metzmacher 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" -#include "winbind/wb_server.h" -#include "smbd/service_task.h" -#include "param/secrets.h" -#include "param/param.h" - -NTSTATUS wbsrv_setup_domains(struct wbsrv_service *service) -{ - const struct dom_sid *primary_sid; - - /* - * This is a bit more difficult here: when we are a domain controller - * or a joined domain member the first call will work. But if we are - * a standalone server or unjoined member then the second is the right - * one. - */ - primary_sid = secrets_get_domain_sid(service, - service->task->event_ctx, - service->task->lp_ctx, - lp_workgroup(service->task->lp_ctx)); - if (primary_sid == NULL) { - primary_sid = secrets_get_domain_sid(service, - service->task->event_ctx, - service->task->lp_ctx, - lp_netbios_name(service->task->lp_ctx)); - } - if (primary_sid == NULL) { - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } - - service->primary_sid = primary_sid; - - return NT_STATUS_OK; -} -- cgit