From d1221c9b6c369113a531063737890b58d89bf6fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:55:00 +0000 Subject: Merge from HEAD client-side authentication changes: - new kerberos code, allowing the account to change it's own password without special SD settings required - NTLMSSP client code, now seperated from cliconnect.c - NTLMv2 client code - SMB signing fixes Andrew Bartlett (This used to be commit 837680ca517982f2e5944730581a83012d4181ae) --- source3/libads/krb5_setpw.c | 429 +++++++++++++++++++++++++++++++------------- source3/libads/ldap.c | 51 ++++-- source3/libads/sasl.c | 7 +- source3/libads/util.c | 10 +- 4 files changed, 351 insertions(+), 146 deletions(-) (limited to 'source3/libads') diff --git a/source3/libads/krb5_setpw.c b/source3/libads/krb5_setpw.c index 087b0e9a71..9d8fb8d24c 100644 --- a/source3/libads/krb5_setpw.c +++ b/source3/libads/krb5_setpw.c @@ -24,13 +24,23 @@ #ifdef HAVE_KRB5 #define DEFAULT_KPASSWD_PORT 464 -#define KRB5_KPASSWD_VERS_CHANGEPW 1 -#define KRB5_KPASSWD_VERS_SETPW 0xff80 -#define KRB5_KPASSWD_ACCESSDENIED 5 -#define KRB5_KPASSWD_BAD_VERSION 6 - -/* This implements the Kerb password change protocol as specifed in - * kerb-chg-password-02.txt +#define KRB5_KPASSWD_VERS_CHANGEPW 1 +#define KRB5_KPASSWD_VERS_SETPW 2 +#define KRB5_KPASSWD_VERS_SETPW_MS 0xff80 +#define KRB5_KPASSWD_ACCESSDENIED 5 +#define KRB5_KPASSWD_BAD_VERSION 6 +#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7 + +/* Those are defined by kerberos-set-passwd-02.txt and are probably + * not supported by M$ implementation */ +#define KRB5_KPASSWD_POLICY_REJECT 8 +#define KRB5_KPASSWD_BAD_PRINCIPAL 9 +#define KRB5_KPASSWD_ETYPE_NOSUPP 10 + +/* This implements kerberos password change protocol as specified in + * kerb-chg-password-02.txt and kerberos-set-passwd-02.txt + * as well as microsoft version of the protocol + * as specified in kerberos-set-passwd-00.txt */ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) { @@ -101,7 +111,8 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password) return ret; } -static krb5_error_code build_setpw_request(krb5_context context, +static krb5_error_code build_kpasswd_request(uint16 pversion, + krb5_context context, krb5_auth_context auth_context, krb5_data *ap_req, const char *princ, @@ -123,7 +134,14 @@ static krb5_error_code build_setpw_request(krb5_context context, return ret; } - setpw = encode_krb5_setpw(princ, passwd); + /* handle protocol differences in chpw and setpw */ + if (pversion == KRB5_KPASSWD_VERS_CHANGEPW) + setpw = data_blob(passwd, strlen(passwd)); + else if (pversion == KRB5_KPASSWD_VERS_SETPW || + pversion == KRB5_KPASSWD_VERS_SETPW_MS) + setpw = encode_krb5_setpw(princ, passwd); + else + return EINVAL; encoded_setpw.data = setpw.data; encoded_setpw.length = setpw.length; @@ -144,7 +162,7 @@ static krb5_error_code build_setpw_request(krb5_context context, /* see the RFC for details */ p = ((char *)packet->data) + 2; - RSSVAL(p, 0, 0xff80); + RSSVAL(p, 0, pversion); p += 2; RSSVAL(p, 0, ap_req->length); p += 2; @@ -160,6 +178,49 @@ static krb5_error_code build_setpw_request(krb5_context context, return 0; } +static krb5_error_code krb5_setpw_result_code_string(krb5_context context, + int result_code, + char **code_string) +{ + switch (result_code) { + case KRB5_KPASSWD_MALFORMED: + *code_string = "Malformed request error"; + break; + case KRB5_KPASSWD_HARDERROR: + *code_string = "Server error"; + break; + case KRB5_KPASSWD_AUTHERROR: + *code_string = "Authentication error"; + break; + case KRB5_KPASSWD_SOFTERROR: + *code_string = "Password change rejected"; + break; + case KRB5_KPASSWD_ACCESSDENIED: + *code_string = "Client does not have proper authorization"; + break; + case KRB5_KPASSWD_BAD_VERSION: + *code_string = "Protocol version not supported"; + break; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + *code_string = "Authorization ticket must have initial flag set"; + break; + case KRB5_KPASSWD_POLICY_REJECT: + *code_string = "Password rejected due to policy requirements"; + break; + case KRB5_KPASSWD_BAD_PRINCIPAL: + *code_string = "Target principal does not exist"; + break; + case KRB5_KPASSWD_ETYPE_NOSUPP: + *code_string = "Unsupported encryption type"; + break; + default: + *code_string = "Password change failed"; + break; + } + + return(0); +} + static krb5_error_code parse_setpw_reply(krb5_context context, krb5_auth_context auth_context, krb5_data *packet) @@ -194,8 +255,11 @@ static krb5_error_code parse_setpw_reply(krb5_context context, p += 2; vnum = RSVAL(p, 0); p += 2; - - if (vnum != KRB5_KPASSWD_VERS_SETPW && vnum != KRB5_KPASSWD_VERS_CHANGEPW) { + + /* FIXME: According to standard there is only one type of reply */ + if (vnum != KRB5_KPASSWD_VERS_SETPW && + vnum != KRB5_KPASSWD_VERS_SETPW_MS && + vnum != KRB5_KPASSWD_VERS_CHANGEPW) { DEBUG(1,("Bad vnum (%d) from kpasswd server\n", vnum)); return KRB5KDC_ERR_BAD_PVNO; } @@ -247,96 +311,57 @@ static krb5_error_code parse_setpw_reply(krb5_context context, free(clearresult.data); if ((res_code < KRB5_KPASSWD_SUCCESS) || - (res_code >= KRB5_KPASSWD_ACCESSDENIED)) { + (res_code > KRB5_KPASSWD_ETYPE_NOSUPP)) { return KRB5KRB_AP_ERR_MODIFIED; } - - return 0; + + if(res_code == KRB5_KPASSWD_SUCCESS) + return 0; + else { + char *errstr; + krb5_setpw_result_code_string(context, res_code, &errstr); + DEBUG(1, ("Error changing password: %s\n", errstr)); + + switch(res_code) { + case KRB5_KPASSWD_ACCESSDENIED: + return KRB5KDC_ERR_BADOPTION; + break; + case KRB5_KPASSWD_INITIAL_FLAG_NEEDED: + return KRB5KDC_ERR_BADOPTION; + /* return KV5M_ALT_METHOD; MIT-only define */ + break; + case KRB5_KPASSWD_ETYPE_NOSUPP: + return KRB5KDC_ERR_ETYPE_NOSUPP; + break; + case KRB5_KPASSWD_BAD_PRINCIPAL: + return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + break; + case KRB5_KPASSWD_POLICY_REJECT: + return KRB5KDC_ERR_POLICY; + break; + default: + return KRB5KRB_ERR_GENERIC; + break; + } + } } -ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, - int time_offset) +static ADS_STATUS do_krb5_kpasswd_request(krb5_context context, + const char *kdc_host, + uint16 pversion, + krb5_creds *credsp, + const char *princ, + const char *newpw) { - krb5_context context; krb5_auth_context auth_context = NULL; - krb5_principal principal; - char *princ_name; - char *realm; - krb5_creds creds, *credsp; - krb5_ccache ccache; krb5_data ap_req, chpw_req, chpw_rep; int ret, sock, addr_len; struct sockaddr remote_addr, local_addr; krb5_address local_kaddr, remote_kaddr; - ret = krb5_init_context(&context); - if (ret) { - DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - if (time_offset != 0) { - krb5_set_real_time(context, time(NULL) + time_offset, 0); - } - - ret = krb5_cc_default(context, &ccache); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ZERO_STRUCT(creds); - - realm = strchr(princ, '@'); - realm++; - - asprintf(&princ_name, "kadmin/changepw@%s", realm); - ret = krb5_parse_name(context, princ_name, &creds.server); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - free(princ_name); - - /* parse the principal we got as a function argument */ - ret = krb5_parse_name(context, princ, &principal); - if (ret) { - krb5_free_context(context); - DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - krb5_princ_set_realm(context, creds.server, - krb5_princ_realm(context, principal)); - - ret = krb5_cc_get_principal(context, ccache, &creds.client); - if (ret) { - krb5_free_principal(context, principal); - krb5_free_context(context); - DEBUG(1,("Failed to get principal from ccache (%s)\n", - error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); - if (ret) { - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); - DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); - return ADS_ERROR_KRB5(ret); - } - - /* we might have to call krb5_free_creds(...) from now on ... */ ret = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY, NULL, credsp, &ap_req); if (ret) { - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); DEBUG(1,("krb5_mk_req_extended failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -345,10 +370,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (sock == -1) { int rc = errno; free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("failed to open kpasswd socket to %s (%s)\n", kdc_host, strerror(errno))); return ADS_ERROR_SYSTEM(rc); @@ -366,23 +388,17 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("krb5_auth_con_setaddrs failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } - ret = build_setpw_request(context, auth_context, &ap_req, + ret = build_kpasswd_request(pversion, context, auth_context, &ap_req, princ, newpw, &chpw_req); if (ret) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("build_setpw_request failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } @@ -391,10 +407,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char close(sock); free(chpw_req.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -406,10 +419,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (!chpw_rep.data) { close(sock); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("send of chpw failed (%s)\n", strerror(errno))); errno = ENOMEM; return ADS_ERROR_SYSTEM(errno); @@ -420,10 +430,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char close(sock); free(chpw_rep.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("recv of chpw reply failed (%s)\n", strerror(errno))); return ADS_ERROR_SYSTEM(errno); } @@ -435,10 +442,7 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { free(chpw_rep.data); free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("krb5_auth_con_setaddrs on reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); @@ -449,22 +453,194 @@ ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char if (ret) { free(ap_req.data); - krb5_free_creds(context, credsp); - krb5_free_principal(context, creds.client); - krb5_free_principal(context, principal); - krb5_free_context(context); + krb5_auth_con_free(context, auth_context); DEBUG(1,("parse_setpw_reply failed (%s)\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } free(ap_req.data); + krb5_auth_con_free(context, auth_context); + + return ADS_SUCCESS; +} + +ADS_STATUS krb5_set_password(const char *kdc_host, const char *princ, const char *newpw, + int time_offset) +{ + + ADS_STATUS aret; + krb5_error_code ret; + krb5_context context; + krb5_principal principal; + char *princ_name; + char *realm; + krb5_creds creds, *credsp; + krb5_ccache ccache; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + + ret = krb5_cc_default(context, &ccache); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ZERO_STRUCT(creds); + + realm = strchr(princ, '@'); + realm++; + + asprintf(&princ_name, "kadmin/changepw@%s", realm); + ret = krb5_parse_name(context, princ_name, &creds.server); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + free(princ_name); + + /* parse the principal we got as a function argument */ + ret = krb5_parse_name(context, princ, &principal); + if (ret) { + krb5_free_context(context); + DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + krb5_princ_set_realm(context, creds.server, + krb5_princ_realm(context, principal)); + + ret = krb5_cc_get_principal(context, ccache, &creds.client); + if (ret) { + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("Failed to get principal from ccache (%s)\n", + error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); + if (ret) { + krb5_free_principal(context, creds.client); + krb5_free_principal(context, principal); + krb5_free_context(context); + DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + /* we might have to call krb5_free_creds(...) from now on ... */ + + aret = do_krb5_kpasswd_request(context, kdc_host, + KRB5_KPASSWD_VERS_SETPW_MS, + credsp, princ, newpw); + krb5_free_creds(context, credsp); krb5_free_principal(context, creds.client); + krb5_free_principal(context, creds.server); krb5_free_principal(context, principal); krb5_free_context(context); - return ADS_SUCCESS; + return aret; +} + +/* + we use a prompter to avoid a crash bug in the kerberos libs when + dealing with empty passwords + this prompter is just a string copy ... +*/ +static krb5_error_code +kerb_prompter(krb5_context ctx, void *data, + const char *name, + const char *banner, + int num_prompts, + krb5_prompt prompts[]) +{ + if (num_prompts == 0) return 0; + + memset(prompts[0].reply->data, 0, prompts[0].reply->length); + if (prompts[0].reply->length > 0) { + if (data) { + strncpy(prompts[0].reply->data, data, prompts[0].reply->length-1); + prompts[0].reply->length = strlen(prompts[0].reply->data); + } else { + prompts[0].reply->length = 0; + } + } + return 0; +} + +ADS_STATUS krb5_chg_password(const char *kdc_host, + const char *principal, + const char *oldpw, + const char *newpw, + int time_offset) +{ + ADS_STATUS aret; + krb5_error_code ret; + krb5_context context; + krb5_principal princ; + krb5_get_init_creds_opt opts; + krb5_creds creds; + char *chpw_princ = NULL, *password; + + ret = krb5_init_context(&context); + if (ret) { + DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + if ((ret = krb5_parse_name(context, principal, + &princ))) { + krb5_free_context(context); + DEBUG(1,("Failed to parse %s (%s)\n", principal, error_message(ret))); + return ADS_ERROR_KRB5(ret); + } + + krb5_get_init_creds_opt_init(&opts); + krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60); + krb5_get_init_creds_opt_set_renew_life(&opts, 0); + krb5_get_init_creds_opt_set_forwardable(&opts, 0); + krb5_get_init_creds_opt_set_proxiable(&opts, 0); + + /* We have to obtain an INITIAL changepw ticket for changing password */ + asprintf(&chpw_princ, "kadmin/changepw@%s", + (char *) krb5_princ_realm(context, princ)); + password = strdup(oldpw); + ret = krb5_get_init_creds_password(context, &creds, princ, password, + kerb_prompter, NULL, + 0, chpw_princ, &opts); + SAFE_FREE(chpw_princ); + SAFE_FREE(password); + + if (ret) { + if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) + DEBUG(1,("Password incorrect while getting initial ticket")); + else + DEBUG(1,("krb5_get_init_creds_password failed (%s)\n", error_message(ret))); + + krb5_free_principal(context, princ); + krb5_free_context(context); + return ADS_ERROR_KRB5(ret); + } + + aret = do_krb5_kpasswd_request(context, kdc_host, + KRB5_KPASSWD_VERS_CHANGEPW, + &creds, principal, newpw); + + krb5_free_principal(context, princ); + krb5_free_context(context); + + return aret; } @@ -480,7 +656,12 @@ ADS_STATUS kerberos_set_password(const char *kpasswd_server, return ADS_ERROR_KRB5(ret); } - return krb5_set_password(kpasswd_server, target_principal, new_password, time_offset); + if (!strcmp(auth_principal, target_principal)) + return krb5_chg_password(kpasswd_server, target_principal, + auth_password, new_password, time_offset); + else + return krb5_set_password(kpasswd_server, target_principal, + new_password, time_offset); } @@ -515,4 +696,6 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, return status; } + + #endif diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 67669fc078..bc90e90ea0 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -816,18 +816,18 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; - void **values; + struct berval **ber_values; + char **char_values; if (!invals) { - values = NULL; mod_op = LDAP_MOD_DELETE; } else { if (mod_op & LDAP_MOD_BVALUES) - values = (void **) ads_dup_values(ctx, - (const struct berval **)invals); + ber_values = ads_dup_values(ctx, + (const struct berval **)invals); else - values = (void **) ads_push_strvals(ctx, - (const char **) invals); + char_values = ads_push_strvals(ctx, + (const char **) invals); } /* find the first empty slot */ @@ -846,10 +846,14 @@ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, if (!(modlist[curmod] = talloc_zero(ctx, sizeof(LDAPMod)))) return ADS_ERROR(LDAP_NO_MEMORY); modlist[curmod]->mod_type = talloc_strdup(ctx, name); - if (mod_op & LDAP_MOD_BVALUES) - modlist[curmod]->mod_bvalues = (struct berval **) values; - else - modlist[curmod]->mod_values = (char **) values; + if (mod_op & LDAP_MOD_BVALUES) { + modlist[curmod]->mod_bvalues = ber_values; + } else if (mod_op & LDAP_MOD_DELETE) { + modlist[curmod]->mod_values = NULL; + } else { + modlist[curmod]->mod_values = char_values; + } + modlist[curmod]->mod_op = mod_op; return ADS_ERROR(LDAP_SUCCESS); } @@ -1500,16 +1504,24 @@ ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) #endif if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); - bval.bv_len = sd_size; - bval.bv_val = talloc(ctx, sd_size); + bval.bv_len = prs_offset(&ps_wire); + bval.bv_val = talloc(ctx, bval.bv_len); if (!bval.bv_val) { ret = ADS_ERROR(LDAP_NO_MEMORY); goto ads_set_sd_error; } - prs_copy_all_data_out(bval.bv_val, &ps_wire); - ads_mod_ber(ctx, &mods, attrs[0], &bval); - ret = ads_gen_mod(ads, dn, mods); + prs_set_offset(&ps_wire, 0); + + if (!prs_copy_data_out(bval.bv_val, &ps_wire, bval.bv_len)) { + ret = ADS_ERROR(LDAP_NO_MEMORY); + goto ads_set_sd_error; + } + + ret = ads_mod_ber(ctx, &mods, attrs[0], &bval); + if (ADS_ERR_OK(ret)) { + ret = ads_gen_mod(ads, dn, mods); + } ads_set_sd_error: ads_msgfree(ads, res); @@ -1554,7 +1566,7 @@ char *ads_pull_string(ADS_STRUCT *ads, char **values; char *ret = NULL; char *ux_string; - int rc; + size_t rc; values = ldap_get_values(ads->ld, msg, field); if (!values) @@ -1563,7 +1575,7 @@ char *ads_pull_string(ADS_STRUCT *ads, if (values[0]) { rc = pull_utf8_talloc(mem_ctx, &ux_string, values[0]); - if (rc != -1) + if (rc != (size_t)-1) ret = ux_string; } @@ -1725,8 +1737,11 @@ int ads_pull_sids(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, count = 0; for (i=0; values[i]; i++) { ret = sid_parse(values[i]->bv_val, values[i]->bv_len, &(*sids)[count]); - if (ret) + if (ret) { + fstring sid; + DEBUG(10, ("pulling SID: %s\n", sid_to_string(sid, &(*sids)[count]))); count++; + } } ldap_value_free_len(values); diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 7aa77bf2a2..29d4533a54 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -241,7 +241,12 @@ static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads) ADS_STATUS status; krb5_principal principal; krb5_context ctx; - krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; gss_OID_desc nt_principal = {10, "\052\206\110\206\367\022\001\002\002\002"}; diff --git a/source3/libads/util.c b/source3/libads/util.c index 021f2d93e4..335cabc952 100644 --- a/source3/libads/util.c +++ b/source3/libads/util.c @@ -29,7 +29,7 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip char *new_password; char *service_principal; ADS_STATUS ret; - + if ((password = secrets_fetch_machine_password()) == NULL) { DEBUG(1,("Failed to retrieve password for principal %s\n", host_principal)); return ADS_ERROR_SYSTEM(ENOENT); @@ -38,15 +38,17 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); new_password = strdup(tmp_password); asprintf(&service_principal, "HOST/%s", host_principal); - - ret = kerberos_set_password(ads->auth.kdc_server, host_principal, password, - service_principal, new_password, ads->auth.time_offset); + + ret = kerberos_set_password(ads->auth.kdc_server, service_principal, password, service_principal, new_password, ads->auth.time_offset); + + if (!ADS_ERR_OK(ret)) goto failed; if (!secrets_store_machine_password(new_password)) { DEBUG(1,("Failed to save machine password\n")); return ADS_ERROR_SYSTEM(EACCES); } +failed: SAFE_FREE(service_principal); SAFE_FREE(new_password); -- cgit