1
0
mirror of https://github.com/samba-team/samba.git synced 2025-11-07 12:23:51 +03:00

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 commit is contained in:
Andrew Bartlett
2005-08-30 01:19:41 +00:00
committed by Gerald (Jerry) Carter
parent 505c9b1d3d
commit 04af95bd31
4 changed files with 168 additions and 76 deletions

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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];

View File

@@ -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;
}
}
if (strncmp(buf, "PW ", 3) == 0) {
cli_credentials_set_password((*gensec_state)->credentials,
talloc_strndup((*gensec_state),
(const char *)in.data,
in.length),
CRED_SPECIFIED);
mux_printf(mux_id, "OK\n");
data_blob_free(&in);
return;
}
/* update */
mem_ctx = talloc_named(NULL, 0, "manage_gensec_request internal mem_ctx");
if (strncmp(buf, "PW ", 3) == 0) {
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;
}
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 {