PATCH: support for LDAP name<->SID lookups

Luke Howard lukeh at PADL.COM
Sat Aug 28 06:21:28 GMT 2004


The adds support (if NCALRPC_FUNNEL is defined) for name<->SID lookups
over LDAP rather than RPC.

Caveats:

  - It only supports the local domain; I'll add Global Catalog
    support later

  - I'm not suggesting this is a better solution to the problem,
    as it breaks the Windows model of deferring name resolution
    to the upstream trusted domain (which allows for all sorts
    of clever tricks)

I wrote this patch to solve a specific problem that is unlikely to be
seen in general SAMBA deployments, however one could make a case for
it in instances where firewall configuration prohibits SMB and RPC
traffic.

The patch is against 3.0.6. You probably do want to pick up the patch
to winbindd_cache.c, though, there was an uninitialized variable.

-- Luke
-------------- next part --------------
Index: source/libads/ads_ldap.c
===================================================================
RCS file: /home/project/cvs/samba/source/libads/ads_ldap.c,v
retrieving revision 1.1.1.3
retrieving revision 1.2
diff -u -r1.1.1.3 -r1.2
--- source/libads/ads_ldap.c	2004/08/16 01:26:08	1.1.1.3
+++ source/libads/ads_ldap.c	2004/08/28 04:20:02	1.2
@@ -30,6 +30,15 @@
 			 DOM_SID *sid,
 			 enum SID_NAME_USE *type)
 {
+	return ads_name_to_sid_ex(ads, NULL, name, sid, type);
+}
+
+NTSTATUS ads_name_to_sid_ex(ADS_STRUCT *ads,
+			    const char *domain_name,
+			    const char *name,
+			    DOM_SID *sid,
+			    enum SID_NAME_USE *type)
+{
 	const char *attrs[] = {"objectSid", "sAMAccountType", NULL};
 	int count;
 	ADS_STATUS rc;
@@ -39,6 +48,7 @@
 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 	char *escaped_name = escape_ldap_string_alloc(name);
 	char *escaped_realm = escape_ldap_string_alloc(ads->config.realm);
+	char *bind_path;
 
 	if (!escaped_name || !escaped_realm) {
 		status = NT_STATUS_NO_MEMORY;
@@ -51,8 +61,36 @@
 		status = NT_STATUS_NO_MEMORY;
 		goto done;
 	}
+
+	if (domain_name != NULL) {
+		/*
+		 * Map NetBIOS name to a distinguished name.
+		 * XXX search cross-references to support non-local
+		 * domains on global catalog servers
+		 */
+		if (strequal(domain_name, ads->server.workgroup)) {
+			bind_path = NULL;
+		} else if (strequal(domain_name, "BUILTIN")) {
+			if (asprintf(&bind_path, "cn=Builtin,%s", ads->config.bind_path) == -1) {
+				DEBUG(1, ("ads_name_to_sid_ex: asprintf failed\n"));
+				status = NT_STATUS_NO_MEMORY;
+				goto done;
+			}
+		} else {
+			DEBUG(1, ("ads_name_to_sid_ex: could not map domain %s to DN\n",
+			      domain_name));
+			status = NT_STATUS_NO_SUCH_DOMAIN;
+			goto done;
+		}
+	} else {
+		bind_path = NULL;
+	}
 
-	rc = ads_search_retry(ads, &res, ldap_exp, attrs);
+	rc = ads_do_search_retry(ads,
+				 (bind_path == NULL) ? ads->config.bind_path : bind_path,
+				 LDAP_SCOPE_SUBTREE, ldap_exp, attrs, &res);
+	if (bind_path != NULL)
+		free(bind_path);
 	free(ldap_exp);
 	if (!ADS_ERR_OK(rc)) {
 		DEBUG(1,("name_to_sid ads_search: %s\n", ads_errstr(rc)));
Index: source/nsswitch/winbindd_ads.c
===================================================================
RCS file: /home/project/cvs/samba/source/nsswitch/winbindd_ads.c,v
retrieving revision 1.1.1.7
retrieving revision 1.2
diff -u -r1.1.1.7 -r1.2
--- source/nsswitch/winbindd_ads.c	2004/08/16 01:26:11	1.1.1.7
+++ source/nsswitch/winbindd_ads.c	2004/08/28 04:20:43	1.2
@@ -956,14 +956,101 @@
 	return ads_ntstatus(rc);	
 }
 
+#ifdef NCALRPC_FUNNEL
+/*
+ * Search local and builtin domains using LDAP, fall back to RPC
+ */
+/* convert a single name to a sid in a domain */
+static NTSTATUS name_to_sid(struct winbindd_domain *domain,
+			    TALLOC_CTX *mem_ctx,
+			    const char *domain_name,
+			    const char *name,
+			    DOM_SID *sid,
+			    enum SID_NAME_USE *type)
+{
+	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+	ADS_STRUCT *ads = NULL;
+	BOOL Builtin;
+	extern DOM_SID global_sid_Builtin;
+
+	DEBUG(3,("name_to_sid [ads] %s for domain %s\n", name, domain_name ));
+
+	Builtin = strequal(domain_name, "BUILTIN");
+
+	if (!strequal(domain_name, get_global_sam_name()) && !Builtin) {
+		return name_to_sid(domain, mem_ctx,
+				   domain_name, name,
+				   sid, type);
+	}
+
+	ads = ads_cached_connection(domain);
+	if (!ads) {
+		domain->last_status = NT_STATUS_SERVER_DISABLED;
+		return result;
+	}
+
+	result = ads_name_to_sid_ex(ads, domain_name, name, sid, type);
+
+	return result;
+}
+
+/*
+  convert a domain SID to a user or group name
+*/
+static NTSTATUS sid_to_name(struct winbindd_domain *domain,
+			    TALLOC_CTX *mem_ctx,
+			    const DOM_SID *sid,
+			    char **domain_name,
+			    char **name,
+			    enum SID_NAME_USE *type)
+{
+	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+	ADS_STATUS rc;
+	ADS_STRUCT *ads = NULL;
+	BOOL Builtin;
+	extern DOM_SID global_sid_Builtin;
+
+	DEBUG(3,("sid_to_name [ads] %s for domain %s\n", sid_string_static(sid),
+		domain->name ));
+
+	Builtin = (sid_compare_domain(sid, &global_sid_Builtin) == 0);
+
+	if (sid_compare_domain(sid, get_global_sam_sid()) != 0 && !Builtin) {
+		return msrpc_sid_to_name(domain, mem_ctx,
+					 sid, domain_name,
+					 name, type);
+	}
+
+	ads = ads_cached_connection(domain);
+	if (!ads) {
+		domain->last_status = NT_STATUS_SERVER_DISABLED;
+		return result;
+	}
+
+	result = ads_sid_to_name(ads, mem_ctx, sid, name, type);
+	if (Builtin) {
+		*domain_name = talloc_strdup(mem_ctx, "BUILTIN");
+	} else {
+		*domain_name = talloc_strdup(mem_ctx, get_global_sam_name());
+	}
+
+	return result;
+}
+#endif /* NCALRPC_FUNNEL */
+
 /* the ADS backend methods are exposed via this structure */
 struct winbindd_methods ads_methods = {
 	True,
 	query_user_list,
 	enum_dom_groups,
 	enum_local_groups,
+#ifdef NCALRPC_FUNNEL
+	name_to_sid,
+	sid_to_name,
+#else
 	msrpc_name_to_sid,
 	msrpc_sid_to_name,
+#endif
 	query_user,
 	lookup_usergroups,
 	lookup_groupmem,
@@ -974,3 +1061,4 @@
 };
 
 #endif
+
Index: source/nsswitch/winbindd_cache.c
===================================================================
RCS file: /home/project/cvs/samba/source/nsswitch/winbindd_cache.c,v
retrieving revision 1.1.1.7
retrieving revision 1.2
diff -u -r1.1.1.7 -r1.2
--- source/nsswitch/winbindd_cache.c	2004/08/16 01:26:11	1.1.1.7
+++ source/nsswitch/winbindd_cache.c	2004/08/28 04:18:52	1.2
@@ -619,7 +619,7 @@
 	fstrcpy(uname, name);
 	strupper_m(uname);
 	centry_end(centry, "NS/%s/%s", domain_name, uname);
-	DEBUG(10,("wcache_save_name_to_sid: %s -> %s\n", uname, sid_string));
+	DEBUG(10,("wcache_save_name_to_sid: %s -> %s\n", uname, sid_to_string(sid_string, sid)));
 	centry_free(centry);
 }
 


More information about the samba-technical mailing list