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