summaryrefslogtreecommitdiff
path: root/source3/libads/ldap.c
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2002-03-10 01:54:44 +0000
committerAndrew Tridgell <tridge@samba.org>2002-03-10 01:54:44 +0000
commitcfbbf736777aca366e388882a389a214b87ca612 (patch)
treef048decf972c08834b4dde8b3f29148a3c444e92 /source3/libads/ldap.c
parent9b9d681870453c488a3c258ce7b56c5d250f3dc7 (diff)
downloadsamba-cfbbf736777aca366e388882a389a214b87ca612.tar.gz
samba-cfbbf736777aca366e388882a389a214b87ca612.tar.bz2
samba-cfbbf736777aca366e388882a389a214b87ca612.zip
yipee! Finally put in the patch from Alexey Kotovich
<a.kotovich@sam-solutions.net> that adds the security decsriptor code for ADS workstation accounts thanks for your patience Cat, and thanks to Andrew Bartlett for extensive reviews and suggestions about this code. (This used to be commit 6891393b5db868246fe52ff62b3dc6aa5ca6f726)
Diffstat (limited to 'source3/libads/ldap.c')
-rw-r--r--source3/libads/ldap.c129
1 files changed, 121 insertions, 8 deletions
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index ef1902960f..a8f9298b0f 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -180,7 +180,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx)
add an attribute to the list, with values list already constructed
*/
static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- int mod_op, char *name, char **values)
+ int mod_op, const char *name, char **values)
{
int curmod;
LDAPMod **modlist = (LDAPMod **) *mods;
@@ -238,7 +238,7 @@ ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods,
add an attribute to the list, with values list to be built from args
*/
ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- int mod_op, char *name, ...)
+ int mod_op, const char *name, ...)
{
va_list ap;
int num_vals, i, do_op;
@@ -267,7 +267,7 @@ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods,
}
ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- int mod_op, char *name, ...)
+ int mod_op, const char *name, ...)
{
va_list ap;
int num_vals, i, do_op;
@@ -308,7 +308,7 @@ ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods,
}
ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- char *name, char *val)
+ const char *name, const char *val)
{
return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL);
}
@@ -329,7 +329,7 @@ ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods,
}
ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods,
- char *name, size_t size, char *val)
+ const char *name, size_t size, char *val)
{
struct berval *bval = NULL;
@@ -457,7 +457,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname,
ads_mod_add(ctx, &mods, "operatingSystem", "Samba");
ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION);
- ret = ads_gen_add(ads, new_dn, mods);
+ ads_gen_add(ads, new_dn, mods);
+ ret = ads_set_machine_sd(ads, hostname, new_dn);
done:
talloc_destroy(ctx);
@@ -493,6 +494,36 @@ static void dump_sid(const char *field, struct berval **values)
}
/*
+ dump ntSecurityDescriptor
+*/
+static void dump_sd(const char *filed, struct berval **values)
+{
+ prs_struct ps;
+
+ SEC_DESC *psd = 0;
+ TALLOC_CTX *ctx = 0;
+
+ if (!(ctx = talloc_init_named("sec_io_desc")))
+ return;
+
+ /* prepare data */
+ prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL);
+ prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len);
+ ps.data_offset = 0;
+
+ /* parse secdesc */
+ if (!sec_io_desc("sd", &psd, &ps, 1)) {
+ prs_mem_free(&ps);
+ talloc_destroy(ctx);
+ return;
+ }
+ if (psd) ads_disp_sd(psd);
+
+ prs_mem_free(&ps);
+ talloc_destroy(ctx);
+}
+
+/*
dump a string result from ldap
*/
static void dump_string(const char *field, struct berval **values)
@@ -517,7 +548,7 @@ void ads_dump(ADS_STRUCT *ads, void *res)
void (*handler)(const char *, struct berval **);
} handlers[] = {
{"objectGUID", dump_binary},
- {"nTSecurityDescriptor", dump_binary},
+ {"nTSecurityDescriptor", dump_sd},
{"objectSid", dump_sid},
{NULL, NULL}
};
@@ -573,7 +604,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org
status = ads_find_machine_acct(ads, (void **)&res, host);
if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) {
- DEBUG(0, ("Host account for %s already exists - deleting for readd\n", host));
+ DEBUG(0, ("Host account for %s already exists - deleting old account\n", host));
status = ads_leave_realm(ads, host);
if (!ADS_ERR_OK(status)) {
DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n",
@@ -637,6 +668,83 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname)
return status;
}
+/*
+ add machine account to existing security descriptor
+*/
+ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn)
+{
+ const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0};
+ char *exp = 0;
+ size_t sd_size = 0;
+ struct berval **bvals = 0;
+ prs_struct ps;
+ prs_struct ps_wire;
+
+ LDAPMessage *res = 0;
+ LDAPMessage *msg = 0;
+ ADS_MODLIST mods = 0;
+
+ NTSTATUS status;
+ ADS_STATUS ret;
+ DOM_SID sid;
+ SEC_DESC *psd = 0;
+ TALLOC_CTX *ctx = 0;
+
+ if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN);
+
+ ret = ADS_ERROR(LDAP_SUCCESS);
+
+ asprintf(&exp, "(samAccountName=%s$)", hostname);
+ ret = ads_search(ads, (void *) &res, exp, attrs);
+
+ if (!ADS_ERR_OK(ret)) return ret;
+
+ msg = ads_first_entry(ads, res);
+ bvals = ldap_get_values_len(ads->ld, msg, attrs[0]);
+ ads_pull_sid(ads, msg, attrs[1], &sid);
+ ads_msgfree(ads, res);
+#if 0
+ file_save("/tmp/sec_desc.old", bvals[0]->bv_val, bvals[0]->bv_len);
+#endif
+ if (!(ctx = talloc_init_named("sec_io_desc")))
+ return ADS_ERROR(LDAP_NO_MEMORY);
+
+ prs_init(&ps, bvals[0]->bv_len, ctx, UNMARSHALL);
+ prs_append_data(&ps, bvals[0]->bv_val, bvals[0]->bv_len);
+ ps.data_offset = 0;
+ ldap_value_free_len(bvals);
+
+ if (!sec_io_desc("sd", &psd, &ps, 1))
+ goto ads_set_sd_error;
+
+ status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size);
+
+ if (!NT_STATUS_IS_OK(status))
+ goto ads_set_sd_error;
+
+ prs_init(&ps_wire, sd_size, ctx, MARSHALL);
+ if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1))
+ goto ads_set_sd_error;
+
+#if 0
+ file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size);
+#endif
+ if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY);
+
+ ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, ps_wire.data_p);
+ ret = ads_gen_mod(ads, dn, mods);
+
+ prs_mem_free(&ps);
+ prs_mem_free(&ps_wire);
+ talloc_destroy(ctx);
+ return ret;
+
+ads_set_sd_error:
+ prs_mem_free(&ps);
+ prs_mem_free(&ps_wire);
+ talloc_destroy(ctx);
+ return ADS_ERROR(LDAP_NO_MEMORY);
+}
ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
const char *hostname,
@@ -646,6 +754,11 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads,
char *host = strdup(hostname);
char *principal;
+ if (!ads->kdc_server) {
+ DEBUG(0, ("Unable to find KDC server\n"));
+ return ADS_ERROR(LDAP_SERVER_DOWN);
+ }
+
strlower(host);
asprintf(&principal, "%s@%s", host, ads->realm);