summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-08-29 04:30:22 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:34:54 -0500
commit24186a80eb4887b5fb3e72e4b877b456cbe8e35f (patch)
tree4f5b7d9147ec0b450ca0da5023113c8c5aad2182
parent1a316fd8c50e501b5d69bb47ff5d1d483b02b04e (diff)
downloadsamba-24186a80eb4887b5fb3e72e4b877b456cbe8e35f.tar.gz
samba-24186a80eb4887b5fb3e72e4b877b456cbe8e35f.tar.bz2
samba-24186a80eb4887b5fb3e72e4b877b456cbe8e35f.zip
r9728: A *major* update to the credentials system, to incorporate the
Kerberos CCACHE into the system. This again allows the use of the system ccache when no username is specified, and brings more code in common between gensec_krb5 and gensec_gssapi. It also has a side-effect that may (or may not) be expected: If there is a ccache, even if it is not used (perhaps the remote server didn't want kerberos), it will change the default username. Andrew Bartlett (This used to be commit 6202267f6ec1446d6bd11d1d37d05a977bc8d315)
-rw-r--r--source4/auth/gensec/gensec_gssapi.c19
-rw-r--r--source4/auth/gensec/gensec_krb5.c148
-rw-r--r--source4/auth/kerberos/kerberos.h9
-rw-r--r--source4/auth/kerberos/kerberos_util.c59
-rw-r--r--source4/auth/ntlmssp/ntlmssp_client.c55
-rw-r--r--source4/client/client.c2
-rw-r--r--source4/include/credentials.h10
-rw-r--r--source4/include/includes.h1
-rw-r--r--source4/lib/cmdline/credentials.c19
-rw-r--r--source4/lib/cmdline/popt_common.c8
-rw-r--r--source4/lib/credentials.c318
-rw-r--r--source4/lib/ldb/ldb_ildap/ldb_ildap.c3
-rw-r--r--source4/lib/samba3/samba3dump.c7
-rw-r--r--source4/libcli/composite/sesssetup.c4
-rw-r--r--source4/librpc/rpc/dcerpc_schannel.c4
-rw-r--r--source4/scripting/ejs/smbcalls_auth.c2
-rw-r--r--source4/scripting/ejs/smbcalls_creds.c2
-rw-r--r--source4/torture/rpc/netlogon.c6
-rw-r--r--source4/torture/rpc/samlogon.c8
-rw-r--r--source4/torture/rpc/schannel.c2
-rw-r--r--source4/utils/net/net_password.c4
-rw-r--r--source4/utils/ntlm_auth.c2
22 files changed, 459 insertions, 233 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 64a6f8be77..26494f0222 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -208,6 +208,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
{
struct gensec_gssapi_state *gensec_gssapi_state;
struct cli_credentials *creds = gensec_get_credentials(gensec_security);
+ struct ccache_container *ccache;
+ krb5_error_code ret;
NTSTATUS nt_status;
gss_buffer_desc name_token;
OM_uint32 maj_stat, min_stat;
@@ -245,6 +247,13 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
return NT_STATUS_INVALID_PARAMETER;
}
+ ret = cli_credentials_get_ccache(creds,
+ &ccache);
+ if (ret) {
+ DEBUG(1, ("Failed to get CCACHE for gensec_gssapi: %s\n", error_message(ret)));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
name_token.value = cli_credentials_get_principal(creds,
gensec_gssapi_state);
name_token.length = strlen(name_token.value);
@@ -260,16 +269,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
return NT_STATUS_UNSUCCESSFUL;
}
- nt_status = kinit_to_ccache(gensec_gssapi_state,
- creds,
- gensec_gssapi_state->smb_krb5_context,
- &gensec_gssapi_state->ccache, &gensec_gssapi_state->ccache_name);
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
-
maj_stat = gsskrb5_acquire_cred(&min_stat,
- NULL, gensec_gssapi_state->ccache,
+ NULL, ccache->ccache,
gensec_gssapi_state->client_name,
GSS_C_INDEFINITE,
GSS_C_NULL_OID_SET,
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index a89f46a411..09722af10b 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -45,7 +45,6 @@ struct gensec_krb5_state {
enum GENSEC_KRB5_STATE state_position;
struct smb_krb5_context *smb_krb5_context;
krb5_auth_context auth_context;
- krb5_ccache ccache;
krb5_data ticket;
krb5_keyblock *keyblock;
char *peer_principal;
@@ -75,7 +74,6 @@ static int gensec_krb5_destory(void *ptr)
static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
{
struct gensec_krb5_state *gensec_krb5_state;
- krb5_error_code ret = 0;
gensec_krb5_state = talloc(gensec_security, struct gensec_krb5_state);
if (!gensec_krb5_state) {
@@ -85,7 +83,6 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
gensec_security->private_data = gensec_krb5_state;
gensec_krb5_state->auth_context = NULL;
- gensec_krb5_state->ccache = NULL;
ZERO_STRUCT(gensec_krb5_state->ticket);
ZERO_STRUCT(gensec_krb5_state->keyblock);
gensec_krb5_state->session_key = data_blob(NULL, 0);
@@ -93,34 +90,29 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
talloc_set_destructor(gensec_krb5_state, gensec_krb5_destory);
- ret = smb_krb5_init_context(gensec_krb5_state,
- &gensec_krb5_state->smb_krb5_context);
- if (ret) {
- DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n",
- error_message(ret)));
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- ret = krb5_auth_con_init(gensec_krb5_state->smb_krb5_context->krb5_context, &gensec_krb5_state->auth_context);
- if (ret) {
- DEBUG(1,("gensec_krb5_start: krb5_auth_con_init failed (%s)\n",
- smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context,
- ret, gensec_krb5_state)));
- return NT_STATUS_INTERNAL_ERROR;
- }
-
return NT_STATUS_OK;
}
static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security)
{
NTSTATUS nt_status;
+ krb5_error_code ret = 0;
struct gensec_krb5_state *gensec_krb5_state;
nt_status = gensec_krb5_start(gensec_security);
if (!NT_STATUS_IS_OK(nt_status)) {
return nt_status;
}
+
+ gensec_krb5_state = gensec_security->private_data;
+
+ ret = smb_krb5_init_context(gensec_krb5_state,
+ &gensec_krb5_state->smb_krb5_context);
+ if (ret) {
+ DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n",
+ error_message(ret)));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
gensec_krb5_state = gensec_security->private_data;
gensec_krb5_state->state_position = GENSEC_KRB5_SERVER_START;
@@ -133,7 +125,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
struct gensec_krb5_state *gensec_krb5_state;
krb5_error_code ret;
NTSTATUS nt_status;
- const char *ccache_name;
+ struct ccache_container *ccache_container;
const char *hostname = gensec_get_target_hostname(gensec_security);
if (!hostname) {
@@ -154,72 +146,68 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
gensec_krb5_state = gensec_security->private_data;
gensec_krb5_state->state_position = GENSEC_KRB5_CLIENT_START;
- /* TODO: This is effecivly a static/global variable...
-
- TODO: If the user set a username, we should use an in-memory CCACHE (see below)
- */
- ret = krb5_cc_default(gensec_krb5_state->smb_krb5_context->krb5_context, &gensec_krb5_state->ccache);
+ ret = cli_credentials_get_ccache(gensec_security->credentials, &ccache_container);
if (ret) {
- DEBUG(1,("krb5_cc_default failed (%s)\n",
- smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, ret, gensec_krb5_state)));
- return NT_STATUS_INTERNAL_ERROR;
+ DEBUG(1,("gensec_krb5_start: cli_credentials_get_ccache failed: %s\n",
+ error_message(ret)));
+ return NT_STATUS_UNSUCCESSFUL;
}
-
- while (1) {
- {
- krb5_data in_data;
- in_data.length = 0;
-
- ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context,
- &gensec_krb5_state->auth_context,
- AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED,
- gensec_get_target_service(gensec_security),
- hostname,
- &in_data, gensec_krb5_state->ccache,
- &gensec_krb5_state->ticket);
-
- }
- switch (ret) {
- case 0:
- return NT_STATUS_OK;
- case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
- DEBUG(3, ("Server [%s] is not registered with our KDC: %s\n",
- hostname, smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, ret, gensec_krb5_state)));
- return NT_STATUS_ACCESS_DENIED;
- case KRB5KDC_ERR_PREAUTH_FAILED:
- case KRB5KRB_AP_ERR_TKT_EXPIRED:
- case KRB5_CC_END:
- /* Too much clock skew - we will need to kinit to re-skew the clock */
- case KRB5KRB_AP_ERR_SKEW:
- case KRB5_KDCREP_SKEW:
- {
- DEBUG(3, ("kerberos (mk_req) failed: %s\n",
- smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, ret, gensec_krb5_state)));
- /* fall down to remaining code */
- }
+ gensec_krb5_state->smb_krb5_context = talloc_reference(gensec_krb5_state, ccache_container->smb_krb5_context);
- /* just don't print a message for these really ordinary messages */
- case KRB5_FCC_NOFILE:
- case KRB5_CC_NOTFOUND:
- case ENOENT:
-
- nt_status = kinit_to_ccache(gensec_krb5_state,
- gensec_security->credentials,
- gensec_krb5_state->smb_krb5_context,
- &gensec_krb5_state->ccache,
- &ccache_name);
+ ret = krb5_auth_con_init(gensec_krb5_state->smb_krb5_context->krb5_context, &gensec_krb5_state->auth_context);
+ if (ret) {
+ DEBUG(1,("gensec_krb5_start: krb5_auth_con_init failed (%s)\n",
+ smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context,
+ ret, gensec_krb5_state)));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ if (!ret) {
+ krb5_data in_data;
+ in_data.length = 0;
- if (!NT_STATUS_IS_OK(nt_status)) {
- return nt_status;
- }
+ ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context,
+ &gensec_krb5_state->auth_context,
+ AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED,
+ gensec_get_target_service(gensec_security),
+ hostname,
+ &in_data, ccache_container->ccache,
+ &gensec_krb5_state->ticket);
+
+ }
+ switch (ret) {
+ case 0:
+ return NT_STATUS_OK;
+ case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
+ DEBUG(3, ("Server [%s] is not registered with our KDC: %s\n",
+ hostname, smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, ret, gensec_krb5_state)));
+ return NT_STATUS_ACCESS_DENIED;
+ case KRB5KDC_ERR_PREAUTH_FAILED:
+ case KRB5KRB_AP_ERR_TKT_EXPIRED:
+ case KRB5_CC_END:
+ /* Too much clock skew - we will need to kinit to re-skew the clock */
+ case KRB5KRB_AP_ERR_SKEW:
+ case KRB5_KDCREP_SKEW:
+ {
+ DEBUG(3, ("kerberos (mk_req) failed: %s\n",
+ smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, ret, gensec_krb5_state)));
+ /* fall down to remaining code */
+ }
+
+
+ /* just don't print a message for these really ordinary messages */
+ case KRB5_FCC_NOFILE:
+ case KRB5_CC_NOTFOUND:
+ case ENOENT:
+
+ return NT_STATUS_UNSUCCESSFUL;
break;
-
- default:
- DEBUG(0, ("kerberos: %s\n",
- smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, ret, gensec_krb5_state)));
- return NT_STATUS_UNSUCCESSFUL;
- }
+
+ default:
+ DEBUG(0, ("kerberos: %s\n",
+ smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, ret, gensec_krb5_state)));
+ return NT_STATUS_UNSUCCESSFUL;
}
}
diff --git a/source4/auth/kerberos/kerberos.h b/source4/auth/kerberos/kerberos.h
index 954ac7dc57..8cc8e561ac 100644
--- a/source4/auth/kerberos/kerberos.h
+++ b/source4/auth/kerberos/kerberos.h
@@ -34,6 +34,10 @@ struct smb_krb5_context {
#endif
};
+struct ccache_container {
+ struct smb_krb5_context *smb_krb5_context;
+ krb5_ccache ccache;
+};
/* not really ASN.1, but RFC 1964 */
#define TOK_ID_KRB_AP_REQ "\x01\x00"
@@ -111,11 +115,10 @@ BOOL kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, k
void kerberos_free_data_contents(krb5_context context, krb5_data *pdata);
krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry);
char *smb_get_krb5_error_message(krb5_context context, krb5_error_code code, TALLOC_CTX *mem_ctx);
-NTSTATUS kinit_to_ccache(TALLOC_CTX *parent_ctx,
+ krb5_error_code kinit_to_ccache(TALLOC_CTX *parent_ctx,
struct cli_credentials *credentials,
struct smb_krb5_context *smb_krb5_context,
- krb5_ccache *ccache,
- const char **ccache_name);
+ krb5_ccache ccache);
krb5_error_code smb_krb5_init_context(TALLOC_CTX *parent_ctx,
struct smb_krb5_context **smb_krb5_context);
krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
index d455dac572..9dc8621b0e 100644
--- a/source4/auth/kerberos/kerberos_util.c
+++ b/source4/auth/kerberos/kerberos_util.c
@@ -33,11 +33,6 @@ struct principal_container {
krb5_principal principal;
};
-struct ccache_container {
- struct smb_krb5_context *smb_krb5_context;
- krb5_ccache ccache;
-};
-
struct keytab_container {
struct smb_krb5_context *smb_krb5_context;
krb5_keytab keytab;
@@ -65,7 +60,7 @@ krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
return ENOMEM;
}
- machine_username = talloc_strdup(mem_ctx, cli_credentials_get_username(machine_account));
+ machine_username = talloc_strdup(mem_ctx, cli_credentials_get_username(machine_account, mem_ctx));
if (!machine_username) {
talloc_free(mem_ctx);
@@ -100,58 +95,30 @@ krb5_error_code salt_principal_from_credentials(TALLOC_CTX *parent_ctx,
return ret;
}
-static int free_ccache(void *ptr) {
- struct ccache_container *ccc = ptr;
- /* current heimdal - 0.6.3, which we need anyway, fixes segfaults here */
- krb5_cc_close(ccc->smb_krb5_context->krb5_context, ccc->ccache);
-
- return 0;
-}
-
/**
* Return a freshly allocated ccache (destroyed by destructor on child
* of parent_ctx), for a given set of client credentials
*/
- NTSTATUS kinit_to_ccache(TALLOC_CTX *parent_ctx,
+ krb5_error_code kinit_to_ccache(TALLOC_CTX *parent_ctx,
struct cli_credentials *credentials,
struct smb_krb5_context *smb_krb5_context,
- krb5_ccache *ccache,
- const char **ccache_name)
+ krb5_ccache ccache)
{
krb5_error_code ret;
const char *password;
- char *ccache_string;
time_t kdc_time = 0;
- struct ccache_container *mem_ctx = talloc(parent_ctx, struct ccache_container);
+
+ TALLOC_CTX *mem_ctx = talloc_new(parent_ctx);
if (!mem_ctx) {
- return NT_STATUS_NO_MEMORY;
+ return ENOMEM;
}
password = cli_credentials_get_password(credentials);
- /* this string should be unique */
- ccache_string = talloc_asprintf(mem_ctx, "MEMORY:%s_%s",
- cli_credentials_get_principal(credentials, mem_ctx),
- generate_random_str(mem_ctx, 16));
-
- ret = krb5_cc_resolve(smb_krb5_context->krb5_context, ccache_string, ccache);
- if (ret) {
- DEBUG(1,("failed to generate a new krb5 ccache (%s): %s\n",
- ccache_string,
- error_message(ret)));
- talloc_free(mem_ctx);
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- mem_ctx->smb_krb5_context = talloc_reference(mem_ctx, smb_krb5_context);
- mem_ctx->ccache = *ccache;
-
- talloc_set_destructor(mem_ctx, free_ccache);
-
if (password) {
- ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, *ccache,
+ ret = kerberos_kinit_password_cc(smb_krb5_context->krb5_context, ccache,
cli_credentials_get_principal(credentials, mem_ctx),
password, NULL, &kdc_time);
} else {
@@ -163,7 +130,7 @@ static int free_ccache(void *ptr) {
if (!mach_pwd) {
talloc_free(mem_ctx);
DEBUG(1, ("kinit_to_ccache: No password available for kinit\n"));
- return NT_STATUS_WRONG_PASSWORD;
+ return EINVAL;
}
ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
ENCTYPE_ARCFOUR_HMAC,
@@ -171,7 +138,7 @@ static int free_ccache(void *ptr) {
&keyblock);
if (ret == 0) {
- ret = kerberos_kinit_keyblock_cc(smb_krb5_context->krb5_context, *ccache,
+ ret = kerberos_kinit_keyblock_cc(smb_krb5_context->krb5_context, ccache,
cli_credentials_get_principal(credentials, mem_ctx),
&keyblock, NULL, &kdc_time);
krb5_free_keyblock_contents(smb_krb5_context->krb5_context, &keyblock);
@@ -192,7 +159,7 @@ static int free_ccache(void *ptr) {
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
ret, mem_ctx)));
talloc_free(mem_ctx);
- return NT_STATUS_TIME_DIFFERENCE_AT_DC;
+ return ret;
}
if (ret) {
DEBUG(1,("kinit for %s failed (%s)\n",
@@ -200,11 +167,9 @@ static int free_ccache(void *ptr) {
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
ret, mem_ctx)));
talloc_free(mem_ctx);
- return NT_STATUS_WRONG_PASSWORD;
+ return ret;
}
- *ccache_name = ccache_string;
-
- return NT_STATUS_OK;
+ return 0;
}
static int free_keytab(void *ptr) {
diff --git a/source4/auth/ntlmssp/ntlmssp_client.c b/source4/auth/ntlmssp/ntlmssp_client.c
index add774f84e..feee14a857 100644
--- a/source4/auth/ntlmssp/ntlmssp_client.c
+++ b/source4/auth/ntlmssp/ntlmssp_client.c
@@ -164,20 +164,10 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
return NT_STATUS_INVALID_PARAMETER;
}
- /* Correctly handle username in the original form of user@REALM, which is valid */
- if (gensec_security->credentials->realm_obtained
- > gensec_security->credentials->domain_obtained) {
- user = talloc_asprintf(out_mem_ctx, "%s@%s",
- cli_credentials_get_username(gensec_security->credentials),
- cli_credentials_get_realm(gensec_security->credentials));
- domain = NULL;
- } else {
- user = cli_credentials_get_username(gensec_security->credentials);
- domain = cli_credentials_get_domain(gensec_security->credentials);
- }
+ user = cli_credentials_get_username(gensec_security->credentials, out_mem_ctx);
+ domain = cli_credentials_get_domain(gensec_security->credentials);
nt_hash = cli_credentials_get_nt_hash(gensec_security->credentials, out_mem_ctx);
- password = cli_credentials_get_password(gensec_security->credentials);
if (!nt_hash) {
static const uint8_t zeros[16];
@@ -265,24 +255,29 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
}
/* lanman auth is insecure, it may be disabled. We may also not have a password */
- if (lp_client_lanman_auth() && password) {
- lm_response = data_blob_talloc(gensec_ntlmssp_state, NULL, 24);
- if (!SMBencrypt(password,challenge_blob.data,
- lm_response.data)) {
- /* If the LM password was too long (and therefore the LM hash being
- of the first 14 chars only), don't send it */
- data_blob_free(&lm_response);
-
- /* LM Key is incompatible with 'long' passwords */
- gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
+ if (lp_client_lanman_auth()) {
+ password = cli_credentials_get_password(gensec_security->credentials);
+ if (!password) {
+ lm_response = nt_response;
} else {
- E_deshash(password, lm_hash);
- lm_session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
- memcpy(lm_session_key.data, lm_hash, 8);
- memset(&lm_session_key.data[8], '\0', 8);
-
- if (!gensec_ntlmssp_state->use_nt_response) {
+ lm_response = data_blob_talloc(gensec_ntlmssp_state, NULL, 24);
+ if (!SMBencrypt(password,challenge_blob.data,
+ lm_response.data)) {
+ /* If the LM password was too long (and therefore the LM hash being
+ of the first 14 chars only), don't send it */
+ data_blob_free(&lm_response);
+
+ /* LM Key is incompatible with 'long' passwords */
+ gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
+ } else {
+ E_deshash(password, lm_hash);
+ lm_session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
+ memcpy(lm_session_key.data, lm_hash, 8);
+ memset(&lm_session_key.data[8], '\0', 8);
+
+ if (!gensec_ntlmssp_state->use_nt_response) {
session_key = lm_session_key;
+ }
}
}
} else {
@@ -353,7 +348,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
gensec_ntlmssp_state->expected_state = NTLMSSP_DONE;
- if (gensec_security->want_features & GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL) {
+ if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)) {
nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
@@ -362,7 +357,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
}
}
- return nt_status;
+ return NT_STATUS_OK;
}
NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
diff --git a/source4/client/client.c b/source4/client/client.c
index 3e6609e68e..eb090aea74 100644
--- a/source4/client/client.c
+++ b/source4/client/client.c
@@ -198,7 +198,7 @@ static void send_message(void)
int total_len = 0;
int grp_id;
- if (!smbcli_message_start(cli->tree, desthost, cli_credentials_get_username(cmdline_credentials), &grp_id)) {
+ if (!smbcli_message_start(cli->tree, desthost, cli_credentials_get_username(cmdline_credentials, cmdline_credentials), &grp_id)) {
d_printf("message start: %s\n", smbcli_errstr(cli->tree));
return;
}
diff --git a/source4/include/credentials.h b/source4/include/credentials.h
index 58cc4767ad..5dadbbd1c5 100644
--- a/source4/include/credentials.h
+++ b/source4/include/credentials.h
@@ -24,8 +24,9 @@
/* In order of priority */
enum credentials_obtained {
CRED_UNINITIALISED = 0, /* We don't even have a guess yet */
- CRED_GUESSED, /* Current value should be used, which was guessed */
+ CRED_GUESS_ENV, /* Current value should be used, which was guessed */
CRED_CALLBACK, /* Callback should be used to obtain value */
+ CRED_GUESS_FILE, /* A guess from a file (or file pointed at in env variable) */
CRED_SPECIFIED /* Was explicitly specified on the command-line */
};
@@ -38,20 +39,26 @@ struct cli_credentials {
enum credentials_obtained password_obtained;
enum credentials_obtained domain_obtained;
enum credentials_obtained realm_obtained;
+ enum credentials_obtained ccache_obtained;
+ enum credentials_obtained principal_obtained;
const char *workstation;
const char *username;
const char *password;
const char *domain;
const char *realm;
+ const char *principal;
struct samr_Password *nt_hash;
+ struct ccache_container *ccache;
+
const char *(*workstation_cb) (struct cli_credentials *);
const char *(*password_cb) (struct cli_credentials *);
const char *(*username_cb) (struct cli_credentials *);
const char *(*domain_cb) (struct cli_credentials *);
const char *(*realm_cb) (struct cli_credentials *);
+ const char *(*principal_cb) (struct cli_credentials *);
/* Private handle for the callback routines to use */
void *priv_data;
@@ -65,4 +72,3 @@ struct cli_credentials {
BOOL machine_account_pending;
};
-
diff --git a/source4/include/includes.h b/source4/include/includes.h
index ea7abb0c9b..94b88d37b2 100644
--- a/source4/include/includes.h
+++ b/source4/include/includes.h
@@ -115,6 +115,7 @@ extern char *sys_errlist[];
extern int errno;
#endif
+
#include "lib/replace/replace.h"
/* Lists, trees, caching, database... */
diff --git a/source4/lib/cmdline/credentials.c b/source4/lib/cmdline/credentials.c
index d827baed76..7832e01e4b 100644
--- a/source4/lib/cmdline/credentials.c
+++ b/source4/lib/cmdline/credentials.c
@@ -29,14 +29,23 @@ static const char *cmdline_get_userpassword(struct cli_credentials *credentials)
{
char *prompt;
char *ret;
-
- prompt = talloc_asprintf(NULL, "Password for [%s\\%s]:",
- cli_credentials_get_domain(credentials),
- cli_credentials_get_username(credentials));
+ char *domain;
+ char *username;
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
+
+ domain = cli_credentials_get_domain(credentials);
+ username = cli_credentials_get_username(credentials, mem_ctx);
+ if (domain && domain[0]) {
+ prompt = talloc_asprintf(mem_ctx, "Password for [%s\\%s]:",
+ domain, username);
+ } else {
+ prompt = talloc_asprintf(mem_ctx, "Password for [%s]:",
+ username);
+ }
ret = getpass(prompt);
- talloc_free(prompt);
+ talloc_free(mem_ctx);
return ret;
}
diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c
index 4e808652f7..d3bd0a35a4 100644
--- a/source4/lib/cmdline/popt_common.c
+++ b/source4/lib/cmdline/popt_common.c
@@ -220,9 +220,11 @@ static void popt_common_credentials_callback(poptContext con,
char *lp;
cli_credentials_parse_string(cmdline_credentials, arg, CRED_SPECIFIED);
-
- if (cmdline_credentials->password && (lp=strchr_m(arg,'%'))) {
- memset(lp,0,strlen(cmdline_credentials->password));
+ /* This breaks the abstraction, including the const above */
+ if (lp=strchr_m(arg,'%')) {
+ lp[0]='\0';
+ lp++;
+ memset(lp,0,strlen(lp));
}
}
break;
diff --git a/source4/lib/credentials.c b/source4/lib/credentials.c
index aae55be800..69e237428c 100644
--- a/source4/lib/credentials.c
+++ b/source4/lib/credentials.c
@@ -25,6 +25,9 @@
#include "include/secrets.h"
#include "lib/ldb/include/ldb.h"
#include "librpc/gen_ndr/ndr_samr.h" /* for struct samrPassword */
+#include "system/kerberos.h"
+#include "auth/kerberos/kerberos.h"
+
/**
* Create a new credentials structure
@@ -44,6 +47,8 @@ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
cred->password_obtained = CRED_UNINITIALISED;
cred->domain_obtained = CRED_UNINITIALISED;
cred->realm_obtained = CRED_UNINITIALISED;
+ cred->ccache_obtained = CRED_UNINITIALISED;
+ cred->principal_obtained = CRED_UNINITIALISED;
return cred;
}
@@ -53,18 +58,23 @@ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx)
* @retval The username set on this context.
* @note Return value will never be NULL except by programmer error.
*/
-const char *cli_credentials_get_username(struct cli_credentials *cred)
+const char *cli_credentials_get_username(struct cli_credentials *cred, TALLOC_CTX *mem_ctx)
{
if (cred->machine_account_pending) {
cli_credentials_set_machine_account(cred);
}
+ /* If we have a principal set on this, we want to login with "" domain and user@realm */
+ if (cred->username_obtained < cred->principal_obtained) {
+ return cli_credentials_get_principal(cred, mem_ctx);
+ }
+
if (cred->username_obtained == CRED_CALLBACK) {
cred->username = cred->username_cb(cred);
cred->username_obtained = CRED_SPECIFIED;
}
- return cred->username;
+ return talloc_reference(mem_ctx, cred->username);
}
BOOL cli_credentials_set_username(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained)
@@ -79,6 +89,53 @@ BOOL cli_credentials_set_username(struct cli_credentials *cred, const char *val,
}
/**
+ * Obtain the client principal for this credentials context.
+ * @param cred credentials context
+ * @retval The username set on this context.
+ * @note Return value will never be NULL except by programmer error.
+ */
+const char *cli_credentials_get_principal(struct cli_credentials *cred, TALLOC_CTX *mem_ctx)
+{
+ if (cred->machine_account_pending) {
+ cli_credentials_set_machine_account(cred);
+ }
+
+ if (cred->principal_obtained == CRED_CALLBACK) {
+ cred->principal = cred->principal_cb(cred);
+ cred->principal_obtained = CRED_SPECIFIED;
+ }
+
+ if (cred->principal_obtained < cred->username_obtained) {
+ return talloc_asprintf(mem_ctx, "%s@%s",
+ cli_credentials_get_username(cred, mem_ctx),
+ cli_credentials_get_realm(cred));
+ }
+ return talloc_reference(mem_ctx, cred->principal);
+}
+
+BOOL cli_credentials_set_principal(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained)
+{
+ if (obtained >= cred->principal_obtained) {
+ cred->principal = talloc_strdup(cred, val);
+ cred->principal_obtained = obtained;
+ return True;
+ }
+
+ return False;
+}
+
+BOOL cli_credentials_authentication_requested(struct cli_credentials *cred)
+{
+ if (cred->principal_obtained == CRED_SPECIFIED) {
+ return True;
+ }
+ if (cred->username_obtained >= CRED_SPECIFIED) {
+ return True;
+ }
+ return False;
+}
+
+/**
* Obtain the password for this credentials context.
* @param cred credentials context
* @retval If set, the cleartext password, otherwise NULL
@@ -148,6 +205,207 @@ BOOL cli_credentials_set_nt_hash(struct cli_credentials *cred,
return False;
}
+int cli_credentials_set_from_ccache(struct cli_credentials *cred,
+ enum credentials_obtained obtained)
+{
+
+ krb5_principal princ;
+ krb5_error_code ret;
+ char *name;
+ char **realm;
+
+ ret = krb5_cc_get_principal(cred->ccache->smb_krb5_context->krb5_context,
+ cred->ccache->ccache, &princ);
+
+ if (ret) {
+ char *err_mess = smb_get_krb5_error_message(cred->ccache->smb_krb5_context->krb5_context, ret, cred);
+ DEBUG(1,("failed to get principal from ccache: %s\n",
+ err_mess));
+ talloc_free(err_mess);
+ return ret;
+ }
+
+ ret = krb5_unparse_name(cred->ccache->smb_krb5_context->krb5_context, princ, &name);
+ if (ret) {
+ char *err_mess = smb_get_krb5_error_message(cred->ccache->smb_krb5_context->krb5_context, ret, cred);
+ DEBUG(1,("failed to unparse principal from ccache: %s\n",
+ err_mess));
+ talloc_free(err_mess);
+ return ret;
+ }
+
+ realm = krb5_princ_realm(cred->ccache->smb_krb5_context->krb5_context, princ);
+
+ cli_credentials_set_realm(cred, *realm, obtained);
+ cli_credentials_set_principal(cred, name, obtained);
+
+ free(name);
+
+ krb5_free_principal(cred->ccache->smb_krb5_context->krb5_context, princ);
+
+ cred->ccache_obtained = obtained;
+
+ return 0;
+}
+
+
+static int free_mccache(void *ptr) {
+ struct ccache_container *ccc = ptr;
+ krb5_cc_destroy(ccc->smb_krb5_context->krb5_context, ccc->ccache);
+
+ return 0;
+}
+
+static int free_dccache(void *ptr) {
+ struct ccache_container *ccc = ptr;
+ krb5_cc_close(ccc->smb_krb5_context->krb5_context, ccc->ccache);
+
+ return 0;
+}
+
+static int cli_credentials_set_ccache(struct cli_credentials *cred,
+ const char *name,
+ enum credentials_obtained obtained)
+{
+ krb5_error_code ret;
+ krb5_principal princ;
+ struct ccache_container *ccc = talloc(cred, struct ccache_container);
+ if (!ccc) {
+ return ENOMEM;
+ }
+
+ ret = smb_krb5_init_context(ccc, &ccc->smb_krb5_context);
+ if (ret) {
+ talloc_free(ccc);
+ return ret;
+ }
+ if (name) {
+ ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache);
+ if (ret) {
+ DEBUG(1,("failed to read krb5 ccache: %s: %s\n",
+ name,
+ smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
+ talloc_free(ccc);
+ return ret;
+ }
+ } else {
+ ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache);
+ if (ret) {
+ DEBUG(1,("failed to read default krb5 ccache: %s\n",
+ smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
+ talloc_free(ccc);
+ return ret;
+ }
+ }
+
+ talloc_set_destructor(ccc, free_dccache);
+
+ ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ);
+
+ if (ret) {
+ DEBUG(1,("failed to get principal from default ccache: %s\n",
+ smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
+ talloc_free(ccc);
+ return ret;
+ }
+
+ krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ);
+
+ cred->ccache = ccc;
+ talloc_steal(cred, ccc);
+
+ ret = cli_credentials_set_from_ccache(cred, obtained);
+
+ if (ret) {
+ return ret;
+ }
+
+ return 0;
+}
+
+
+int cli_credentials_new_ccache(struct cli_credentials *cred)
+{
+ krb5_error_code ret;
+ char *rand_string;
+ struct ccache_container *ccc = talloc(cred, struct ccache_container);
+ char *ccache_name;
+ if (!ccc) {
+ return ENOMEM;
+ }
+
+ rand_string = generate_random_str(NULL, 16);
+ if (!rand_string) {
+ talloc_free(ccc);
+ return ENOMEM;
+ }
+
+ ccache_name = talloc_asprintf(ccc, "MEMORY:%s",
+ rand_string);
+ talloc_free(rand_string);
+
+ if (!ccache_name) {
+ talloc_free(ccc);
+ return ENOMEM;
+ }
+
+ ret = smb_krb5_init_context(ccc, &ccc->smb_krb5_context);
+ if (ret) {
+ talloc_free(ccache_name);
+ talloc_free(ccc);
+ return ret;
+ }
+
+ ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, ccache_name, &ccc->ccache);
+ if (ret) {
+ DEBUG(1,("failed to generate a new krb5 ccache (%s): %s\n",
+ ccache_name,
+ smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)));
+ talloc_free(ccache_name);
+ talloc_free(ccc);
+ return ret;
+ }
+
+ talloc_set_destructor(ccc, free_mccache);
+
+ cred->ccache = ccc;
+ talloc_steal(cred, ccc);
+ talloc_free(ccache_name);
+
+ return ret;
+}
+
+int cli_credentials_get_ccache(struct cli_credentials *cred, struct ccache_container **ccc)
+{
+ krb5_error_code ret;
+
+ if (cred->ccache_obtained >= (MAX(cred->principal_obtained,
+ cred->username_obtained))) {
+ *ccc = cred->ccache;
+ return 0;
+ }
+ if (cli_credentials_is_anonymous(cred)) {
+ return EINVAL;
+ }
+
+ ret = cli_credentials_new_ccache(cred);
+ if (ret) {
+ return ret;
+ }
+ ret = kinit_to_ccache(cred, cred, cred->ccache->smb_krb5_context, cred->ccache->ccache);
+ if (ret) {
+ return ret;
+ }
+ ret = cli_credentials_set_from_ccache(cred, cred->principal_obtained);
+
+ if (ret) {
+ return ret;
+ }
+ *ccc = cred->ccache;
+ return ret;
+}
+
+
/**
* Obtain the 'short' or 'NetBIOS' domain for this credentials context.
* @param cred credentials context
@@ -160,6 +418,11 @@ const char *cli_credentials_get_domain(struct cli_credentials *cred)
cli_credentials_set_machine_account(cred);
}
+ /* If we have a principal set on this, we want to login with "" domain and user@realm */
+ if (cred->domain_obtained < cred->principal_obtained) {
+ return "";
+ }
+
if (cred->domain_obtained == CRED_CALLBACK) {
cred->domain = cred->domain_cb(cred);
cred->domain_obtained = CRED_SPECIFIED;
@@ -201,21 +464,6 @@ const char *cli_credentials_get_realm(struct cli_credentials *cred)
}
/**
- * Obtain the user's Kerberos principal for this credentials context.
- * @param cred credentials context
- * @param mem_ctx A talloc context to return the prinipal name on.
- * @retval The user's Kerberos principal
- * @note Return value may be NULL due to out-of memeory or invalid mem_ctx
- */
-char *cli_credentials_get_principal(struct cli_credentials *cred,
- TALLOC_CTX *mem_ctx)
-{
- return talloc_asprintf(mem_ctx, "%s@%s",
- cli_credentials_get_username(cred),
- cli_credentials_get_realm(cred));
-}
-
-/**
* Set the realm for this credentials context, and force it to
* uppercase for the sainity of our local kerberos libraries
*/
@@ -419,8 +667,10 @@ void cli_credentials_parse_string(struct cli_credentials *credentials, const cha
}
if ((p = strchr_m(uname,'@'))) {
+ cli_credentials_set_principal(credentials, uname, obtained);
*p = 0;
cli_credentials_set_realm(credentials, p+1, obtained);
+ return;
} else if ((p = strchr_m(uname,'\\')) || (p = strchr_m(uname, '/'))) {
*p = 0;
cli_credentials_set_domain(credentials, uname, obtained);
@@ -437,9 +687,10 @@ void cli_credentials_parse_string(struct cli_credentials *credentials, const cha
*/
void cli_credentials_set_conf(struct cli_credentials *cred)
{
- cli_credentials_set_domain(cred, lp_workgroup(), CRED_GUESSED);
- cli_credentials_set_workstation(cred, lp_netbios_name(), CRED_GUESSED);
- cli_credentials_set_realm(cred, lp_realm(), CRED_GUESSED);
+ cli_credentials_set_username(cred, "", CRED_UNINITIALISED);
+ cli_credentials_set_domain(cred, lp_workgroup(), CRED_UNINITIALISED);
+ cli_credentials_set_workstation(cred, lp_netbios_name(), CRED_UNINITIALISED);
+ cli_credentials_set_realm(cred, lp_realm(), CRED_UNINITIALISED);
}
/**
@@ -452,35 +703,36 @@ void cli_credentials_guess(struct cli_credentials *cred)
{
char *p;
- cli_credentials_set_username(cred, "", CRED_GUESSED);
cli_credentials_set_conf(cred);
if (getenv("LOGNAME")) {
- cli_credentials_set_username(cred, getenv("LOGNAME"), CRED_GUESSED);
+ cli_credentials_set_username(cred, getenv("LOGNAME"), CRED_GUESS_ENV);
}
if (getenv("USER")) {
- cli_credentials_parse_string(cred, getenv("USER"), CRED_GUESSED);
+ cli_credentials_parse_string(cred, getenv("USER"), CRED_GUESS_ENV);
if ((p = strchr_m(getenv("USER"),'%'))) {
memset(p,0,strlen(cred->password));
}
}
if (getenv("DOMAIN")) {
- cli_credentials_set_domain(cred, getenv("DOMAIN"), CRED_GUESSED);
+ cli_credentials_set_domain(cred, getenv("DOMAIN"), CRED_GUESS_ENV);
}
if (getenv("PASSWD")) {
- cli_credentials_set_password(cred, getenv("PASSWD"), CRED_GUESSED);
+ cli_credentials_set_password(cred, getenv("PASSWD"), CRED_GUESS_ENV);
}
if (getenv("PASSWD_FD")) {
- cli_credentials_parse_password_fd(cred, atoi(getenv("PASSWD_FD")), CRED_GUESSED);
+ cli_credentials_parse_password_fd(cred, atoi(getenv("PASSWD_FD")), CRED_GUESS_FILE);
}
if (getenv("PASSWD_FILE")) {
- cli_credentials_parse_password_file(cred, getenv("PASSWD_FILE"), CRED_GUESSED);
+ cli_credentials_parse_password_file(cred, getenv("PASSWD_FILE"), CRED_GUESS_FILE);
}
+
+ cli_credentials_set_ccache(cred, NULL, CRED_GUESS_FILE);
}
/**
@@ -690,13 +942,17 @@ void cli_credentials_set_anonymous(struct cli_credentials *cred)
BOOL cli_credentials_is_anonymous(struct cli_credentials *cred)
{
- const char *username = cli_credentials_get_username(cred);
-
+ TALLOC_CTX *tmp_ctx = talloc_new(cred);
+ const char *username = cli_credentials_get_username(cred, tmp_ctx);
+
/* Yes, it is deliberate that we die if we have a NULL pointer
* here - anonymous is "", not NULL, which is 'never specified,
* never guessed', ie programmer bug */
- if (!username[0])
+ if (!username[0]) {
+ talloc_free(tmp_ctx);
return True;
-
+ }
+
+ talloc_free(tmp_ctx);
return False;
}
diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c
index bb89fc910e..3d47863067 100644
--- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c
+++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c
@@ -474,8 +474,7 @@ int ildb_connect(struct ldb_context *ldb, const char *url,
ldb->modules->private_data = ildb;
ldb->modules->ops = &ildb_ops;
- if (cmdline_credentials != NULL &&
- cmdline_credentials->username_obtained > CRED_GUESSED) {
+ if (cmdline_credentials != NULL && cli_credentials_authentication_requested(cmdline_credentials)) {
status = ldap_bind_sasl(ildb->ldap, cmdline_credentials);
if (!NT_STATUS_IS_OK(status)) {
ldb_debug(ldb, LDB_DEBUG_ERROR, "Failed to bind - %s\n",
diff --git a/source4/lib/samba3/samba3dump.c b/source4/lib/samba3/samba3dump.c
index b95fc0d4b2..6be91c0db2 100644
--- a/source4/lib/samba3/samba3dump.c
+++ b/source4/lib/samba3/samba3dump.c
@@ -86,8 +86,11 @@ static NTSTATUS print_samba3_secrets(struct samba3_secrets *secrets)
print_header("Secrets");
printf("IPC Credentials:\n");
- if (secrets->ipc_cred->username_obtained)
- printf(" User: %s\n", cli_credentials_get_username(secrets->ipc_cred));
+ if (secrets->ipc_cred->username_obtained) {
+ TALLOC_CTX *mem_ctx = talloc_new(NULL);
+ printf(" User: %s\n", cli_credentials_get_username(secrets->ipc_cred, mem_ctx));
+ talloc_free(mem_ctx);
+ }
if (secrets->ipc_cred->password_obtained)
printf(" Password: %s\n", cli_credentials_get_password(secrets->ipc_cred));
diff --git a/source4/libcli/composite/sesssetup.c b/source4/libcli/composite/sesssetup.c
index b27290d5e4..b925f99bed 100644
--- a/source4/libcli/composite/sesssetup.c
+++ b/source4/libcli/composite/sesssetup.c
@@ -174,7 +174,7 @@ static NTSTATUS session_setup_nt1(struct composite_context *c,
state->setup.nt1.in.capabilities = io->in.capabilities;
state->setup.nt1.in.os = "Unix";
state->setup.nt1.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING);
- state->setup.nt1.in.user = cli_credentials_get_username(io->in.credentials);
+ state->setup.nt1.in.user = cli_credentials_get_username(io->in.credentials, state);
state->setup.nt1.in.domain = cli_credentials_get_domain(io->in.credentials);
if (!password) {
@@ -260,7 +260,7 @@ static NTSTATUS session_setup_old(struct composite_context *c,
state->setup.old.in.vc_num = 1;
state->setup.old.in.sesskey = io->in.sesskey;
state->setup.old.in.domain = cli_credentials_get_domain(io->in.credentials);
- state->setup.old.in.user = cli_credentials_get_username(io->in.credentials);
+ state->setup.old.in.user = cli_credentials_get_username(io->in.credentials, state);
state->setup.old.in.os = "Unix";
state->setup.old.in.lanman = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING);
diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c
index ae4ce94269..77c8c028af 100644
--- a/source4/librpc/rpc/dcerpc_schannel.c
+++ b/source4/librpc/rpc/dcerpc_schannel.c
@@ -110,7 +110,7 @@ static NTSTATUS dcerpc_schannel_key(TALLOC_CTX *tmp_ctx,
negotiate_flags);
a.in.server_name = r.in.server_name;
- a.in.account_name = cli_credentials_get_username(credentials);
+ a.in.account_name = cli_credentials_get_username(credentials, tmp_ctx);
a.in.secure_channel_type =
cli_credentials_get_secure_channel_type(credentials);
a.in.computer_name = cli_credentials_get_workstation(credentials);
@@ -153,7 +153,7 @@ NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to setup credentials for account %s: %s\n",
- cli_credentials_get_username(credentials),
+ cli_credentials_get_username(credentials, tmp_ctx),
nt_errstr(status)));
return status;
}
diff --git a/source4/scripting/ejs/smbcalls_auth.c b/source4/scripting/ejs/smbcalls_auth.c
index ef3b86a8b4..8df69cf087 100644
--- a/source4/scripting/ejs/smbcalls_auth.c
+++ b/source4/scripting/ejs/smbcalls_auth.c
@@ -119,7 +119,7 @@ static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv)
ejsSetErrorMsg(eid, "userAuth requires a 'creds' element");
return -1;
}
- username = cli_credentials_get_username(creds);
+ username = cli_credentials_get_username(creds, tmp_ctx);
password = cli_credentials_get_password(creds);
domain = cli_credentials_get_domain(creds);
remote_host = cli_credentials_get_workstation(creds);
diff --git a/source4/scripting/ejs/smbcalls_creds.c b/source4/scripting/ejs/smbcalls_creds.c
index cc2ccf8c47..f9d231293a 100644
--- a/source4/scripting/ejs/smbcalls_creds.c
+++ b/source4/scripting/ejs/smbcalls_creds.c
@@ -73,7 +73,7 @@ static int ejs_creds_get_username(MprVarHandle eid, int argc, struct MprVar **ar
{
struct cli_credentials *creds = ejs_creds_get_credentials(eid);
- mpr_Return(eid, mprString(cli_credentials_get_username(creds)));
+ mpr_Return(eid, mprString(cli_credentials_get_username(creds, mprMemCtx())));
return 0;
}
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 14353ff590..10ac1cbba3 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -38,7 +38,7 @@ static BOOL test_LogonUasLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
struct netr_LogonUasLogon r;
r.in.server_name = NULL;
- r.in.account_name = cli_credentials_get_username(cmdline_credentials),
+ r.in.account_name = cli_credentials_get_username(cmdline_credentials, mem_ctx);
r.in.workstation = TEST_MACHINE_NAME;
printf("Testing LogonUasLogon\n");
@@ -59,7 +59,7 @@ static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
struct netr_LogonUasLogoff r;
r.in.server_name = NULL;
- r.in.account_name = cli_credentials_get_username(cmdline_credentials),
+ r.in.account_name = cli_credentials_get_username(cmdline_credentials, mem_ctx);
r.in.workstation = TEST_MACHINE_NAME;
printf("Testing LogonUasLogoff\n");
@@ -487,7 +487,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
struct netr_LogonSamLogon r;
struct netr_Authenticator auth, auth2;
struct netr_NetworkInfo ninfo;
- const char *username = cli_credentials_get_username(cmdline_credentials);
+ const char *username = cli_credentials_get_username(cmdline_credentials, mem_ctx);
const char *password = cli_credentials_get_password(cmdline_credentials);
struct creds_CredentialState *creds;
diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c
index 607dbaec8a..42051795c8 100644
--- a/source4/torture/rpc/samlogon.c
+++ b/source4/torture/rpc/samlogon.c
@@ -1366,13 +1366,13 @@ BOOL torture_rpc_samlogon(void)
} usercreds[] = {
{
cli_credentials_get_domain(cmdline_credentials),
- cli_credentials_get_username(cmdline_credentials),
+ cli_credentials_get_username(cmdline_credentials, mem_ctx),
cli_credentials_get_password(cmdline_credentials),
True
},
{
cli_credentials_get_realm(cmdline_credentials),
- cli_credentials_get_username(cmdline_credentials),
+ cli_credentials_get_username(cmdline_credentials, mem_ctx),
cli_credentials_get_password(cmdline_credentials),
True
},
@@ -1380,7 +1380,7 @@ BOOL torture_rpc_samlogon(void)
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
- cli_credentials_get_username(cmdline_credentials),
+ cli_credentials_get_username(cmdline_credentials, mem_ctx),
cli_credentials_get_domain(cmdline_credentials)
),
cli_credentials_get_password(cmdline_credentials),
@@ -1390,7 +1390,7 @@ BOOL torture_rpc_samlogon(void)
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
- cli_credentials_get_username(cmdline_credentials),
+ cli_credentials_get_username(cmdline_credentials, mem_ctx),
cli_credentials_get_realm(cmdline_credentials)
),
cli_credentials_get_password(cmdline_credentials),
diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
index 580c6f57eb..3f02622e1c 100644
--- a/source4/torture/rpc/schannel.c
+++ b/source4/torture/rpc/schannel.c
@@ -92,7 +92,7 @@ static BOOL test_netlogon_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct netr_LogonSamLogon r;
struct netr_Authenticator auth, auth2;
struct netr_NetworkInfo ninfo;
- const char *username = cli_credentials_get_username(cmdline_credentials);
+ const char *username = cli_credentials_get_username(cmdline_credentials, mem_ctx);
const char *password = cli_credentials_get_password(cmdline_credentials);
int i;
BOOL ret = True;
diff --git a/source4/utils/net/net_password.c b/source4/utils/net/net_password.c
index 1912beeb41..0bfb8a5be8 100644
--- a/source4/utils/net/net_password.c
+++ b/source4/utils/net/net_password.c
@@ -49,7 +49,7 @@ static int net_password_change(struct net_context *ctx, int argc, const char **a
} else {
password_prompt = talloc_asprintf(ctx->mem_ctx, "Enter new password for account [%s\\%s]:",
cli_credentials_get_domain(ctx->credentials),
- cli_credentials_get_username(ctx->credentials));
+ cli_credentials_get_username(ctx->credentials, ctx->mem_ctx));
new_password = getpass(password_prompt);
}
@@ -61,7 +61,7 @@ static int net_password_change(struct net_context *ctx, int argc, const char **a
/* prepare password change */
r.generic.level = LIBNET_CHANGE_PASSWORD_GENERIC;
- r.generic.in.account_name = cli_credentials_get_username(ctx->credentials);
+ r.generic.in.account_name = cli_credentials_get_username(ctx->credentials, ctx->mem_ctx);
r.generic.in.domain_name = cli_credentials_get_domain(ctx->credentials);
r.generic.in.oldpassword = cli_credentials_get_password(ctx->credentials);
r.generic.in.newpassword = new_password;
diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c
index 7e1ca011e4..b10d4af6ce 100644
--- a/source4/utils/ntlm_auth.c
+++ b/source4/utils/ntlm_auth.c
@@ -349,8 +349,6 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
cli_credentials_set_conf(creds);
if (opt_username) {
cli_credentials_set_username(creds, opt_username, CRED_SPECIFIED);
- } else {
- cli_credentials_set_username(creds, "", CRED_GUESSED);
}
if (opt_domain) {
cli_credentials_set_domain(creds, opt_domain, CRED_SPECIFIED);