mirror of
https://github.com/samba-team/samba.git
synced 2025-02-08 05:57:51 +03:00
s3:libads: Fix creating machine account using LDAP
This implements the same behaviour as Windows. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13884 Pair-Programmed-With: Guenther Deschner <gd@samba.org> Signed-off-by: Guenther Deschner <gd@samba.org> Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org> (cherry picked from commit ce7762935051c862ecdd3e82d93096aac61dd292)
This commit is contained in:
parent
ac8c51fbb5
commit
1e38443496
@ -114,8 +114,10 @@ ADS_STATUS ads_add_service_principal_names(ADS_STRUCT *ads, const char *machine_
|
||||
const char **spns);
|
||||
ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
|
||||
const char *machine_name,
|
||||
const char *machine_password,
|
||||
const char *org_unit,
|
||||
uint32_t etype_list);
|
||||
uint32_t etype_list,
|
||||
const char *dns_domain_name);
|
||||
ADS_STATUS ads_move_machine_acct(ADS_STRUCT *ads, const char *machine_name,
|
||||
const char *org_unit, bool *moved);
|
||||
int ads_count_replies(ADS_STRUCT *ads, void *res);
|
||||
|
@ -1516,7 +1516,6 @@ ADS_STATUS ads_mod_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods,
|
||||
name, (const void **) vals);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Add a single ber-encoded value to a mod list
|
||||
* @param ctx An initialized TALLOC_CTX
|
||||
@ -1537,7 +1536,6 @@ static ADS_STATUS ads_mod_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods,
|
||||
return ads_modlist_add(ctx, mods, LDAP_MOD_REPLACE|LDAP_MOD_BVALUES,
|
||||
name, (const void **) values);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ads_print_error(int ret, LDAP *ld)
|
||||
{
|
||||
@ -2111,8 +2109,10 @@ ADS_STATUS ads_add_service_principal_names(ADS_STRUCT *ads,
|
||||
|
||||
ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
|
||||
const char *machine_name,
|
||||
const char *machine_password,
|
||||
const char *org_unit,
|
||||
uint32_t etype_list)
|
||||
uint32_t etype_list,
|
||||
const char *dns_domain_name)
|
||||
{
|
||||
ADS_STATUS ret;
|
||||
char *samAccountName = NULL;
|
||||
@ -2120,13 +2120,23 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
|
||||
TALLOC_CTX *ctx = NULL;
|
||||
ADS_MODLIST mods;
|
||||
char *machine_escaped = NULL;
|
||||
char *dns_hostname = NULL;
|
||||
char *new_dn = NULL;
|
||||
const char *objectClass[] = {"top", "person", "organizationalPerson",
|
||||
"user", "computer", NULL};
|
||||
char *utf8_pw = NULL;
|
||||
size_t utf8_pw_len = 0;
|
||||
char *utf16_pw = NULL;
|
||||
size_t utf16_pw_len = 0;
|
||||
struct berval machine_pw_val;
|
||||
bool ok;
|
||||
const char **spn_array = NULL;
|
||||
size_t num_spns = 0;
|
||||
const char *spn_prefix[] = {
|
||||
"HOST",
|
||||
"RestrictedKrbHost",
|
||||
};
|
||||
size_t i;
|
||||
LDAPMessage *res = NULL;
|
||||
uint32_t acct_control = ( UF_WORKSTATION_TRUST_ACCOUNT |\
|
||||
UF_DONT_EXPIRE_PASSWD |\
|
||||
UF_ACCOUNTDISABLE );
|
||||
uint32_t acct_control = UF_WORKSTATION_TRUST_ACCOUNT;
|
||||
|
||||
ctx = talloc_init("ads_add_machine_acct");
|
||||
if (ctx == NULL) {
|
||||
@ -2139,10 +2149,9 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check if the machine account already exists. */
|
||||
ret = ads_find_machine_acct(ads, &res, machine_escaped);
|
||||
if (ADS_ERR_OK(ret)) {
|
||||
DBG_DEBUG("Host account for %s already exists.\n",
|
||||
machine_escaped);
|
||||
ret = ADS_ERROR_LDAP(LDAP_ALREADY_EXISTS);
|
||||
ads_msgfree(ads, res);
|
||||
goto done;
|
||||
@ -2155,28 +2164,111 @@ ADS_STATUS ads_create_machine_acct(ADS_STRUCT *ads,
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Create machine account */
|
||||
|
||||
samAccountName = talloc_asprintf(ctx, "%s$", machine_name);
|
||||
if (samAccountName == NULL) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
dns_hostname = talloc_asprintf(ctx,
|
||||
"%s.%s",
|
||||
machine_name,
|
||||
dns_domain_name);
|
||||
if (dns_hostname == NULL) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Add dns_hostname SPNs */
|
||||
for (i = 0; i < ARRAY_SIZE(spn_prefix); i++) {
|
||||
char *spn = talloc_asprintf(ctx,
|
||||
"%s/%s",
|
||||
spn_prefix[i],
|
||||
dns_hostname);
|
||||
if (spn == NULL) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ok = add_string_to_array(spn_array,
|
||||
spn,
|
||||
&spn_array,
|
||||
&num_spns);
|
||||
if (!ok) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add machine_name SPNs */
|
||||
for (i = 0; i < ARRAY_SIZE(spn_prefix); i++) {
|
||||
char *spn = talloc_asprintf(ctx,
|
||||
"%s/%s",
|
||||
spn_prefix[i],
|
||||
machine_name);
|
||||
if (spn == NULL) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ok = add_string_to_array(spn_array,
|
||||
spn,
|
||||
&spn_array,
|
||||
&num_spns);
|
||||
if (!ok) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure to NULL terminate the array */
|
||||
spn_array = talloc_realloc(ctx, spn_array, const char *, num_spns + 1);
|
||||
if (spn_array == NULL) {
|
||||
return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
|
||||
}
|
||||
spn_array[num_spns] = NULL;
|
||||
|
||||
controlstr = talloc_asprintf(ctx, "%u", acct_control);
|
||||
if (controlstr == NULL) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
utf8_pw = talloc_asprintf(ctx, "\"%s\"", machine_password);
|
||||
if (utf8_pw == NULL) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
utf8_pw_len = strlen(utf8_pw);
|
||||
|
||||
ok = convert_string_talloc(ctx,
|
||||
CH_UTF8, CH_UTF16MUNGED,
|
||||
utf8_pw, utf8_pw_len,
|
||||
(void *)&utf16_pw, &utf16_pw_len);
|
||||
if (!ok) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
machine_pw_val = (struct berval) {
|
||||
.bv_val = utf16_pw,
|
||||
.bv_len = utf16_pw_len,
|
||||
};
|
||||
|
||||
mods = ads_init_mods(ctx);
|
||||
if (mods == NULL) {
|
||||
ret = ADS_ERROR(LDAP_NO_MEMORY);
|
||||
goto done;
|
||||
}
|
||||
|
||||
ads_mod_str(ctx, &mods, "cn", machine_name);
|
||||
ads_mod_str(ctx, &mods, "sAMAccountName", samAccountName);
|
||||
ads_mod_strlist(ctx, &mods, "objectClass", objectClass);
|
||||
ads_mod_str(ctx, &mods, "objectClass", "Computer");
|
||||
ads_mod_str(ctx, &mods, "SamAccountName", samAccountName);
|
||||
ads_mod_str(ctx, &mods, "userAccountControl", controlstr);
|
||||
ads_mod_str(ctx, &mods, "DnsHostName", dns_hostname);
|
||||
ads_mod_strlist(ctx, &mods, "ServicePrincipalName", spn_array);
|
||||
ads_mod_ber(ctx, &mods, "unicodePwd", &machine_pw_val);
|
||||
|
||||
ret = ads_gen_add(ads, new_dn, mods);
|
||||
|
||||
|
@ -338,10 +338,22 @@ static ADS_STATUS libnet_join_precreate_machine_acct(TALLOC_CTX *mem_ctx,
|
||||
/* Attempt to create the machine account and bail if this fails.
|
||||
Assume that the admin wants exactly what they requested */
|
||||
|
||||
if (r->in.machine_password == NULL) {
|
||||
r->in.machine_password =
|
||||
trust_pw_new_value(mem_ctx,
|
||||
r->in.secure_channel_type,
|
||||
SEC_ADS);
|
||||
if (r->in.machine_password == NULL) {
|
||||
return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
status = ads_create_machine_acct(r->in.ads,
|
||||
r->in.machine_name,
|
||||
r->in.machine_password,
|
||||
r->in.account_ou,
|
||||
r->in.desired_encryption_types);
|
||||
r->in.desired_encryption_types,
|
||||
r->out.dns_domain_name);
|
||||
|
||||
if (ADS_ERR_OK(status)) {
|
||||
DEBUG(1,("machine account creation created\n"));
|
||||
@ -2668,12 +2680,11 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
|
||||
if (ADS_ERR_OK(ads_status)) {
|
||||
|
||||
/*
|
||||
* LDAP object create succeeded, now go to the rpc
|
||||
* password set routines
|
||||
* LDAP object creation succeeded.
|
||||
*/
|
||||
|
||||
r->in.join_flags &= ~WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
|
||||
goto rpc_join;
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
if (initial_account_ou != NULL) {
|
||||
@ -2687,8 +2698,6 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
|
||||
DBG_INFO("Failed to pre-create account in OU %s: %s\n",
|
||||
r->in.account_ou, ads_errstr(ads_status));
|
||||
}
|
||||
rpc_join:
|
||||
|
||||
#endif /* HAVE_ADS */
|
||||
|
||||
if ((r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE) &&
|
||||
|
Loading…
x
Reference in New Issue
Block a user