summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-08-30 01:19:41 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:34:59 -0500
commit6f9b901fa0db18faae603db67d8d31e229d92c27 (patch)
tree8c54a8369d17994a8ef087c95038b81d87f50352
parentc0293aa7159c8b5c9f1a1b13f64af08e5a55ad6a (diff)
downloadsamba-6f9b901fa0db18faae603db67d8d31e229d92c27.tar.gz
samba-6f9b901fa0db18faae603db67d8d31e229d92c27.tar.bz2
samba-6f9b901fa0db18faae603db67d8d31e229d92c27.zip
r9772: Make credentials callbacks more consistant with the abstraction
function interface used in the credentials code. Fix bug in ntlm_auth, where we would overwrite the PW specified as a first input. (Reported and chased by Kai Blin <blin@gmx.net>, bug #3040) Andrew Bartlett (This used to be commit 04af95bd31de39ad6aff349a4838dd77cb300034)
-rw-r--r--source4/gtk/common/credentials.c17
-rw-r--r--source4/lib/cmdline/credentials.c9
-rw-r--r--source4/lib/credentials.c99
-rw-r--r--source4/utils/ntlm_auth.c113
4 files changed, 165 insertions, 73 deletions
diff --git a/source4/gtk/common/credentials.c b/source4/gtk/common/credentials.c
index ccc9759e8f..01132ec6bd 100644
--- a/source4/gtk/common/credentials.c
+++ b/source4/gtk/common/credentials.c
@@ -132,18 +132,7 @@ static const char *gtk_get_domain(struct cli_credentials *credentials)
void cli_credentials_set_gtk_callbacks(struct cli_credentials *cred)
{
- if (cred->password_obtained <= CRED_CALLBACK) {
- cred->password_cb = gtk_get_userpassword;
- cred->password_obtained = CRED_CALLBACK;
- }
-
- if (cred->username_obtained <= CRED_CALLBACK) {
- cred->username_cb = gtk_get_username;
- cred->username_obtained = CRED_CALLBACK;
- }
-
- if (cred->domain_obtained <= CRED_CALLBACK) {
- cred->domain_cb = gtk_get_domain;
- cred->domain_obtained = CRED_CALLBACK;
- }
+ cli_credentials_set_username_callback(cred, gtk_get_username);
+ cli_credentials_set_domain_callback(cred, gtk_get_domain);
+ cli_credentials_set_password_callback(cred, gtk_get_userpassword);
}
diff --git a/source4/lib/cmdline/credentials.c b/source4/lib/cmdline/credentials.c
index 7832e01e4b..f46a03b236 100644
--- a/source4/lib/cmdline/credentials.c
+++ b/source4/lib/cmdline/credentials.c
@@ -29,8 +29,8 @@ static const char *cmdline_get_userpassword(struct cli_credentials *credentials)
{
char *prompt;
char *ret;
- char *domain;
- char *username;
+ const char *domain;
+ const char *username;
TALLOC_CTX *mem_ctx = talloc_new(NULL);
domain = cli_credentials_get_domain(credentials);
@@ -51,8 +51,5 @@ static const char *cmdline_get_userpassword(struct cli_credentials *credentials)
void cli_credentials_set_cmdline_callbacks(struct cli_credentials *cred)
{
- if (cred->password_obtained <= CRED_CALLBACK) {
- cred->password_cb = cmdline_get_userpassword;
- cred->password_obtained = CRED_CALLBACK;
- }
+ cli_credentials_set_password_callback(cred, cmdline_get_userpassword);
}
diff --git a/source4/lib/credentials.c b/source4/lib/credentials.c
index 579f199d2e..162b52e5d0 100644
--- a/source4/lib/credentials.c
+++ b/source4/lib/credentials.c
@@ -77,7 +77,8 @@ const char *cli_credentials_get_username(struct cli_credentials *cred, TALLOC_CT
return talloc_reference(mem_ctx, cred->username);
}
-BOOL cli_credentials_set_username(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained)
+BOOL cli_credentials_set_username(struct cli_credentials *cred,
+ const char *val, enum credentials_obtained obtained)
{
if (obtained >= cred->username_obtained) {
cred->username = talloc_strdup(cred, val);
@@ -88,6 +89,20 @@ BOOL cli_credentials_set_username(struct cli_credentials *cred, const char *val,
return False;
}
+BOOL cli_credentials_set_username_callback(struct cli_credentials *cred,
+ const char *(*username_cb) (struct cli_credentials *))
+{
+ if (cred->username_obtained < CRED_CALLBACK) {
+ cred->username_cb = username_cb;
+ cred->username_obtained = CRED_CALLBACK;
+ return True;
+ }
+
+ return False;
+}
+
+
+
/**
* Obtain the client principal for this credentials context.
* @param cred credentials context
@@ -124,6 +139,18 @@ BOOL cli_credentials_set_principal(struct cli_credentials *cred, const char *val
return False;
}
+BOOL cli_credentials_set_principal_callback(struct cli_credentials *cred,
+ const char *(*principal_cb) (struct cli_credentials *))
+{
+ if (cred->principal_obtained < CRED_CALLBACK) {
+ cred->principal_cb = principal_cb;
+ cred->principal_obtained = CRED_CALLBACK;
+ return True;
+ }
+
+ return False;
+}
+
BOOL cli_credentials_authentication_requested(struct cli_credentials *cred)
{
if (cred->principal_obtained >= CRED_SPECIFIED) {
@@ -154,7 +181,9 @@ const char *cli_credentials_get_password(struct cli_credentials *cred)
return cred->password;
}
-BOOL cli_credentials_set_password(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained)
+BOOL cli_credentials_set_password(struct cli_credentials *cred,
+ const char *val,
+ enum credentials_obtained obtained)
{
if (obtained >= cred->password_obtained) {
cred->password = talloc_strdup(cred, val);
@@ -167,6 +196,18 @@ BOOL cli_credentials_set_password(struct cli_credentials *cred, const char *val,
return False;
}
+BOOL cli_credentials_set_password_callback(struct cli_credentials *cred,
+ const char *(*password_cb) (struct cli_credentials *))
+{
+ if (cred->password_obtained < CRED_CALLBACK) {
+ cred->password_cb = password_cb;
+ cred->password_obtained = CRED_CALLBACK;
+ return True;
+ }
+
+ return False;
+}
+
/**
* Obtain the password for this credentials context.
* @param cred credentials context
@@ -375,7 +416,8 @@ int cli_credentials_new_ccache(struct cli_credentials *cred)
return ret;
}
-int cli_credentials_get_ccache(struct cli_credentials *cred, struct ccache_container **ccc)
+int cli_credentials_get_ccache(struct cli_credentials *cred,
+ struct ccache_container **ccc)
{
krb5_error_code ret;
@@ -432,7 +474,9 @@ const char *cli_credentials_get_domain(struct cli_credentials *cred)
}
-BOOL cli_credentials_set_domain(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained)
+BOOL cli_credentials_set_domain(struct cli_credentials *cred,
+ const char *val,
+ enum credentials_obtained obtained)
{
if (obtained >= cred->domain_obtained) {
cred->domain = talloc_strdup(cred, val);
@@ -443,6 +487,18 @@ BOOL cli_credentials_set_domain(struct cli_credentials *cred, const char *val, e
return False;
}
+BOOL cli_credentials_set_domain_callback(struct cli_credentials *cred,
+ const char *(*domain_cb) (struct cli_credentials *))
+{
+ if (cred->domain_obtained < CRED_CALLBACK) {
+ cred->domain_cb = domain_cb;
+ cred->domain_obtained = CRED_CALLBACK;
+ return True;
+ }
+
+ return False;
+}
+
/**
* Obtain the Kerberos realm for this credentials context.
* @param cred credentials context
@@ -467,7 +523,9 @@ const char *cli_credentials_get_realm(struct cli_credentials *cred)
* Set the realm for this credentials context, and force it to
* uppercase for the sainity of our local kerberos libraries
*/
-BOOL cli_credentials_set_realm(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained)
+BOOL cli_credentials_set_realm(struct cli_credentials *cred,
+ const char *val,
+ enum credentials_obtained obtained)
{
if (obtained >= cred->realm_obtained) {
cred->realm = strupper_talloc(cred, val);
@@ -478,6 +536,18 @@ BOOL cli_credentials_set_realm(struct cli_credentials *cred, const char *val, en
return False;
}
+BOOL cli_credentials_set_realm_callback(struct cli_credentials *cred,
+ const char *(*realm_cb) (struct cli_credentials *))
+{
+ if (cred->realm_obtained < CRED_CALLBACK) {
+ cred->realm_cb = realm_cb;
+ cred->realm_obtained = CRED_CALLBACK;
+ return True;
+ }
+
+ return False;
+}
+
/**
* Obtain the 'short' or 'NetBIOS' workstation name for this credentials context.
*
@@ -495,7 +565,9 @@ const char *cli_credentials_get_workstation(struct cli_credentials *cred)
return cred->workstation;
}
-BOOL cli_credentials_set_workstation(struct cli_credentials *cred, const char *val, enum credentials_obtained obtained)
+BOOL cli_credentials_set_workstation(struct cli_credentials *cred,
+ const char *val,
+ enum credentials_obtained obtained)
{
if (obtained >= cred->workstation_obtained) {
cred->workstation = talloc_strdup(cred, val);
@@ -506,6 +578,18 @@ BOOL cli_credentials_set_workstation(struct cli_credentials *cred, const char *v
return False;
}
+BOOL cli_credentials_set_workstation_callback(struct cli_credentials *cred,
+ const char *(*workstation_cb) (struct cli_credentials *))
+{
+ if (cred->workstation_obtained < CRED_CALLBACK) {
+ cred->workstation_cb = workstation_cb;
+ cred->workstation_obtained = CRED_CALLBACK;
+ return True;
+ }
+
+ return False;
+}
+
/**
* Read a file descriptor, and parse it for a password (eg from a file or stdin)
*
@@ -514,7 +598,8 @@ BOOL cli_credentials_set_workstation(struct cli_credentials *cred, const char *v
* @param obtained This enum describes how 'specified' this password is
*/
-BOOL cli_credentials_parse_password_fd(struct cli_credentials *credentials, int fd, enum credentials_obtained obtained)
+BOOL cli_credentials_parse_password_fd(struct cli_credentials *credentials,
+ int fd, enum credentials_obtained obtained)
{
char *p;
char pass[128];
diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c
index b10d4af6ce..fe29cff021 100644
--- a/source4/utils/ntlm_auth.c
+++ b/source4/utils/ntlm_auth.c
@@ -292,13 +292,32 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
DATA_BLOB out = data_blob(NULL, 0);
char *out_base64 = NULL;
const char *reply_arg = NULL;
- struct gensec_security **gensec_state = (struct gensec_security **)private;
+ struct gensec_ntlm_state {
+ struct gensec_security *gensec_state;
+ const char *set_password;
+ };
+ struct gensec_ntlm_state *state;
+
NTSTATUS nt_status;
BOOL first = False;
const char *reply_code;
struct cli_credentials *creds;
TALLOC_CTX *mem_ctx;
+
+ if (*private) {
+ state = *private;
+ } else {
+ state = talloc_zero(NULL, struct gensec_ntlm_state);
+ if (!state) {
+ mux_printf(mux_id, "BH No Memory\n");
+ exit(1);
+ }
+ *private = state;
+ if (opt_password) {
+ state->set_password = opt_password;
+ }
+ }
if (strlen(buf) < 2) {
DEBUG(1, ("query [%s] invalid", buf));
@@ -313,9 +332,9 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
}
if (strncmp(buf, "YR", 2) == 0) {
- if (gensec_state && *gensec_state) {
- talloc_free(*gensec_state);
- *gensec_state = NULL;
+ if (state->gensec_state) {
+ talloc_free(state->gensec_state);
+ state->gensec_state = NULL;
}
} else if ( (strncmp(buf, "OK", 2) == 0)) {
/* do nothing */
@@ -334,42 +353,21 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
}
/* setup gensec */
- if (!(gensec_state && *gensec_state)) {
+ if (!(state->gensec_state)) {
switch (stdio_helper_mode) {
case GSS_SPNEGO_CLIENT:
case NTLMSSP_CLIENT_1:
/* setup the client side */
- nt_status = gensec_client_start(NULL, gensec_state, NULL);
+ nt_status = gensec_client_start(NULL, &state->gensec_state, NULL);
if (!NT_STATUS_IS_OK(nt_status)) {
exit(1);
}
- creds = cli_credentials_init(*gensec_state);
- cli_credentials_set_conf(creds);
- if (opt_username) {
- cli_credentials_set_username(creds, opt_username, CRED_SPECIFIED);
- }
- if (opt_domain) {
- cli_credentials_set_domain(creds, opt_domain, CRED_SPECIFIED);
- }
- if (opt_password) {
- cli_credentials_set_password(creds, opt_password, CRED_SPECIFIED);
- } else {
- creds->password_obtained = CRED_CALLBACK;
- creds->password_cb = get_password;
- creds->priv_data = (void*)mux_id;
- }
- if (opt_workstation) {
- cli_credentials_set_workstation(creds, opt_workstation, CRED_SPECIFIED);
- }
-
- gensec_set_credentials(*gensec_state, creds);
-
break;
case GSS_SPNEGO_SERVER:
case SQUID_2_5_NTLMSSP:
- if (!NT_STATUS_IS_OK(gensec_server_start(NULL, gensec_state, NULL))) {
+ if (!NT_STATUS_IS_OK(gensec_server_start(NULL, &state->gensec_state, NULL))) {
exit(1);
}
break;
@@ -377,10 +375,29 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
abort();
}
+ creds = cli_credentials_init(state->gensec_state);
+ cli_credentials_set_conf(creds);
+ if (opt_username) {
+ cli_credentials_set_username(creds, opt_username, CRED_SPECIFIED);
+ }
+ if (opt_domain) {
+ cli_credentials_set_domain(creds, opt_domain, CRED_SPECIFIED);
+ }
+ if (state->set_password) {
+ cli_credentials_set_password(creds, state->set_password, CRED_SPECIFIED);
+ } else {
+ cli_credentials_set_password_callback(creds, get_password);
+ creds->priv_data = (void*)mux_id;
+ }
+ if (opt_workstation) {
+ cli_credentials_set_workstation(creds, opt_workstation, CRED_SPECIFIED);
+ }
+ gensec_set_credentials(state->gensec_state, creds);
+
switch (stdio_helper_mode) {
case GSS_SPNEGO_CLIENT:
case GSS_SPNEGO_SERVER:
- nt_status = gensec_start_mech_by_oid(*gensec_state, GENSEC_OID_SPNEGO);
+ nt_status = gensec_start_mech_by_oid(state->gensec_state, GENSEC_OID_SPNEGO);
if (!in.length) {
first = True;
}
@@ -390,7 +407,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
first = True;
}
case SQUID_2_5_NTLMSSP:
- nt_status = gensec_start_mech_by_oid(*gensec_state, GENSEC_OID_NTLMSSP);
+ nt_status = gensec_start_mech_by_oid(state->gensec_state, GENSEC_OID_NTLMSSP);
break;
default:
abort();
@@ -401,32 +418,36 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
mux_printf(mux_id, "BH\n");
return;
}
+
}
+
+ /* update */
+ mem_ctx = talloc_named(NULL, 0, "manage_gensec_request internal mem_ctx");
if (strncmp(buf, "PW ", 3) == 0) {
-
- cli_credentials_set_password((*gensec_state)->credentials,
- talloc_strndup((*gensec_state),
- (const char *)in.data,
- in.length),
+ state->set_password = talloc_strndup(state,
+ (const char *)in.data,
+ in.length);
+
+ cli_credentials_set_password(gensec_get_credentials(state->gensec_state),
+ state->set_password,
CRED_SPECIFIED);
mux_printf(mux_id, "OK\n");
data_blob_free(&in);
+ talloc_free(mem_ctx);
return;
}
- /* update */
- mem_ctx = talloc_named(NULL, 0, "manage_gensec_request internal mem_ctx");
-
if (strncmp(buf, "UG", 2) == 0) {
int i;
char *grouplist = NULL;
struct auth_session_info *session_info;
- if (!NT_STATUS_IS_OK(gensec_session_info(*gensec_state, &session_info))) {
+ if (!NT_STATUS_IS_OK(gensec_session_info(state->gensec_state, &session_info))) {
DEBUG(1, ("gensec_session_info failed: %s\n", nt_errstr(nt_status)));
mux_printf(mux_id, "BH %s\n", nt_errstr(nt_status));
data_blob_free(&in);
+ talloc_free(mem_ctx);
return;
}
@@ -447,7 +468,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
return;
}
- nt_status = gensec_update(*gensec_state, mem_ctx, in, &out);
+ nt_status = gensec_update(state->gensec_state, mem_ctx, in, &out);
/* don't leak 'bad password'/'no such user' info to the network client */
nt_status = auth_nt_status_squash(nt_status);
@@ -462,9 +483,9 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
reply_arg = "*";
if (first) {
reply_code = "YR";
- } else if ((*gensec_state)->gensec_role == GENSEC_CLIENT) {
+ } else if (state->gensec_state->gensec_role == GENSEC_CLIENT) {
reply_code = "KK";
- } else if ((*gensec_state)->gensec_role == GENSEC_SERVER) {
+ } else if (state->gensec_state->gensec_role == GENSEC_SERVER) {
reply_code = "TT";
} else {
abort();
@@ -483,10 +504,10 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
reply_code = "NA";
reply_arg = nt_errstr(nt_status);
DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));
- } else if /* OK */ ((*gensec_state)->gensec_role == GENSEC_SERVER) {
+ } else if /* OK */ (state->gensec_state->gensec_role == GENSEC_SERVER) {
struct auth_session_info *session_info;
- nt_status = gensec_session_info(*gensec_state, &session_info);
+ nt_status = gensec_session_info(state->gensec_state, &session_info);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_code = "BH";
reply_arg = nt_errstr(nt_status);
@@ -494,12 +515,12 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
} else {
reply_code = "AF";
- reply_arg = talloc_asprintf(*gensec_state,
+ reply_arg = talloc_asprintf(state->gensec_state,
"%s%s%s", session_info->server_info->domain_name,
lp_winbind_separator(), session_info->server_info->account_name);
talloc_free(session_info);
}
- } else if ((*gensec_state)->gensec_role == GENSEC_CLIENT) {
+ } else if (state->gensec_state->gensec_role == GENSEC_CLIENT) {
reply_code = "AF";
reply_arg = out_base64;
} else {