From: Andrew Bartlett Date: Wed, 20 Dec 2023 23:00:46 +0000 (+1300) Subject: auth/credentials: Dynamically calculate the salt principal (unless speccified) X-Git-Tag: tdb-1.4.11~1463 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dd993c217032ad6f6188947f4d4d96ec7da70823;p=thirdparty%2Fsamba.git auth/credentials: Dynamically calculate the salt principal (unless speccified) This helps pull the salt principal calculation into a single spot. Signed-off-by: Andrew Bartlett Reviewed-by: Jo Sutton --- diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 9c11bbd9bca..0464d7a08c8 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -262,7 +262,7 @@ void cli_credentials_set_impersonate_principal(struct cli_credentials *cred, const char *principal, const char *self_service); void cli_credentials_set_target_service(struct cli_credentials *cred, const char *principal); -const char *cli_credentials_get_salt_principal(struct cli_credentials *cred); +char *cli_credentials_get_salt_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx); const char *cli_credentials_get_impersonate_principal(struct cli_credentials *cred); const char *cli_credentials_get_self_service(struct cli_credentials *cred); const char *cli_credentials_get_target_service(struct cli_credentials *cred); diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index 4e7a1a3b265..3e8d4651b44 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -1174,10 +1174,8 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred, krb5_keytab keytab; TALLOC_CTX *mem_ctx; const char *username = cli_credentials_get_username(cred); - const char *upn = NULL; const char *realm = cli_credentials_get_realm(cred); char *salt_principal = NULL; - uint32_t uac_flags = 0; if (cred->keytab_obtained >= (MAX(cred->principal_obtained, cred->username_obtained))) { @@ -1200,37 +1198,10 @@ _PUBLIC_ int cli_credentials_get_keytab(struct cli_credentials *cred, return ENOMEM; } - switch (cred->secure_channel_type) { - case SEC_CHAN_WKSTA: - case SEC_CHAN_RODC: - uac_flags = UF_WORKSTATION_TRUST_ACCOUNT; - break; - case SEC_CHAN_BDC: - uac_flags = UF_SERVER_TRUST_ACCOUNT; - break; - case SEC_CHAN_DOMAIN: - case SEC_CHAN_DNS_DOMAIN: - uac_flags = UF_INTERDOMAIN_TRUST_ACCOUNT; - break; - default: - upn = cli_credentials_get_principal(cred, mem_ctx); - if (upn == NULL) { - TALLOC_FREE(mem_ctx); - return ENOMEM; - } - uac_flags = UF_NORMAL_ACCOUNT; - break; - } - - ret = smb_krb5_salt_principal_str(realm, - username, /* sAMAccountName */ - upn, /* userPrincipalName */ - uac_flags, - mem_ctx, - &salt_principal); - if (ret) { + salt_principal = cli_credentials_get_salt_principal(cred, mem_ctx); + if (salt_principal == NULL) { talloc_free(mem_ctx); - return ret; + return ENOMEM; } ret = smb_krb5_create_memory_keytab(mem_ctx, @@ -1412,9 +1383,61 @@ _PUBLIC_ int cli_credentials_get_kvno(struct cli_credentials *cred) } -const char *cli_credentials_get_salt_principal(struct cli_credentials *cred) +char *cli_credentials_get_salt_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx) { - return cred->salt_principal; + TALLOC_CTX *frame = NULL; + const char *realm = NULL; + const char *username = NULL; + uint32_t uac_flags = 0; + char *salt_principal = NULL; + const char *upn = NULL; + int ret; + + /* If specified, use the specified value */ + if (cred->salt_principal != NULL) { + return talloc_strdup(mem_ctx, cred->salt_principal); + } + + frame = talloc_stackframe(); + + switch (cred->secure_channel_type) { + case SEC_CHAN_WKSTA: + case SEC_CHAN_RODC: + uac_flags = UF_WORKSTATION_TRUST_ACCOUNT; + break; + case SEC_CHAN_BDC: + uac_flags = UF_SERVER_TRUST_ACCOUNT; + break; + case SEC_CHAN_DOMAIN: + case SEC_CHAN_DNS_DOMAIN: + uac_flags = UF_INTERDOMAIN_TRUST_ACCOUNT; + break; + default: + upn = cli_credentials_get_principal(cred, frame); + if (upn == NULL) { + TALLOC_FREE(frame); + return NULL; + } + uac_flags = UF_NORMAL_ACCOUNT; + break; + } + + realm = cli_credentials_get_realm(cred); + username = cli_credentials_get_username(cred); + + ret = smb_krb5_salt_principal_str(realm, + username, /* sAMAccountName */ + upn, /* userPrincipalName */ + uac_flags, + mem_ctx, + &salt_principal); + if (ret) { + TALLOC_FREE(frame); + return NULL; + } + + TALLOC_FREE(frame); + return salt_principal; } _PUBLIC_ void cli_credentials_set_salt_principal(struct cli_credentials *cred, const char *principal) @@ -1497,18 +1520,23 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred, }; krb5_keyblock key; + TALLOC_CTX *frame = talloc_stackframe(); + if (cred->password_will_be_nt_hash) { DEBUG(1,("cli_credentials_get_aes256_key: cannot generate AES256 key using NT hash\n")); + TALLOC_FREE(frame); return EINVAL; } - salt = cli_credentials_get_salt_principal(cred); + salt = cli_credentials_get_salt_principal(cred, frame); if (salt == NULL) { + TALLOC_FREE(frame); return EINVAL; } password = cli_credentials_get_password(cred); if (password == NULL) { + TALLOC_FREE(frame); return EINVAL; } @@ -1518,6 +1546,7 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred, ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context); if (ret != 0) { + TALLOC_FREE(frame); return ret; } @@ -1539,6 +1568,7 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred, "generation of a aes256-cts-hmac-sha1-96 key failed: %s\n", smb_get_krb5_error_message(smb_krb5_context->krb5_context, krb5_ret, mem_ctx))); + TALLOC_FREE(frame); return EINVAL; } *aes_256 = data_blob_talloc(mem_ctx, @@ -1546,10 +1576,12 @@ _PUBLIC_ int cli_credentials_get_aes256_key(struct cli_credentials *cred, KRB5_KEY_LENGTH(&key)); krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &key); if (aes_256->data == NULL) { + TALLOC_FREE(frame); return ENOMEM; } talloc_keep_secret(aes_256->data); + TALLOC_FREE(frame); return 0; } diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 6d73a0a2c32..75cd2909a4c 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -994,12 +994,24 @@ static PyObject *py_creds_set_kerberos_salt_principal(PyObject *self, PyObject * static PyObject *py_creds_get_kerberos_salt_principal(PyObject *self, PyObject *unused) { + TALLOC_CTX *mem_ctx; + PyObject *ret = NULL; struct cli_credentials *creds = PyCredentials_AsCliCredentials(self); if (creds == NULL) { PyErr_Format(PyExc_TypeError, "Credentials expected"); return NULL; } - return PyString_FromStringOrNULL(cli_credentials_get_salt_principal(creds)); + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + ret = PyString_FromStringOrNULL(cli_credentials_get_salt_principal(creds, mem_ctx)); + + TALLOC_FREE(mem_ctx); + + return ret; } static PyObject *py_creds_get_aes256_key(PyObject *self, PyObject *args) diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 7527a78b30e..2234efeed54 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -835,7 +835,7 @@ static bool migrate_secrets_tdb_to_ldb(struct winbindd_domain *domain) NULL /* oldpass */, cli_credentials_get_domain(creds), cli_credentials_get_realm(creds), - cli_credentials_get_salt_principal(creds), + cli_credentials_get_salt_principal(creds, creds), 0, /* Supported enc types, unused */ &domain->sid, cli_credentials_get_password_last_changed_time(creds),