diff options
author | Andrew Tridgell <tridge@samba.org> | 2002-01-16 02:22:30 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2002-01-16 02:22:30 +0000 |
commit | 9f85d4ad5f2bb5fdb7739b3f90c4bfac705393ce (patch) | |
tree | 013b7f83aeb828c9fb42591d07abab9d234f4e84 /source3 | |
parent | 3fee2ac712c5fe7a85b89ba3a3c19ab8801f0b22 (diff) | |
download | samba-9f85d4ad5f2bb5fdb7739b3f90c4bfac705393ce.tar.gz samba-9f85d4ad5f2bb5fdb7739b3f90c4bfac705393ce.tar.bz2 samba-9f85d4ad5f2bb5fdb7739b3f90c4bfac705393ce.zip |
much better support for organisational units in ADS join
(This used to be commit 7e876057d5e392f85e6fdb0f2c233b0fe76df688)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libads/ads_struct.c | 36 | ||||
-rw-r--r-- | source3/libads/ldap.c | 22 | ||||
-rw-r--r-- | source3/utils/net_ads.c | 10 |
3 files changed, 53 insertions, 15 deletions
diff --git a/source3/libads/ads_struct.c b/source3/libads/ads_struct.c index 013491eaed..476152f2c2 100644 --- a/source3/libads/ads_struct.c +++ b/source3/libads/ads_struct.c @@ -22,14 +22,13 @@ #include "includes.h" -/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a - realm of the form AA.BB.CC +/* return a ldap dn path from a string, given separators and field name caller must free */ -char *ads_build_dn(const char *realm) +char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse) { char *p, *r; - int numdots = 0; + int numbits = 0; char *ret; int len; @@ -38,19 +37,25 @@ char *ads_build_dn(const char *realm) if (!r || !*r) return r; for (p=r; *p; p++) { - if (*p == '.') numdots++; + if (strchr(sep, *p)) numbits++; } - len = (numdots+1)*4 + strlen(r) + 1; + len = (numbits+1)*(strlen(field)+1) + strlen(r) + 1; ret = malloc(len); - strlcpy(ret,"dc=", len); - p=strtok(r,"."); + strlcpy(ret,field, len); + p=strtok(r,sep); strlcat(ret, p, len); - while ((p=strtok(NULL,"."))) { - strlcat(ret,",dc=", len); - strlcat(ret, p, len); + while ((p=strtok(NULL,sep))) { + char *s; + if (reverse) { + asprintf(&s, "%s%s,%s", field, p, ret); + } else { + asprintf(&s, "%s,%s%s", ret, field, p); + } + free(ret); + ret = s; } free(r); @@ -58,6 +63,15 @@ char *ads_build_dn(const char *realm) return ret; } +/* return a dn of the form "dc=AA,dc=BB,dc=CC" from a + realm of the form AA.BB.CC + caller must free +*/ +char *ads_build_dn(const char *realm) +{ + return ads_build_path(realm, ".", "dc=", 0); +} + #ifdef HAVE_LDAP /* diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 2e93e11603..d922e4c7c5 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -173,6 +173,23 @@ ADS_STATUS ads_gen_add(ADS_STRUCT *ads, const char *new_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 + caller must free +*/ +char *ads_ou_string(const char *org_unit) +{ + if (!org_unit || !*org_unit || strcasecmp(org_unit, "Computers") == 0) { + return strdup("cn=Computers"); + } + + return ads_build_path(org_unit, "\\/", "ou=", 1); +} + + + +/* add a machine account to the ADS server */ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, @@ -180,10 +197,13 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, { ADS_STATUS ret; char *host_spn, *host_upn, *new_dn, *samAccountName, *controlstr; + char *ou_str; asprintf(&host_spn, "HOST/%s", hostname); asprintf(&host_upn, "%s@%s", host_spn, ads->realm); - asprintf(&new_dn, "cn=%s,cn=%s,%s", hostname, org_unit, ads->bind_path); + ou_str = ads_ou_string(org_unit); + asprintf(&new_dn, "cn=%s,%s,%s", hostname, ou_str, ads->bind_path); + free(ou_str); asprintf(&samAccountName, "%s$", hostname); asprintf(&controlstr, "%u", UF_DONT_EXPIRE_PASSWD | UF_WORKSTATION_TRUST_ACCOUNT | diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 7baa297230..fec31c6ea3 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -211,6 +211,7 @@ static int net_ads_join(int argc, const char **argv) char *dn; void *res; DOM_SID dom_sid; + char *ou_str; if (argc > 0) org_unit = argv[0]; @@ -224,16 +225,19 @@ static int net_ads_join(int argc, const char **argv) if (!(ads = ads_startup())) return -1; - asprintf(&dn, "cn=%s,%s", org_unit, ads->bind_path); + ou_str = ads_ou_string(org_unit); + asprintf(&dn, "%s,%s", ou_str, ads->bind_path); + free(ou_str); rc = ads_search_dn(ads, &res, dn, NULL); - free(dn); ads_msgfree(ads, res); if (rc.error_type == ADS_ERROR_LDAP && rc.rc == LDAP_NO_SUCH_OBJECT) { - d_printf("ads_join_realm: organisational unit %s does not exist\n", org_unit); + d_printf("ads_join_realm: organisational unit %s does not exist (dn:%s)\n", + org_unit, dn); return -1; } + free(dn); if (!ADS_ERR_OK(rc)) { d_printf("ads_join_realm: %s\n", ads_errstr(rc)); |