#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;
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);
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
/*
return ADS_ERROR(ret);
}
+/*
+ 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
*/
{
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 |
char *dn;
void *res;
DOM_SID dom_sid;
+ char *ou_str;
if (argc > 0) org_unit = argv[0];
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));