summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2002-01-16 02:22:30 +0000
committerAndrew Tridgell <tridge@samba.org>2002-01-16 02:22:30 +0000
commit9f85d4ad5f2bb5fdb7739b3f90c4bfac705393ce (patch)
tree013b7f83aeb828c9fb42591d07abab9d234f4e84 /source3
parent3fee2ac712c5fe7a85b89ba3a3c19ab8801f0b22 (diff)
downloadsamba-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.c36
-rw-r--r--source3/libads/ldap.c22
-rw-r--r--source3/utils/net_ads.c10
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));