summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-11-10 19:50:09 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:05:22 -0500
commit438d0ad451678c42614ab800bceaf490e09c120a (patch)
tree257d4e4c338c0d600d7e579a20e875bdc1452063
parente04e7e1ffcf0ad4c8a3837f8553ea83f6b49166d (diff)
downloadsamba-438d0ad451678c42614ab800bceaf490e09c120a.tar.gz
samba-438d0ad451678c42614ab800bceaf490e09c120a.tar.bz2
samba-438d0ad451678c42614ab800bceaf490e09c120a.zip
r11651: After talking to Jeremy, commit my winbindd "Do the Right Thing" patch.
Still needs some more testing ni domains with multiple DCs. Coming next.... (This used to be commit aaed605206a8549cec575dab31e56bf6d32f26a6)
-rw-r--r--source3/libads/kerberos.c19
-rw-r--r--source3/nsswitch/winbindd_ads.c34
-rw-r--r--source3/nsswitch/winbindd_cache.c57
3 files changed, 82 insertions, 28 deletions
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index 7f855add06..d5b4b11fa2 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -130,8 +130,25 @@ int ads_kinit_password(ADS_STRUCT *ads)
{
char *s;
int ret;
+ const char *account_name;
+ fstring acct_name;
- if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) {
+ if ( IS_DC ) {
+ /* this will end up getting a ticket for DOMAIN@RUSTED.REA.LM */
+ account_name = lp_workgroup();
+ } else {
+ /* always use the sAMAccountName for security = domain */
+ /* global_myname()$@REA.LM */
+ if ( lp_security() == SEC_DOMAIN ) {
+ fstr_sprintf( acct_name, "%s$", global_myname() );
+ account_name = acct_name;
+ }
+ else
+ /* This looks like host/global_myname()@REA.LM */
+ account_name = ads->auth.user_name;
+ }
+
+ if (asprintf(&s, "%s@%s", account_name, ads->auth.realm) == -1) {
return KRB5_CC_NOMEM;
}
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c
index 6b170c3330..32bc641b6a 100644
--- a/source3/nsswitch/winbindd_ads.c
+++ b/source3/nsswitch/winbindd_ads.c
@@ -68,11 +68,39 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
}
/* the machine acct password might have change - fetch it every time */
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
+ SAFE_FREE(ads->auth.password);
SAFE_FREE(ads->auth.realm);
- ads->auth.realm = SMB_STRDUP(lp_realm());
+
+ if ( IS_DC ) {
+ DOM_SID sid;
+ time_t last_set_time;
+
+ if ( !secrets_fetch_trusted_domain_password( domain->name, &ads->auth.password, &sid, &last_set_time ) ) {
+ ads_destroy( &ads );
+ return NULL;
+ }
+ ads->auth.realm = SMB_STRDUP( ads->server.realm );
+ strupper_m( ads->auth.realm );
+ }
+ else {
+ struct winbindd_domain *our_domain = domain;
+
+ ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
+
+ /* always give preference to the alt_name in our
+ primary domain if possible */
+
+ if ( !domain->primary )
+ our_domain = find_our_domain();
+
+ if ( our_domain->alt_name[0] != '\0' ) {
+ ads->auth.realm = SMB_STRDUP( our_domain->alt_name );
+ strupper_m( ads->auth.realm );
+ }
+ else
+ ads->auth.realm = SMB_STRDUP( lp_realm() );
+ }
status = ads_connect(ads);
if (!ADS_ERR_OK(status) || !ads->config.realm) {
diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c
index 9164a135c5..993e6d96e8 100644
--- a/source3/nsswitch/winbindd_cache.c
+++ b/source3/nsswitch/winbindd_cache.c
@@ -100,43 +100,52 @@ void winbindd_check_cache_size(time_t t)
static struct winbind_cache *get_cache(struct winbindd_domain *domain)
{
struct winbind_cache *ret = wcache;
+ struct winbindd_domain *our_domain = domain;
/* we have to know what type of domain we are dealing with first */
if ( !domain->initialized )
set_dc_type_and_flags( domain );
+ /*
+ OK. listen up becasue I'm only going to say this once.
+ We have the following scenarios to consider
+ (a) trusted AD domains on a Samba DC,
+ (b) trusted AD domains and we are joined to a non-kerberos domain
+ (c) trusted AD domains and we are joined to a kerberos (AD) domain
+
+ For (a) we can always contact the trusted domain using krb5
+ since we have the domain trust account password
+
+ For (b) we can only use RPC since we have no way of
+ getting a krb5 ticket in our own domain
+
+ For (c) we can always use krb5 since we have a kerberos trust
+
+ --jerry
+ */
+
if (!domain->backend) {
extern struct winbindd_methods reconnect_methods;
- switch (lp_security()) {
#ifdef HAVE_ADS
- case SEC_ADS: {
- extern struct winbindd_methods ads_methods;
- /* always obey the lp_security parameter for our domain */
- if (domain->primary) {
- domain->backend = &ads_methods;
- break;
- }
+ extern struct winbindd_methods ads_methods;
- /* only use ADS for native modes at the momment.
- The problem is the correct detection of mixed
- mode domains from NT4 BDC's --jerry */
-
- if ( domain->native_mode ) {
- DEBUG(5,("get_cache: Setting ADS methods for domain %s\n",
- domain->name));
- domain->backend = &ads_methods;
- break;
- }
+ /* find our domain first so we can figure out if we
+ are joined to a kerberized domain */
- /* fall through */
- }
-#endif
- default:
- DEBUG(5,("get_cache: Setting MS-RPC methods for domain %s\n",
- domain->name));
+ if ( !domain->primary )
+ our_domain = find_our_domain();
+
+ if ( (our_domain->active_directory || IS_DC) && domain->active_directory ) {
+ DEBUG(5,("get_cache: Setting ADS methods for domain %s\n", domain->name));
+ domain->backend = &ads_methods;
+ } else {
+#endif /* HAVE_ADS */
+ DEBUG(5,("get_cache: Setting MS-RPC methods for domain %s\n", domain->name));
domain->backend = &reconnect_methods;
+#ifdef HAVE_ADS
}
+#endif /* HAVE_ADS */
}
if (ret)