From 2fbc63cacc81ab9e1dfdbe6d979c248c3bdea686 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 20 Aug 2020 10:50:30 +0200 Subject: [PATCH] auth:creds: Add obtained arg to cli_credentials_set_gensec_features() Signed-off-by: Andreas Schneider Reviewed-by: Andrew Bartlett --- auth/credentials/credentials.c | 33 ++++++++++++++++++++++--- auth/credentials/credentials.h | 4 ++- auth/credentials/credentials_internal.h | 1 + auth/credentials/pycredentials.c | 4 ++- source3/lib/netapi/netapi.c | 4 ++- source3/lib/util_cmdline.c | 4 ++- source3/libsmb/cliconnect.c | 4 ++- source3/utils/net_util.c | 4 ++- source4/lib/cmdline/popt_credentials.c | 6 +++-- source4/libcli/ldap/ldap_bind.c | 8 ++++-- 10 files changed, 58 insertions(+), 14 deletions(-) diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index f7c7a47bd4e..85fe03bdf94 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -150,9 +150,18 @@ _PUBLIC_ enum credentials_krb_forwardable cli_credentials_get_krb_forwardable(st return creds->krb_forwardable; } -_PUBLIC_ void cli_credentials_set_gensec_features(struct cli_credentials *creds, uint32_t gensec_features) +_PUBLIC_ bool cli_credentials_set_gensec_features(struct cli_credentials *creds, + uint32_t gensec_features, + enum credentials_obtained obtained) { - creds->gensec_features = gensec_features; + if (obtained >= creds->gensec_features_obtained) { + creds->gensec_features_obtained = obtained; + creds->gensec_features = gensec_features; + + return true; + } + + return false; } _PUBLIC_ uint32_t cli_credentials_get_gensec_features(struct cli_credentials *creds) @@ -1017,8 +1026,6 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, break; } } - - cred->encryption_state_obtained = CRED_SMB_CONF; } if (cred->kerberos_state_obtained <= CRED_SMB_CONF) { @@ -1026,6 +1033,24 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, cred->kerberos_state = lpcfg_client_use_kerberos(lp_ctx); cred->kerberos_state_obtained = CRED_SMB_CONF; } + + if (cred->gensec_features_obtained <= CRED_SMB_CONF) { + switch (protection) { + case CRED_CLIENT_PROTECTION_DEFAULT: + break; + case CRED_CLIENT_PROTECTION_PLAIN: + cred->gensec_features = 0; + break; + case CRED_CLIENT_PROTECTION_SIGN: + cred->gensec_features = GENSEC_FEATURE_SIGN; + break; + case CRED_CLIENT_PROTECTION_ENCRYPT: + cred->gensec_features = + GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL; + break; + } + cred->gensec_features_obtained = CRED_SMB_CONF; + } } /** diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 540e4cfb6b6..1007d8e3d66 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -233,7 +233,9 @@ int cli_credentials_set_keytab_name(struct cli_credentials *cred, struct loadparm_context *lp_ctx, const char *keytab_name, enum credentials_obtained obtained); -void cli_credentials_set_gensec_features(struct cli_credentials *creds, uint32_t gensec_features); +bool cli_credentials_set_gensec_features(struct cli_credentials *creds, + uint32_t gensec_features, + enum credentials_obtained obtained); uint32_t cli_credentials_get_gensec_features(struct cli_credentials *creds); int cli_credentials_set_ccache(struct cli_credentials *cred, struct loadparm_context *lp_ctx, diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index d39ead3b379..afbda1a4b48 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -41,6 +41,7 @@ struct cli_credentials { enum credentials_obtained ipc_signing_state_obtained; enum credentials_obtained encryption_state_obtained; enum credentials_obtained kerberos_state_obtained; + enum credentials_obtained gensec_features_obtained; /* Threshold values (essentially a MAX() over a number of the * above) for the ccache and GSS credentials, to ensure we diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 127085f4950..0ba2618cec9 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -842,7 +842,9 @@ static PyObject *py_creds_set_gensec_features(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "I", &gensec_features)) return NULL; - cli_credentials_set_gensec_features(creds, gensec_features); + cli_credentials_set_gensec_features(creds, + gensec_features, + CRED_SPECIFIED); Py_RETURN_NONE; } diff --git a/source3/lib/netapi/netapi.c b/source3/lib/netapi/netapi.c index 56e26c83fa4..fb51bb34323 100644 --- a/source3/lib/netapi/netapi.c +++ b/source3/lib/netapi/netapi.c @@ -357,7 +357,9 @@ NET_API_STATUS libnetapi_set_use_ccache(struct libnetapi_ctx *ctx) gensec_features = cli_credentials_get_gensec_features(ctx->creds); gensec_features |= GENSEC_FEATURE_NTLM_CCACHE; - cli_credentials_set_gensec_features(ctx->creds, gensec_features); + cli_credentials_set_gensec_features(ctx->creds, + gensec_features, + CRED_SPECIFIED); return NET_API_STATUS_SUCCESS; } diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c index 5374a29a514..3d1ee091f3a 100644 --- a/source3/lib/util_cmdline.c +++ b/source3/lib/util_cmdline.c @@ -272,7 +272,9 @@ void set_cmdline_auth_info_use_ccache(struct user_auth_info *auth_info, bool b) gensec_features = cli_credentials_get_gensec_features(auth_info->creds); gensec_features |= GENSEC_FEATURE_NTLM_CCACHE; - cli_credentials_set_gensec_features(auth_info->creds, gensec_features); + cli_credentials_set_gensec_features(auth_info->creds, + gensec_features, + CRED_SPECIFIED); } bool get_cmdline_auth_info_use_ccache(const struct user_auth_info *auth_info) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b13e43f9801..89b9fb0d6dd 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -140,7 +140,9 @@ struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx, features = cli_credentials_get_gensec_features(creds); features |= GENSEC_FEATURE_NTLM_CCACHE; - cli_credentials_set_gensec_features(creds, features); + cli_credentials_set_gensec_features(creds, + features, + CRED_SPECIFIED); if (password != NULL && strlen(password) == 0) { /* diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 5747bfa581a..f0b670a3f96 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -516,7 +516,9 @@ struct cli_credentials *net_context_creds(struct net_context *c, features = cli_credentials_get_gensec_features(creds); features |= GENSEC_FEATURE_NTLM_CCACHE; - cli_credentials_set_gensec_features(creds, features); + cli_credentials_set_gensec_features(creds, + features, + CRED_SPECIFIED); if (c->opt_password != NULL && strlen(c->opt_password) == 0) { /* diff --git a/source4/lib/cmdline/popt_credentials.c b/source4/lib/cmdline/popt_credentials.c index 552e68b7eeb..5add2454c2a 100644 --- a/source4/lib/cmdline/popt_credentials.c +++ b/source4/lib/cmdline/popt_credentials.c @@ -154,7 +154,8 @@ static void popt_common_credentials_callback(poptContext con, gensec_features |= GENSEC_FEATURE_SIGN; cli_credentials_set_gensec_features( popt_get_cmdline_credentials(), - gensec_features); + gensec_features, + CRED_SPECIFIED); break; } case OPT_ENCRYPT: @@ -167,7 +168,8 @@ static void popt_common_credentials_callback(poptContext con, gensec_features |= GENSEC_FEATURE_SEAL; cli_credentials_set_gensec_features( popt_get_cmdline_credentials(), - gensec_features); + gensec_features, + CRED_SPECIFIED); break; } } diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index 66fe9f5ea92..1008ff21b63 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -319,7 +319,9 @@ try_logon_again: old_gensec_features = cli_credentials_get_gensec_features(creds); if (wrap_flags == 0) { - cli_credentials_set_gensec_features(creds, old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)); + cli_credentials_set_gensec_features(creds, + old_gensec_features & ~(GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL), + CRED_SPECIFIED); } /* this call also sets the gensec_want_features */ @@ -332,7 +334,9 @@ try_logon_again: /* reset the original gensec_features (on the credentials * context, so we don't tatoo it ) */ - cli_credentials_set_gensec_features(creds, old_gensec_features); + cli_credentials_set_gensec_features(creds, + old_gensec_features, + CRED_SPECIFIED); if (wrap_flags & ADS_AUTH_SASL_SEAL) { gensec_want_feature(conn->gensec, GENSEC_FEATURE_SIGN);