diff options
author | Isaac Boukris <iboukris@gmail.com> | 2020-05-27 13:25:17 +0200 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2020-06-04 11:47:48 +0000 |
commit | b3630d58e4816402231500551aa6268b5a8cffa7 (patch) | |
tree | d7c9b8dc8203fcc09dc9e854ae8962cf125bacae | |
parent | 533a4be557bd7923ff8bfaea9a82cd99d47b10f4 (diff) | |
download | samba-b3630d58e4816402231500551aa6268b5a8cffa7.tar.gz |
Refactor ads_keytab_add_entry() to make it iterable
so we can more easily add msDS-AdditionalDnsHostName entries.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14396
Signed-off-by: Isaac Boukris <iboukris@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
-rw-r--r-- | source3/libads/kerberos_keytab.c | 197 |
1 files changed, 107 insertions, 90 deletions
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c index bc35d5edbe4..c46e98a4270 100644 --- a/source3/libads/kerberos_keytab.c +++ b/source3/libads/kerberos_keytab.c @@ -228,18 +228,16 @@ out: return ok; } -/********************************************************************** - 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) +static int add_kt_entry_etypes(krb5_context context, TALLOC_CTX *tmpctx, + ADS_STRUCT *ads, const char *salt_princ_s, + krb5_keytab keytab, krb5_kvno kvno, + const char *srvPrinc, const char *my_fqdn, + krb5_data *password, bool update_ads) { krb5_error_code ret = 0; - krb5_context context = NULL; - krb5_keytab keytab = NULL; - krb5_data password; - krb5_kvno kvno; - krb5_enctype enctypes[6] = { + char *princ_s = NULL; + char *short_princ_s = NULL; + krb5_enctype enctypes[4] = { #ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96 ENCTYPE_AES256_CTS_HMAC_SHA1_96, #endif @@ -249,65 +247,7 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads) ENCTYPE_ARCFOUR_HMAC, 0 }; - char *princ_s = NULL; - char *short_princ_s = NULL; - char *salt_princ_s = NULL; - char *password_s = NULL; - char *my_fqdn; - TALLOC_CTX *tmpctx = NULL; - int i; - - ret = smb_krb5_init_context_common(&context); - if (ret) { - DBG_ERR("kerberos init context failed (%s)\n", - error_message(ret)); - return -1; - } - - ret = ads_keytab_open(context, &keytab); - if (ret != 0) { - goto out; - } - - /* retrieve the password */ - if (!secrets_init()) { - DEBUG(1, (__location__ ": secrets_init failed\n")); - ret = -1; - goto out; - } - password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - if (!password_s) { - DEBUG(1, (__location__ ": failed to fetch machine password\n")); - ret = -1; - goto out; - } - ZERO_STRUCT(password); - password.data = password_s; - password.length = strlen(password_s); - - /* we need the dNSHostName value here */ - tmpctx = talloc_init(__location__); - if (!tmpctx) { - DEBUG(0, (__location__ ": talloc_init() failed!\n")); - ret = -1; - goto out; - } - - my_fqdn = ads_get_dnshostname(ads, tmpctx, lp_netbios_name()); - if (!my_fqdn) { - DEBUG(0, (__location__ ": unable to determine machine " - "account's dns name in AD!\n")); - ret = -1; - goto out; - } - - /* make sure we have a single instance of a the computer account */ - if (!ads_has_samaccountname(ads, tmpctx, lp_netbios_name())) { - DEBUG(0, (__location__ ": unable to determine machine " - "account's short name in AD!\n")); - ret = -1; - goto out; - } + size_t i; /* Construct our principal */ if (strchr_m(srvPrinc, '@')) { @@ -356,22 +296,6 @@ 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; - } - - salt_princ_s = kerberos_secrets_fetch_salt_princ(); - if (salt_princ_s == NULL) { - DBG_WARNING("kerberos_secrets_fetch_salt_princ() failed\n"); - ret = -1; - goto out; - } - for (i = 0; enctypes[i]; i++) { /* add the fqdn principal to the keytab */ @@ -381,11 +305,11 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads) princ_s, salt_princ_s, enctypes[i], - &password, + password, false, false); if (ret) { - DEBUG(1, (__location__ ": Failed to add entry to keytab\n")); + DBG_WARNING("Failed to add entry to keytab\n"); goto out; } @@ -397,16 +321,109 @@ int ads_keytab_add_entry(ADS_STRUCT *ads, const char *srvPrinc, bool update_ads) short_princ_s, salt_princ_s, enctypes[i], - &password, + password, false, false); if (ret) { - DEBUG(1, (__location__ - ": Failed to add short entry to keytab\n")); + DBG_WARNING("Failed to add short entry to keytab\n"); goto out; } } } +out: + return ret; +} + +/********************************************************************** + 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) +{ + krb5_error_code ret = 0; + krb5_context context = NULL; + krb5_keytab keytab = NULL; + krb5_data password; + krb5_kvno kvno; + char *salt_princ_s = NULL; + char *password_s = NULL; + char *my_fqdn; + TALLOC_CTX *tmpctx = NULL; + + ret = smb_krb5_init_context_common(&context); + if (ret) { + DBG_ERR("kerberos init context failed (%s)\n", + error_message(ret)); + return -1; + } + + ret = ads_keytab_open(context, &keytab); + if (ret != 0) { + goto out; + } + + /* retrieve the password */ + if (!secrets_init()) { + DBG_WARNING("secrets_init failed\n"); + ret = -1; + goto out; + } + password_s = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + if (!password_s) { + DBG_WARNING("failed to fetch machine password\n"); + ret = -1; + goto out; + } + ZERO_STRUCT(password); + password.data = password_s; + password.length = strlen(password_s); + + /* we need the dNSHostName value here */ + tmpctx = talloc_init(__location__); + if (!tmpctx) { + DBG_ERR("talloc_init() failed!\n"); + ret = -1; + goto out; + } + + my_fqdn = ads_get_dnshostname(ads, tmpctx, lp_netbios_name()); + if (!my_fqdn) { + DBG_ERR("unable to determine machine account's dns name in " + "AD!\n"); + ret = -1; + goto out; + } + + /* make sure we have a single instance of a the computer account */ + if (!ads_has_samaccountname(ads, tmpctx, lp_netbios_name())) { + DBG_ERR("unable to determine machine account's short name in " + "AD!\n"); + ret = -1; + goto out; + } + + kvno = (krb5_kvno)ads_get_machine_kvno(ads, lp_netbios_name()); + if (kvno == -1) { + /* -1 indicates failure, everything else is OK */ + DBG_WARNING("ads_get_machine_kvno failed to determine the " + "system's kvno.\n"); + ret = -1; + goto out; + } + + salt_princ_s = kerberos_secrets_fetch_salt_princ(); + if (salt_princ_s == NULL) { + DBG_WARNING("kerberos_secrets_fetch_salt_princ() failed\n"); + ret = -1; + goto out; + } + + ret = add_kt_entry_etypes(context, tmpctx, ads, salt_princ_s, keytab, + kvno, srvPrinc, my_fqdn, &password, + update_ads); + if (ret != 0) { + goto out; + } out: SAFE_FREE(salt_princ_s); |