diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h index 154bf67f964..879534f9528 100644 --- a/source3/libads/ads_proto.h +++ b/source3/libads/ads_proto.h @@ -32,6 +32,8 @@ #ifndef _LIBADS_ADS_PROTO_H_ #define _LIBADS_ADS_PROTO_H_ +#include "krb5.h" + /* The following definitions come from libads/ads_struct.c */ char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse); @@ -50,9 +52,9 @@ void ads_disp_sd(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, struct security_descripto /* The following definitions come from libads/kerberos_keytab.c */ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, - bool update_ads); + bool update_ads, krb5_kvno *kvno); int ads_keytab_flush(ADS_STRUCT *ads); -int ads_keytab_create_default(ADS_STRUCT *ads); +int ads_keytab_create_default(ADS_STRUCT *ads, krb5_kvno *kvno); int ads_keytab_list(const char *keytab_name); /* The following definitions come from libads/net_ads_setspn.c */ diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index 8eb7b2a7c6b..5ff18123b63 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -232,13 +232,16 @@ out: Adds a single service principal, i.e. 'host' to the system keytab ***********************************************************************/ -int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads) +int ads_keytab_add_entry(ADS_STRUCT *ads, + const char *srvPrinc, + bool update_ads, + krb5_kvno *kvno) { krb5_error_code ret = 0; krb5_context context = NULL; krb5_keytab keytab = NULL; krb5_data password; - krb5_kvno kvno; + krb5_kvno lkvno; krb5_enctype enctypes[6] = { ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, @@ -359,13 +362,18 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads) } } - kvno = (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name()); - if (kvno == -1) { - /* -1 indicates failure, everything else is OK */ - DEBUG(1, (__location__ ": ads_get_machine_kvno failed to " - "determine the system's kvno.\n")); - ret = -1; - goto out; + if (!kvno) { + lkvno = + (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name()); + if (lkvno == -1) { + /* -1 indicates failure, everything else is OK */ + DEBUG(1, (__location__ + ": ads_get_machine_kvno failed to " + "determine the system's kvno.\n")); + ret = -1; + goto out; + } + kvno = &lkvno; } salt_princ_s = kerberos_secrets_fetch_salt_princ(); @@ -380,7 +388,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads) /* add the fqdn principal to the keytab */ ret = smb_krb5_kt_add_entry(context, keytab, - kvno, + *kvno, princ_s, salt_princ_s, enctypes[i], @@ -396,7 +404,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads) if (short_princ_s) { ret = smb_krb5_kt_add_entry(context, keytab, - kvno, + *kvno, short_princ_s, salt_princ_s, enctypes[i], @@ -490,14 +498,14 @@ out: Adds all the required service principals to the system keytab. ***********************************************************************/ -int ads_keytab_create_default(ADS_STRUCT *ads) +int ads_keytab_create_default(ADS_STRUCT *ads, krb5_kvno *kvno) { krb5_error_code ret = 0; krb5_context context = NULL; krb5_keytab keytab = NULL; krb5_kt_cursor cursor = {0}; krb5_keytab_entry kt_entry = {0}; - krb5_kvno kvno; + krb5_kvno lkvno; size_t found = 0; char *sam_account_name, *upn; char **oldEntries = NULL, *princ_s[26]; @@ -528,6 +536,23 @@ int ads_keytab_create_default(ADS_STRUCT *ads) goto done; } + machine_name = talloc_strdup(frame, lp_netbios_name()); + if (!machine_name) { + ret = -1; + goto done; + } + + if (!kvno) { + lkvno = (krb5_kvno)ads_get_machine_kvno(ads, machine_name); + if (lkvno == (krb5_kvno)-1) { + DEBUG(1, (__location__ + ": ads_get_machine_kvno() failed to " + "determine the system's kvno.\n")); + goto done; + } + kvno = &lkvno; + } + for (i = 0; i < num_spns; i++) { char *srv_princ; char *p; @@ -545,7 +570,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) p[0] = '\0'; /* Add the SPNs found on the DC */ - ret = ads_keytab_add_entry(ads, srv_princ, false); + ret = ads_keytab_add_entry(ads, srv_princ, false, kvno); if (ret != 0) { DEBUG(1, ("ads_keytab_add_entry failed while " "adding '%s' principal.\n", @@ -576,12 +601,6 @@ int ads_keytab_create_default(ADS_STRUCT *ads) goto done; } - machine_name = talloc_strdup(frame, lp_netbios_name()); - if (!machine_name) { - ret = -1; - goto done; - } - /* now add the userPrincipalName and sAMAccountName entries */ ok = ads_has_samaccountname(ads, frame, machine_name); if (!ok) { @@ -607,7 +626,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) goto done; } - ret = ads_keytab_add_entry(ads, sam_account_name, false); + ret = ads_keytab_add_entry(ads, sam_account_name, false, NULL); if (ret != 0) { DEBUG(1, (__location__ ": ads_keytab_add_entry() failed " "while adding sAMAccountName (%s)\n", @@ -618,7 +637,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) /* remember that not every machine account will have a upn */ upn = ads_get_upn(ads, frame, machine_name); if (upn) { - ret = ads_keytab_add_entry(ads, upn, false); + ret = ads_keytab_add_entry(ads, upn, false, NULL); if (ret != 0) { DEBUG(1, (__location__ ": ads_keytab_add_entry() " "failed while adding UPN (%s)\n", upn)); @@ -627,12 +646,6 @@ int ads_keytab_create_default(ADS_STRUCT *ads) } /* Now loop through the keytab and update any other existing entries */ - kvno = (krb5_kvno)ads_get_machine_kvno(ads, machine_name); - if (kvno == (krb5_kvno)-1) { - DEBUG(1, (__location__ ": ads_get_machine_kvno() failed to " - "determine the system's kvno.\n")); - goto done; - } DEBUG(3, (__location__ ": Searching for keytab entries to preserve " "and update.\n")); @@ -680,7 +693,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) } while (krb5_kt_next_entry(context, keytab, &kt_entry, &cursor) == 0) { - if (kt_entry.vno != kvno) { + if (kt_entry.vno != *kvno) { char *ktprinc = NULL; char *p; @@ -732,7 +745,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads) ret = 0; for (i = 0; oldEntries[i]; i++) { - ret |= ads_keytab_add_entry(ads, oldEntries[i], false); + ret |= ads_keytab_add_entry(ads, oldEntries[i], false, NULL); TALLOC_FREE(oldEntries[i]); } diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index a9405e8d288..06d130aeff1 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -809,7 +809,7 @@ static bool libnet_join_create_keytab(TALLOC_CTX *mem_ctx, return true; } - if (ads_keytab_create_default(r->in.ads) != 0) { + if (ads_keytab_create_default(r->in.ads, NULL) != 0) { return false; } diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index ffa67d8f525..69df6b3d235 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -2341,6 +2341,7 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv) char *host_principal; fstring my_name; ADS_STATUS ret; + krb5_kvno kvno; if (c->display_usage) { d_printf( "%s\n" @@ -2376,6 +2377,7 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv) } d_printf(_("Changing password for principal: %s\n"), host_principal); + kvno = (krb5_kvno)ads_get_machine_kvno(ads, my_name); ret = ads_change_trust_account_password(ads, host_principal); if (!ADS_ERR_OK(ret)) { @@ -2386,10 +2388,14 @@ int net_ads_changetrustpw(struct net_context *c, int argc, const char **argv) } d_printf(_("Password change for principal %s succeeded.\n"), host_principal); + if (kvno != (krb5_kvno)ads_get_machine_kvno(ads, my_name)) { + d_printf(_( + "Server reported different kvno than calculated kvno!\n")); + } if (USE_SYSTEM_KEYTAB) { d_printf(_("Attempting to update system keytab with new password.\n")); - if (ads_keytab_create_default(ads)) { + if (ads_keytab_create_default(ads, &kvno)) { d_printf(_("Failed to update system keytab.\n")); } } @@ -2630,7 +2636,7 @@ static int net_ads_keytab_add(struct net_context *c, return -1; } for (i = 0; i < argc; i++) { - ret |= ads_keytab_add_entry(ads, argv[i], update_ads); + ret |= ads_keytab_add_entry(ads, argv[i], update_ads, NULL); } ads_destroy(&ads); return ret; @@ -2667,7 +2673,7 @@ static int net_ads_keytab_create(struct net_context *c, int argc, const char **a if (!ADS_ERR_OK(ads_startup(c, true, &ads))) { return -1; } - ret = ads_keytab_create_default(ads); + ret = ads_keytab_create_default(ads, NULL); ads_destroy(&ads); return ret; }