summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auth/credentials/credentials_krb5.c16
-rw-r--r--source4/auth/kerberos/kerberos_util.c18
-rw-r--r--source4/auth/kerberos/srv_keytab.c74
-rwxr-xr-xsource4/auth/kerberos/wscript_build2
-rw-r--r--source4/dsdb/samdb/ldb_modules/update_keytab.c2
5 files changed, 68 insertions, 44 deletions
diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c
index f4defa1cc0..40ae454a9d 100644
--- a/auth/credentials/credentials_krb5.c
+++ b/auth/credentials/credentials_krb5.c
@@ -665,6 +665,8 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
krb5_error_code ret;
struct keytab_container *ktc;
struct smb_krb5_context *smb_krb5_context;
+ const char *keytab_name;
+ krb5_keytab keytab;
TALLOC_CTX *mem_ctx;
if (cred->keytab_obtained >= (MAX(cred->principal_obtained,
@@ -688,8 +690,16 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred,
return ENOMEM;
}
- ret = smb_krb5_create_memory_keytab(mem_ctx, cred,
- smb_krb5_context, &ktc);
+ ret = smb_krb5_create_memory_keytab(mem_ctx, cred,
+ smb_krb5_context,
+ &keytab, &keytab_name);
+ if (ret) {
+ talloc_free(mem_ctx);
+ return ret;
+ }
+
+ ret = smb_krb5_get_keytab_container(mem_ctx, smb_krb5_context,
+ keytab, keytab_name, &ktc);
if (ret) {
talloc_free(mem_ctx);
return ret;
@@ -733,7 +743,7 @@ _PUBLIC_ int cli_credentials_set_keytab_name(struct cli_credentials *cred,
}
ret = smb_krb5_get_keytab_container(mem_ctx, smb_krb5_context,
- keytab_name, &ktc);
+ NULL, keytab_name, &ktc);
if (ret) {
return ret;
}
diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
index 0d2d19c78d..d30ac24c34 100644
--- a/source4/auth/kerberos/kerberos_util.c
+++ b/source4/auth/kerberos/kerberos_util.c
@@ -327,19 +327,25 @@ static krb5_error_code free_keytab_container(struct keytab_container *ktc)
krb5_error_code smb_krb5_get_keytab_container(TALLOC_CTX *mem_ctx,
struct smb_krb5_context *smb_krb5_context,
+ krb5_keytab opt_keytab,
const char *keytab_name,
struct keytab_container **ktc)
{
krb5_keytab keytab;
krb5_error_code ret;
- ret = krb5_kt_resolve(smb_krb5_context->krb5_context,
- keytab_name, &keytab);
- if (ret) {
- DEBUG(1,("failed to open krb5 keytab: %s\n",
- smb_get_krb5_error_message(
+
+ if (opt_keytab) {
+ keytab = opt_keytab;
+ } else {
+ ret = krb5_kt_resolve(smb_krb5_context->krb5_context,
+ keytab_name, &keytab);
+ if (ret) {
+ DEBUG(1,("failed to open krb5 keytab: %s\n",
+ smb_get_krb5_error_message(
smb_krb5_context->krb5_context,
ret, mem_ctx)));
- return ret;
+ return ret;
+ }
}
*ktc = talloc(mem_ctx, struct keytab_container);
diff --git a/source4/auth/kerberos/srv_keytab.c b/source4/auth/kerberos/srv_keytab.c
index 1ace396b6f..475f09d934 100644
--- a/source4/auth/kerberos/srv_keytab.c
+++ b/source4/auth/kerberos/srv_keytab.c
@@ -26,7 +26,6 @@
#include "system/kerberos.h"
#include "auth/kerberos/kerberos.h"
#include "auth/kerberos/kerberos_srv_keytab.h"
-#include "auth/kerberos/kerberos_util.h"
static void keytab_principals_free(krb5_context context, krb5_principal *set)
{
@@ -508,29 +507,37 @@ krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
int kvno,
uint32_t supp_enctypes,
bool delete_all_kvno,
+ krb5_keytab *_keytab,
const char **error_string)
{
+ krb5_keytab keytab;
krb5_error_code ret;
bool found_previous;
- TALLOC_CTX *mem_ctx = talloc_new(NULL);
- struct keytab_container *keytab_container;
+ TALLOC_CTX *tmp_ctx;
krb5_principal *principals = NULL;
- if (!keytab_name) {
+ if (keytab_name == NULL) {
return ENOENT;
}
- ret = smb_krb5_get_keytab_container(mem_ctx, smb_krb5_context,
- keytab_name, &keytab_container);
-
- if (ret != 0) {
- goto done;
+ ret = krb5_kt_resolve(smb_krb5_context->krb5_context,
+ keytab_name, &keytab);
+ if (ret) {
+ *error_string = smb_get_krb5_error_message(
+ smb_krb5_context->krb5_context,
+ ret, parent_ctx);
+ return ret;
}
DEBUG(5, ("Opened keytab %s\n", keytab_name));
+ tmp_ctx = talloc_new(parent_ctx);
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
/* Get the principal we will store the new keytab entries under */
- ret = principals_from_list(mem_ctx,
+ ret = principals_from_list(tmp_ctx,
samAccountName, realm, SPNs, num_SPNs,
smb_krb5_context->krb5_context,
&principals, error_string);
@@ -542,10 +549,9 @@ krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
goto done;
}
- ret = remove_old_entries(mem_ctx, kvno, principals, delete_all_kvno,
+ ret = remove_old_entries(tmp_ctx, kvno, principals, delete_all_kvno,
smb_krb5_context->krb5_context,
- keytab_container->keytab,
- &found_previous, error_string);
+ keytab, &found_previous, error_string);
if (ret != 0) {
*error_string = talloc_asprintf(parent_ctx,
"Failed to remove old principals from keytab: %s\n",
@@ -558,31 +564,42 @@ krb5_error_code smb_krb5_update_keytab(TALLOC_CTX *parent_ctx,
* entires for kvno -1, then don't try and duplicate them.
* Otherwise, add kvno, and kvno -1 */
- ret = create_keytab(mem_ctx,
+ ret = create_keytab(tmp_ctx,
samAccountName, realm, saltPrincipal,
kvno, new_secret, old_secret,
supp_enctypes, principals,
smb_krb5_context->krb5_context,
- keytab_container->keytab,
+ keytab,
found_previous ? false : true,
error_string);
+ if (ret) {
+ talloc_steal(parent_ctx, *error_string);
+ }
+ }
+
+ if (ret == 0 && _keytab != NULL) {
+ /* caller wants the keytab handle back */
+ *_keytab = keytab;
}
done:
keytab_principals_free(smb_krb5_context->krb5_context, principals);
- talloc_free(mem_ctx);
+ if (ret != 0 || _keytab == NULL) {
+ krb5_kt_close(smb_krb5_context->krb5_context, keytab);
+ }
+ talloc_free(tmp_ctx);
return ret;
}
krb5_error_code smb_krb5_create_memory_keytab(TALLOC_CTX *parent_ctx,
struct cli_credentials *machine_account,
struct smb_krb5_context *smb_krb5_context,
- struct keytab_container **keytab_container)
+ krb5_keytab *keytab,
+ const char **keytab_name)
{
krb5_error_code ret;
TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
const char *rand_string;
- const char *keytab_name;
const char *new_secret;
const char *samAccountName;
const char *realm;
@@ -592,43 +609,34 @@ krb5_error_code smb_krb5_create_memory_keytab(TALLOC_CTX *parent_ctx,
return ENOMEM;
}
- *keytab_container = talloc(mem_ctx, struct keytab_container);
-
rand_string = generate_random_str(mem_ctx, 16);
if (!rand_string) {
talloc_free(mem_ctx);
return ENOMEM;
}
- keytab_name = talloc_asprintf(mem_ctx, "MEMORY:%s",
- rand_string);
- if (!keytab_name) {
+ *keytab_name = talloc_asprintf(mem_ctx, "MEMORY:%s", rand_string);
+ if (*keytab_name == NULL) {
talloc_free(mem_ctx);
return ENOMEM;
}
- ret = smb_krb5_get_keytab_container(mem_ctx, smb_krb5_context,
- keytab_name, keytab_container);
- if (ret) {
- return ret;
- }
-
new_secret = cli_credentials_get_password(machine_account);
samAccountName = cli_credentials_get_username(machine_account);
realm = cli_credentials_get_realm(machine_account);
kvno = cli_credentials_get_kvno(machine_account);
ret = smb_krb5_update_keytab(mem_ctx, smb_krb5_context,
- keytab_name, samAccountName, realm,
+ *keytab_name, samAccountName, realm,
NULL, 0, NULL, new_secret, NULL,
kvno, ENC_ALL_TYPES,
- false, &error_string);
+ false, keytab, &error_string);
if (ret == 0) {
- talloc_steal(parent_ctx, *keytab_container);
+ talloc_steal(parent_ctx, *keytab_name);
} else {
DEBUG(0, ("Failed to create in-memory keytab: %s\n",
error_string));
- *keytab_container = NULL;
+ *keytab_name = NULL;
}
talloc_free(mem_ctx);
return ret;
diff --git a/source4/auth/kerberos/wscript_build b/source4/auth/kerberos/wscript_build
index 075c7b48b4..28269c54b4 100755
--- a/source4/auth/kerberos/wscript_build
+++ b/source4/auth/kerberos/wscript_build
@@ -17,5 +17,5 @@ bld.SAMBA_SUBSYSTEM('KERBEROS_UTIL',
bld.SAMBA_SUBSYSTEM('KERBEROS_SRV_KEYTAB',
autoproto='kerberos_srv_keytab.h',
source='srv_keytab.c',
- deps='authkrb5 samba-credentials KERBEROS_UTIL',
+ deps='authkrb5 samba-credentials',
)
diff --git a/source4/dsdb/samdb/ldb_modules/update_keytab.c b/source4/dsdb/samdb/ldb_modules/update_keytab.c
index 5e14cb7798..f1ec9953fb 100644
--- a/source4/dsdb/samdb/ldb_modules/update_keytab.c
+++ b/source4/dsdb/samdb/ldb_modules/update_keytab.c
@@ -440,7 +440,7 @@ static int update_kt_prepare_commit(struct ldb_module *module)
ldb_msg_find_attr_as_string(p->msg, "priorSecret", NULL),
ldb_msg_find_attr_as_int(p->msg, "msDS-KeyVersionNumber", 0),
(uint32_t)ldb_msg_find_attr_as_int(p->msg, "msDS-SupportedEncryptionTypes", ENC_ALL_TYPES),
- p->do_delete, &error_string);
+ p->do_delete, NULL, &error_string);
if (krb5_ret != 0) {
ldb_asprintf_errstring(ldb, "Failed to update keytab from entry %s in %s: %s",
ldb_dn_get_linearized(p->msg->dn),