diff options
author | Matthias Dieter Wallnöfer <mdw@samba.org> | 2010-04-13 18:28:53 +0200 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-04-27 15:24:41 +1000 |
commit | 093d35661d25d7fd89ce46fef5922768c0c0ace7 (patch) | |
tree | 7ed0b265e283b0176d173d2b03499fa1d19d75b6 /source4/dsdb | |
parent | 725e48c22c92e284bb55567f2116c8ddc82a0529 (diff) | |
download | samba-093d35661d25d7fd89ce46fef5922768c0c0ace7.tar.gz samba-093d35661d25d7fd89ce46fef5922768c0c0ace7.tar.bz2 samba-093d35661d25d7fd89ce46fef5922768c0c0ace7.zip |
s4:util - add a function which finds the matching client site using the client address
The lookup of the client site is done using the subnets in the configuration
partition. If no one matches we use the Windows Server fallback mechansim.
This means: if only one site is available just use it. If they're more set the
output variable to "".
Signed-off-by: Andrew Tridgell <tridge@samba.org>
Diffstat (limited to 'source4/dsdb')
-rw-r--r-- | source4/dsdb/common/util.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 3a04797f82..7dd68b8b99 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -40,6 +40,7 @@ #include "system/locale.h" #include "lib/util/tsort.h" #include "dsdb/common/util.h" +#include "lib/socket/socket.h" /* search the sam for the specified attributes in a specific domain, filter on @@ -1593,6 +1594,95 @@ const char *samdb_server_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx) } /* + * Finds the client site by using the client's IP address. + * The "subnet_name" returns the name of the subnet if parameter != NULL + */ +const char *samdb_client_site_name(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, + const char *ip_address, char **subnet_name) +{ + const char *attrs[] = { "cn", "siteObject", NULL }; + struct ldb_dn *sites_container_dn, *subnets_dn, *sites_dn; + struct ldb_result *res; + const struct ldb_val *val; + const char *site_name = NULL, *l_subnet_name = NULL; + const char *allow_list[2] = { NULL, NULL }; + unsigned int i; + int cnt, ret; + + sites_container_dn = samdb_sites_dn(ldb, mem_ctx); + if (sites_container_dn == NULL) { + return NULL; + } + + subnets_dn = ldb_dn_copy(mem_ctx, sites_container_dn); + if ( ! ldb_dn_add_child_fmt(subnets_dn, "CN=Subnets")) { + talloc_free(sites_container_dn); + talloc_free(subnets_dn); + return NULL; + } + + ret = ldb_search(ldb, mem_ctx, &res, subnets_dn, LDB_SCOPE_ONELEVEL, + attrs, NULL); + if (ret != LDB_SUCCESS) { + talloc_free(sites_container_dn); + talloc_free(subnets_dn); + return NULL; + } + + for (i = 0; i < res->count; i++) { + l_subnet_name = ldb_msg_find_attr_as_string(res->msgs[i], "cn", + NULL); + + allow_list[0] = l_subnet_name; + + if (allow_access(mem_ctx, NULL, allow_list, "", ip_address)) { + sites_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, + res->msgs[i], + "siteObject"); + if (sites_dn == NULL) { + /* No reference, maybe another subnet matches */ + continue; + } + + /* "val" cannot be NULL here since "sites_dn" != NULL */ + val = ldb_dn_get_rdn_val(sites_dn); + site_name = talloc_strdup(mem_ctx, + (const char *) val->data); + + talloc_free(sites_dn); + + break; + } + } + + if (site_name == NULL) { + /* This is the Windows Server fallback rule: when no subnet + * exists and we have only one site available then use it (it + * is for sure the same as our server site). If more sites do + * exist then we don't know which one to use and set the site + * name to "". */ + cnt = samdb_search_count(ldb, sites_container_dn, + "(objectClass=site)"); + if (cnt == 1) { + site_name = samdb_server_site_name(ldb, mem_ctx); + } else { + site_name = talloc_strdup(mem_ctx, ""); + } + l_subnet_name = NULL; + } + + if (subnet_name != NULL) { + *subnet_name = talloc_strdup(mem_ctx, l_subnet_name); + } + + talloc_free(sites_container_dn); + talloc_free(subnets_dn); + talloc_free(res); + + return site_name; +} + +/* work out if we are the PDC for the domain of the current open ldb */ bool samdb_is_pdc(struct ldb_context *ldb) |