diff options
author | Günther Deschner <gd@samba.org> | 2004-10-06 16:21:35 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:52:54 -0500 |
commit | 132879b285e66bff896c761858311d7f5d43e9b6 (patch) | |
tree | 106c6b70d2c93f2c8dbdecae2cc7f60d7da098a5 /source3 | |
parent | 4fd4aa1152732311178f1b1c70880d9efeccbaf6 (diff) | |
download | samba-132879b285e66bff896c761858311d7f5d43e9b6.tar.gz samba-132879b285e66bff896c761858311d7f5d43e9b6.tar.bz2 samba-132879b285e66bff896c761858311d7f5d43e9b6.zip |
r2832: Readd WKGUID-binding to match the correct default-locations of new
User-, Group- and Machine-Accounts in Active Directory (this got lost
during the last trunk-merge).
This way we match e.g. default containers moved by redircmp.exe and
redirusr.exe in Windows 2003 and don't blindly default to cn=Users or
cn=Computers.
Further wkguids can be examied via "net ads search wellknownobjects=*".
This should still keep a samba3-client joining a samba4 dc. Fixes
Bugzilla #1343.
Guenther
(This used to be commit 8836621694c95779475fa9a1acf158e5e0577288)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/ads.h | 3 | ||||
-rw-r--r-- | source3/libads/ldap.c | 77 | ||||
-rw-r--r-- | source3/utils/net.c | 2 | ||||
-rw-r--r-- | source3/utils/net_ads.c | 12 |
4 files changed, 87 insertions, 7 deletions
diff --git a/source3/include/ads.h b/source3/include/ads.h index 4daa65e796..de020f2a3f 100644 --- a/source3/include/ads.h +++ b/source3/include/ads.h @@ -224,3 +224,6 @@ typedef void **ADS_MODLIST; #ifndef HAVE_AP_OPTS_USE_SUBKEY #define AP_OPTS_USE_SUBKEY 0 #endif + +#define WELL_KNOWN_GUID_COMPUTERS "AA312825768811D1ADED00C04FD8D5CD" +#define WELL_KNOWN_GUID_USERS "A9D1CA15768811D1ADED00C04FD8D5CD" diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index d1539b83da..e5d2dfb8d3 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -995,12 +995,23 @@ ADS_STATUS ads_del_dn(ADS_STRUCT *ads, char *del_dn) * Build an org unit string * if org unit is Computers or blank then assume a container, otherwise * assume a \ separated list of organisational units + * @param ads connection to ads server * @param org_unit Organizational unit * @return org unit string - caller must free **/ -char *ads_ou_string(const char *org_unit) -{ - if (!org_unit || !*org_unit || strequal(org_unit, "Computers")) { +char *ads_ou_string(ADS_STRUCT *ads, const char *org_unit) +{ + char *ret = NULL; + + if (!org_unit || !*org_unit) { + + ret = ads_default_ou_string(ads, WELL_KNOWN_GUID_COMPUTERS); + + /* samba4 might not yet respond to a wellknownobject-query */ + return ret ? ret : strdup("cn=Computers"); + } + + if (strequal(org_unit, "Computers")) { return strdup("cn=Computers"); } @@ -1008,6 +1019,64 @@ char *ads_ou_string(const char *org_unit) } /** + * Get a org unit string for a well-known GUID + * @param ads connection to ads server + * @param wknguid Well known GUID + * @return org unit string - caller must free + **/ +char *ads_default_ou_string(ADS_STRUCT *ads, const char *wknguid) +{ + ADS_STATUS status; + void *res; + char *base, *wkn_dn, *ret, **wkn_dn_exp, **bind_dn_exp; + const char *attrs[] = {"distinguishedName", NULL}; + int new_ln, wkn_ln, bind_ln, i; + + if (wknguid == NULL) { + return NULL; + } + + if (asprintf(&base, "<WKGUID=%s,%s>", wknguid, ads->config.bind_path ) == -1) { + DEBUG(1, ("asprintf failed!\n")); + return NULL; + } + + status = ads_search_dn(ads, &res, base, attrs); + if (!ADS_ERR_OK(status)) { + DEBUG(1,("Failed while searching for: %s\n", base)); + return NULL; + } + free(base); + + if (ads_count_replies(ads, res) != 1) { + return NULL; + } + + /* substitute the bind-path from the well-known-guid-search result */ + wkn_dn = ads_get_dn(ads, res); + wkn_dn_exp = ldap_explode_dn(wkn_dn, 0); + bind_dn_exp = ldap_explode_dn(ads->config.bind_path, 0); + + for (wkn_ln=0; wkn_dn_exp[wkn_ln]; wkn_ln++) + ; + for (bind_ln=0; bind_dn_exp[bind_ln]; bind_ln++) + ; + + new_ln = wkn_ln - bind_ln; + + ret = wkn_dn_exp[0]; + + for (i=1; i < new_ln; i++) { + char *s; + asprintf(&s, "%s,%s", ret, wkn_dn_exp[i]); + ret = strdup(s); + free(s); + } + + return ret; +} + +/** * Adds (appends) an item to an attribute array, rather then * replacing the whole list * @param ctx An initialized TALLOC_CTX @@ -1283,7 +1352,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name machine_name)); exists=1; } else { - char *ou_str = ads_ou_string(org_unit); + char *ou_str = ads_ou_string(ads,org_unit); if (!ou_str) { DEBUG(1, ("ads_add_machine_acct: ads_ou_string returned NULL (malloc failure?)\n")); goto done; diff --git a/source3/utils/net.c b/source3/utils/net.c index da1339aed1..2bf8ac286d 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -69,7 +69,7 @@ int opt_port = 0; int opt_verbose = 0; int opt_maxusers = -1; const char *opt_comment = ""; -const char *opt_container = "cn=Users"; +const char *opt_container = NULL; int opt_flags = -1; int opt_timeout = 0; const char *opt_target_workgroup = NULL; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 70e9e6cea8..8afc42c456 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -297,6 +297,10 @@ static int ads_user_add(int argc, const char **argv) goto done; } + if (opt_container == NULL) { + opt_container = ads_default_ou_string(ads, WELL_KNOWN_GUID_USERS); + } + status = ads_add_user_acct(ads, argv[0], opt_container, opt_comment); if (!ADS_ERR_OK(status)) { @@ -498,6 +502,10 @@ static int ads_group_add(int argc, const char **argv) goto done; } + if (opt_container == NULL) { + opt_container = ads_default_ou_string(ads, WELL_KNOWN_GUID_USERS); + } + status = ads_add_group_acct(ads, argv[0], opt_container, opt_comment); if (ADS_ERR_OK(status)) { @@ -690,7 +698,7 @@ int net_ads_join(int argc, const char **argv) char *password; char *machine_account = NULL; char *tmp_password; - const char *org_unit = "Computers"; + const char *org_unit = NULL; char *dn; void *res; DOM_SID dom_sid; @@ -728,7 +736,7 @@ int net_ads_join(int argc, const char **argv) return -1; } - ou_str = ads_ou_string(org_unit); + ou_str = ads_ou_string(ads,org_unit); asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path); free(ou_str); |