summaryrefslogtreecommitdiff
path: root/source3/libads
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libads')
-rw-r--r--source3/libads/ads_struct.c36
-rw-r--r--source3/libads/ldap.c22
2 files changed, 46 insertions, 12 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 |