]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r2832: Readd WKGUID-binding to match the correct default-locations of new
authorGünther Deschner <gd@samba.org>
Wed, 6 Oct 2004 16:21:35 +0000 (16:21 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:52:54 +0000 (10:52 -0500)
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

source/include/ads.h
source/libads/ldap.c
source/utils/net.c
source/utils/net_ads.c

index 4daa65e796d2cdb2293cce36be6d7d49e577b6b7..de020f2a3f48dd25bb616a4247c9428cf8fc87ac 100644 (file)
@@ -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"
index d1539b83da73241eab2c4d2659c26ccdadec7a51..e5d2dfb8d3f2d9c68b562771c239e74ac2220755 100644 (file)
@@ -995,18 +995,87 @@ 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");
        }
 
        return ads_build_path(org_unit, "\\/", "ou=", 1);
 }
 
+/**
+ * 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
@@ -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;
index da1339aed10c132cdc2cd472d9c63b02592bf0d9..2bf8ac286dd7e9dd2c5f7162c68ef1858a222cd1 100644 (file)
@@ -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;
index 70e9e6cea80856591dbaf7714e066fcf6dc65824..8afc42c456bb0b29b56d37dbdc978b427782b53c 100644 (file)
@@ -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);