[patch] winbindd: try to fix 'restrict anonymous=1'

Martin Pool mbp at samba.org
Mon Jan 20 11:12:00 GMT 2003


hp CR1501 and friends

This patch tries to make winbindd cope with the security option
'restrict anonymous=1' on NT4 and W2kS.  When this option is set, the
DC disallows SAMR calls on unauthenticated connections, but does allow
LSA translations between names and sids.  

Obviously winbindd can't be fully functional in this case, but it
ought to be able to still do these operations -- in particular, with
this patch "wbinfo -n" works, while it does not work without it.

I'm not sure this is right yet but I'd appreciate comments.  If this
is correct, I think it ought to be ported to HEAD and 3.0 as well.

It seems to work for me.  As Tim suggested I used both built in
(Administrator) and otherwise (jrhacker) SIDs for testing.

This partially reverts the "cached failure" case, and possibly causes
winbindd to hammer on dcs that just don't want to talk to it.  You can
imagine a more detailed fix that specifically detects the "ra=1" case
and handles it by using only LSA.  From what I know, it doesn't seem
specifically handling that, though perhaps it would be so in HEAD.

Incidentally, gdb remote mode absolutely rocks for debugging appliances.


Thanks to Tim for patient help.
 

Index: nsswitch/winbindd_cache.c
===================================================================
RCS file: /data/cvs/samba/source/nsswitch/winbindd_cache.c,v
retrieving revision 1.5.2.8
diff -u -r1.5.2.8 winbindd_cache.c
--- nsswitch/winbindd_cache.c	31 Oct 2002 23:56:32 -0000	1.5.2.8
+++ nsswitch/winbindd_cache.c	20 Jan 2003 10:43:58 -0000
@@ -201,7 +201,8 @@
   refresh the domain sequence number. If force is True
   then always refresh it, no matter how recently we fetched it
 */
-static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
+static NTSTATUS refresh_sequence_number(struct winbindd_domain *domain, 
+					BOOL force)
 {
 	NTSTATUS status;
 	unsigned time_diff;
@@ -210,7 +211,7 @@
 
 	/* see if we have to refetch the domain sequence number */
 	if (!force && (time_diff < lp_winbind_cache_time())) {
-		return;
+		return NT_STATUS_OK;
 	}
 
 	status = wcache->backend->sequence_number(domain, &domain->sequence_number);
@@ -238,6 +239,8 @@
 
 	DEBUG(10, ("refresh_sequence_number: seq number is now %d\n", 
 		   domain->sequence_number));
+
+	return status;
 }
 
 /*
@@ -276,8 +279,18 @@
 	TDB_DATA data;
 	struct cache_entry *centry;
 	TDB_DATA key;
+	NTSTATUS result;
 
-	refresh_sequence_number(domain, False);
+	result = refresh_sequence_number(domain, False);
+
+	/* Treat an access denied result from refresh_sequence_number as a
+	   cache miss.  Access denied is returned when the domain
+	   controller disallows anonymous access.  Perhaps we should treat
+	   any error as a miss although that might increase the time it
+	   takes winbindd to determine if a domain controller is down. */
+
+	if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED))
+		return NULL;
 
 	va_start(ap, format);
 	smb_xvasprintf(&kstr, format, ap);
@@ -738,9 +751,15 @@
 do_query:
 	ZERO_STRUCTP(sid);
 
-	/* Return status value returned by seq number check */
+	/* If the seq number check indicated that there is a problem
+	 * with this DC, then return that status... except for
+	 * access_denied.  This is special because the dc may be in
+	 * "restrict anonymous = 1" mode, in which case it will deny
+	 * most unauthenticated operations, but *will* allow the LSA
+	 * name-to-sid that we try as a fallback. */
 
-	if (!NT_STATUS_IS_OK(domain->last_status))
+	if (!(NT_STATUS_IS_OK(domain->last_status)
+	      || NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)))
 		return domain->last_status;
 
 	status = cache->backend->name_to_sid(domain, name, sid, type);
@@ -784,9 +803,16 @@
 do_query:
 	*name = NULL;
 
-	/* Return status value returned by seq number check */
 
-	if (!NT_STATUS_IS_OK(domain->last_status))
+	/* If the seq number check indicated that there is a problem
+	 * with this DC, then return that status... except for
+	 * access_denied.  This is special because the dc may be in
+	 * "restrict anonymous = 1" mode, in which case it will deny
+	 * most unauthenticated operations, but *will* allow the LSA
+	 * sid-to-name that we try as a fallback. */
+
+	if (!(NT_STATUS_IS_OK(domain->last_status)
+	      || NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)))
 		return domain->last_status;
 
 	status = cache->backend->sid_to_name(domain, mem_ctx, sid, name, type);


-- 
Martin 



More information about the samba-technical mailing list