Copyright (C) Tim Potter 2000-2003
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004
Copyright (C) Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it> 2000
+ Copyright (C) Robert O'Callahan 2006 (added cached credential code).
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
static DATA_BLOB opt_nt_response;
static int request_lm_key;
static int request_user_session_key;
+static int use_cached_creds;
static const char *require_membership_of;
static const char *require_membership_of_sid;
static char winbind_separator(void)
{
struct winbindd_response response;
- static BOOL got_sep;
+ static bool got_sep;
static char sep;
if (got_sep)
/* Copy of parse_domain_user from winbindd_util.c. Parse a string of the
form DOMAIN/user into a domain and a user */
-static BOOL parse_ntlm_auth_domain_user(const char *domuser, fstring domain,
+static bool parse_ntlm_auth_domain_user(const char *domuser, fstring domain,
fstring user)
{
return True;
}
-static BOOL get_require_membership_sid(void) {
+static bool get_require_membership_sid(void) {
struct winbindd_request request;
struct winbindd_response response;
}
/* Authenticate a user with a plaintext password */
-static BOOL check_plaintext_auth(const char *user, const char *pass,
- BOOL stdout_diagnostics)
+static bool check_plaintext_auth(const char *user, const char *pass,
+ bool stdout_diagnostics)
{
struct winbindd_request request;
struct winbindd_response response;
fstrcpy(request.data.auth.user, user);
fstrcpy(request.data.auth.pass, pass);
- if (require_membership_of_sid)
- fstrcpy(request.data.auth.require_membership_of_sid, require_membership_of_sid);
+ if (require_membership_of_sid) {
+ strlcpy(request.data.auth.require_membership_of_sid,
+ require_membership_of_sid,
+ sizeof(request.data.auth.require_membership_of_sid));
+ }
result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
/* Display response */
-
+
if (stdout_diagnostics) {
if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
d_printf("Reading winbind reply failed! (0x01)\n");
}
-
- d_printf("%s: %s (0x%x)\n",
- response.data.auth.nt_status_string,
- response.data.auth.error_string,
+
+ d_printf("%s: %s (0x%x)\n",
+ response.data.auth.nt_status_string,
+ response.data.auth.error_string,
response.data.auth.nt_status);
} else {
if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {
DEBUG(1, ("Reading winbind reply failed! (0x01)\n"));
}
-
- DEBUG(3, ("%s: %s (0x%x)\n",
- response.data.auth.nt_status_string,
+
+ DEBUG(3, ("%s: %s (0x%x)\n",
+ response.data.auth.nt_status_string,
response.data.auth.error_string,
- response.data.auth.nt_status));
+ response.data.auth.nt_status));
}
-
+
return (result == NSS_STATUS_SUCCESS);
}
/* authenticate a user with an encrypted username/password */
-NTSTATUS contact_winbind_auth_crap(const char *username,
- const char *domain,
+NTSTATUS contact_winbind_auth_crap(const char *username,
+ const char *domain,
const char *workstation,
- const DATA_BLOB *challenge,
- const DATA_BLOB *lm_response,
- const DATA_BLOB *nt_response,
- uint32 flags,
- uint8 lm_key[8],
- uint8 user_session_key[16],
- char **error_string,
- char **unix_name)
+ const DATA_BLOB *challenge,
+ const DATA_BLOB *lm_response,
+ const DATA_BLOB *nt_response,
+ uint32 flags,
+ uint8 lm_key[8],
+ uint8 user_session_key[16],
+ char **error_string,
+ char **unix_name)
{
NTSTATUS nt_status;
NSS_STATUS result;
nt_status = NT_STATUS_UNSUCCESSFUL;
if (error_string)
*error_string = smb_xstrdup("Reading winbind reply failed!");
- free_response(&response);
+ winbindd_free_response(&response);
return nt_status;
}
if (!NT_STATUS_IS_OK(nt_status)) {
if (error_string)
*error_string = smb_xstrdup(response.data.auth.error_string);
- free_response(&response);
+ winbindd_free_response(&response);
return nt_status;
}
if (flags & WBFLAG_PAM_UNIX_NAME) {
*unix_name = SMB_STRDUP((char *)response.extra_data.data);
if (!*unix_name) {
- free_response(&response);
+ winbindd_free_response(&response);
return NT_STATUS_NO_MEMORY;
}
}
- free_response(&response);
+ winbindd_free_response(&response);
return nt_status;
}
nt_status = NT_STATUS_UNSUCCESSFUL;
if (error_string)
*error_string = smb_xstrdup("Reading winbind reply failed!");
- free_response(&response);
+ winbindd_free_response(&response);
return nt_status;
}
{
if (error_string)
*error_string = smb_xstrdup(response.data.auth.error_string);
- free_response(&response);
+ winbindd_free_response(&response);
return nt_status;
}
- free_response(&response);
+ winbindd_free_response(&response);
return nt_status;
}
static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
{
- static const char zeros[16];
+ static const char zeros[16] = { 0, };
NTSTATUS nt_status;
char *error_string;
uint8 lm_key[8];
return status;
}
- status = ntlmssp_set_password(*client_ntlmssp_state, opt_password);
+ if (opt_password) {
+ status = ntlmssp_set_password(*client_ntlmssp_state, opt_password);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not set password: %s\n",
- nt_errstr(status)));
- ntlmssp_end(client_ntlmssp_state);
- return status;
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Could not set password: %s\n",
+ nt_errstr(status)));
+ ntlmssp_end(client_ntlmssp_state);
+ return status;
+ }
}
+
return NT_STATUS_OK;
}
return NT_STATUS_OK;
}
+/*******************************************************************
+ Used by firefox to drive NTLM auth to IIS servers.
+*******************************************************************/
+
+static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_msg,
+ DATA_BLOB *reply)
+{
+ struct winbindd_request wb_request;
+ struct winbindd_response wb_response;
+ NSS_STATUS result;
+
+ /* get winbindd to do the ntlmssp step on our behalf */
+ ZERO_STRUCT(wb_request);
+ ZERO_STRUCT(wb_response);
+
+ fstr_sprintf(wb_request.data.ccache_ntlm_auth.user,
+ "%s%c%s", opt_domain, winbind_separator(), opt_username);
+ wb_request.data.ccache_ntlm_auth.uid = geteuid();
+ wb_request.data.ccache_ntlm_auth.initial_blob_len = initial_msg.length;
+ wb_request.data.ccache_ntlm_auth.challenge_blob_len = challenge_msg.length;
+ wb_request.extra_len = initial_msg.length + challenge_msg.length;
+
+ if (wb_request.extra_len > 0) {
+ wb_request.extra_data.data = SMB_MALLOC_ARRAY(char, wb_request.extra_len);
+ if (wb_request.extra_data.data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ memcpy(wb_request.extra_data.data, initial_msg.data, initial_msg.length);
+ memcpy(wb_request.extra_data.data + initial_msg.length,
+ challenge_msg.data, challenge_msg.length);
+ }
+
+ result = winbindd_request_response(WINBINDD_CCACHE_NTLMAUTH, &wb_request, &wb_response);
+ SAFE_FREE(wb_request.extra_data.data);
+
+ if (result != NSS_STATUS_SUCCESS) {
+ winbindd_free_response(&wb_response);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ if (reply) {
+ *reply = data_blob(wb_response.extra_data.data,
+ wb_response.data.ccache_ntlm_auth.auth_blob_len);
+ if (wb_response.data.ccache_ntlm_auth.auth_blob_len > 0 &&
+ reply->data == NULL) {
+ winbindd_free_response(&wb_response);
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ winbindd_free_response(&wb_response);
+ return NT_STATUS_MORE_PROCESSING_REQUIRED;
+}
+
static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode,
char *buf, int length)
{
static NTLMSSP_STATE *ntlmssp_state = NULL;
+ static char* want_feature_list = NULL;
+ static uint32 neg_flags = 0;
+ static bool have_session_key = False;
+ static DATA_BLOB session_key;
DATA_BLOB request, reply;
NTSTATUS nt_status;
}
if (strlen(buf) > 3) {
+ if(strncmp(buf, "SF ", 3) == 0){
+ DEBUG(10, ("Setting flags to negotioate\n"));
+ SAFE_FREE(want_feature_list);
+ want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3);
+ x_fprintf(x_stdout, "OK\n");
+ return;
+ }
request = base64_decode_data_blob(buf + 3);
} else {
- request = data_blob(NULL, 0);
+ request = data_blob_null;
}
if ((strncmp(buf, "PW ", 3) == 0)) {
ntlmssp_end(&ntlmssp_state);
} else if (strncmp(buf, "KK", 2) == 0) {
+ } else if (strncmp(buf, "GF", 2) == 0) {
+ DEBUG(10, ("Requested negotiated NTLMSSP flags\n"));
+ x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l);
+ data_blob_free(&request);
+ return;
+ } else if (strncmp(buf, "GK", 2) == 0) {
+ DEBUG(10, ("Requested NTLMSSP session key\n"));
+ if(have_session_key) {
+ char *key64 = base64_encode_data_blob(talloc_tos(),
+ session_key);
+ x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>");
+ TALLOC_FREE(key64);
+ } else {
+ x_fprintf(x_stdout, "BH\n");
+ }
+
+ data_blob_free(&request);
+ return;
} else {
DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
x_fprintf(x_stdout, "BH\n");
x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
return;
}
+ ntlmssp_want_feature_list(ntlmssp_state, want_feature_list);
}
DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, (const char *)request.data, request.length);
+ dump_data(10, request.data, request.length);
nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- char *reply_base64 = base64_encode_data_blob(reply);
+ char *reply_base64 = base64_encode_data_blob(talloc_tos(),
+ reply);
x_fprintf(x_stdout, "TT %s\n", reply_base64);
- SAFE_FREE(reply_base64);
+ TALLOC_FREE(reply_base64);
data_blob_free(&reply);
DEBUG(10, ("NTLMSSP challenge\n"));
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {
} else {
x_fprintf(x_stdout, "AF %s\n", (char *)ntlmssp_state->auth_context);
DEBUG(10, ("NTLMSSP OK!\n"));
+
+ if(have_session_key)
+ data_blob_free(&session_key);
+ session_key = data_blob(ntlmssp_state->session_key.data,
+ ntlmssp_state->session_key.length);
+ neg_flags = ntlmssp_state->neg_flags;
+ have_session_key = True;
}
data_blob_free(&request);
static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode,
char *buf, int length)
{
+ /* The statics here are *HORRIBLE* and this entire concept
+ needs to be rewritten. Essentially it's using these statics
+ as the state in a state machine. BLEEEGH ! JRA. */
+
static NTLMSSP_STATE *ntlmssp_state = NULL;
+ static DATA_BLOB initial_message;
+ static char* want_feature_list = NULL;
+ static uint32 neg_flags = 0;
+ static bool have_session_key = False;
+ static DATA_BLOB session_key;
DATA_BLOB request, reply;
NTSTATUS nt_status;
- BOOL first = False;
+ bool first = False;
+ if (!opt_username || !*opt_username) {
+ x_fprintf(x_stderr, "username must be specified!\n\n");
+ exit(1);
+ }
+
if (strlen(buf) < 2) {
DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
x_fprintf(x_stdout, "BH\n");
}
if (strlen(buf) > 3) {
+ if(strncmp(buf, "SF ", 3) == 0) {
+ DEBUG(10, ("Looking for flags to negotiate\n"));
+ SAFE_FREE(want_feature_list);
+ want_feature_list = SMB_STRNDUP(buf+3, strlen(buf)-3);
+ x_fprintf(x_stdout, "OK\n");
+ return;
+ }
request = base64_decode_data_blob(buf + 3);
} else {
- request = data_blob(NULL, 0);
+ request = data_blob_null;
}
if (strncmp(buf, "PW ", 3) == 0) {
return;
}
- if (opt_password == NULL) {
+ if (!ntlmssp_state && use_cached_creds) {
+ /* check whether credentials are usable. */
+ DATA_BLOB empty_blob = data_blob_null;
+
+ nt_status = do_ccache_ntlm_auth(empty_blob, empty_blob, NULL);
+ if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ /* failed to use cached creds */
+ use_cached_creds = False;
+ }
+ }
+
+ if (opt_password == NULL && !use_cached_creds) {
/* Request a password from the calling process. After
sending it, the calling process should retry asking for the negotiate. */
ntlmssp_end(&ntlmssp_state);
} else if (strncmp(buf, "TT", 2) == 0) {
+ } else if (strncmp(buf, "GF", 2) == 0) {
+ DEBUG(10, ("Requested negotiated NTLMSSP flags\n"));
+ x_fprintf(x_stdout, "GF 0x%08lx\n", have_session_key?neg_flags:0l);
+ data_blob_free(&request);
+ return;
+ } else if (strncmp(buf, "GK", 2) == 0 ) {
+ DEBUG(10, ("Requested session key\n"));
+
+ if(have_session_key) {
+ char *key64 = base64_encode_data_blob(talloc_tos(),
+ session_key);
+ x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>");
+ TALLOC_FREE(key64);
+ }
+ else {
+ x_fprintf(x_stdout, "BH\n");
+ }
+
+ data_blob_free(&request);
+ return;
} else {
DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
x_fprintf(x_stdout, "BH\n");
x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
return;
}
+ ntlmssp_want_feature_list(ntlmssp_state, want_feature_list);
first = True;
+ initial_message = data_blob_null;
}
DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, (const char *)request.data, request.length);
+ dump_data(10, request.data, request.length);
- nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
+ if (use_cached_creds && !opt_password && !first) {
+ nt_status = do_ccache_ntlm_auth(initial_message, request, &reply);
+ } else {
+ nt_status = ntlmssp_update(ntlmssp_state, request, &reply);
+ }
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- char *reply_base64 = base64_encode_data_blob(reply);
+ char *reply_base64 = base64_encode_data_blob(talloc_tos(),
+ reply);
if (first) {
x_fprintf(x_stdout, "YR %s\n", reply_base64);
} else {
x_fprintf(x_stdout, "KK %s\n", reply_base64);
}
- SAFE_FREE(reply_base64);
- data_blob_free(&reply);
+ TALLOC_FREE(reply_base64);
+ if (first) {
+ initial_message = reply;
+ } else {
+ data_blob_free(&reply);
+ }
DEBUG(10, ("NTLMSSP challenge\n"));
} else if (NT_STATUS_IS_OK(nt_status)) {
- char *reply_base64 = base64_encode_data_blob(reply);
+ char *reply_base64 = base64_encode_data_blob(talloc_tos(),
+ reply);
x_fprintf(x_stdout, "AF %s\n", reply_base64);
- SAFE_FREE(reply_base64);
+ TALLOC_FREE(reply_base64);
+
+ if(have_session_key)
+ data_blob_free(&session_key);
+
+ session_key = data_blob(ntlmssp_state->session_key.data,
+ ntlmssp_state->session_key.length);
+ neg_flags = ntlmssp_state->neg_flags;
+ have_session_key = True;
+
DEBUG(10, ("NTLMSSP OK!\n"));
if (ntlmssp_state)
ntlmssp_end(&ntlmssp_state);
char *user, *pass;
user=buf;
- pass=memchr(buf,' ',length);
+ pass=(char *)memchr(buf,' ',length);
if (!pass) {
DEBUG(2, ("Password not found. Denying access\n"));
x_fprintf(x_stdout, "ERR\n");
SPNEGO_DATA spnego;
ssize_t len;
char *reply_base64;
-
- pstring principal;
- pstring myname_lower;
+ TALLOC_CTX *ctx = talloc_tos();
+ char *principal;
+ char *myname_lower;
ZERO_STRUCT(spnego);
- pstrcpy(myname_lower, global_myname());
+ myname_lower = talloc_strdup(ctx, global_myname());
+ if (!myname_lower) {
+ return;
+ }
strlower_m(myname_lower);
- pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm());
+ principal = talloc_asprintf(ctx, "%s$@%s", myname_lower, lp_realm());
+ if (!principal) {
+ return;
+ }
/* Server negTokenInit (mech offerings) */
spnego.type = SPNEGO_NEG_TOKEN_INIT;
return;
}
- reply_base64 = base64_encode_data_blob(token);
+ reply_base64 = base64_encode_data_blob(talloc_tos(), token);
x_fprintf(x_stdout, "TT %s *\n", reply_base64);
- SAFE_FREE(reply_base64);
+ TALLOC_FREE(reply_base64);
data_blob_free(&token);
DEBUG(10, ("sent SPNEGO negTokenInit\n"));
return;
DATA_BLOB token;
NTSTATUS status;
ssize_t len;
+ TALLOC_CTX *ctx = talloc_tos();
char *user = NULL;
char *domain = NULL;
const char *reply_code;
char *reply_base64;
- pstring reply_argument;
+ char *reply_argument = NULL;
if (strlen(buf) < 2) {
DEBUG(1, ("SPENGO query [%s] invalid", buf));
if (ntlmssp_state)
ntlmssp_end(&ntlmssp_state);
} else if (strncmp(buf, "KK", 2) == 0) {
-
+ ;
} else {
DEBUG(1, ("SPENGO query [%s] invalid", buf));
x_fprintf(x_stdout, "BH\n");
}
DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, (const char *)request.negTokenInit.mechToken.data,
+ dump_data(10, request.negTokenInit.mechToken.data,
request.negTokenInit.mechToken.length);
response.type = SPNEGO_NEG_TOKEN_TARG;
response.negTokenTarg.supportedMech = SMB_STRDUP(OID_NTLMSSP);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+ response.negTokenTarg.mechListMIC = data_blob_null;
status = ntlmssp_update(ntlmssp_state,
request.negTokenInit.mechToken,
char *principal;
DATA_BLOB ap_rep;
DATA_BLOB session_key;
+ PAC_DATA *pac_data = NULL;
if ( request.negTokenInit.mechToken.data == NULL ) {
DEBUG(1, ("Client did not provide Kerberos data\n"));
response.type = SPNEGO_NEG_TOKEN_TARG;
response.negTokenTarg.supportedMech = SMB_STRDUP(OID_KERBEROS5_OLD);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
- response.negTokenTarg.responseToken = data_blob(NULL, 0);
+ response.negTokenTarg.mechListMIC = data_blob_null;
+ response.negTokenTarg.responseToken = data_blob_null;
status = ads_verify_ticket(mem_ctx, lp_realm(), 0,
&request.negTokenInit.mechToken,
- &principal, NULL, &ap_rep,
- &session_key);
+ &principal, &pac_data, &ap_rep,
+ &session_key, True);
talloc_destroy(mem_ctx);
response.type = SPNEGO_NEG_TOKEN_TARG;
response.negTokenTarg.supportedMech = SMB_STRDUP(OID_NTLMSSP);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
+ response.negTokenTarg.mechListMIC = data_blob_null;
if (NT_STATUS_IS_OK(status)) {
user = SMB_STRDUP(ntlmssp_state->user);
if (NT_STATUS_IS_OK(status)) {
response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
reply_code = "AF";
- pstr_sprintf(reply_argument, "%s\\%s", domain, user);
+ reply_argument = talloc_asprintf(ctx, "%s\\%s", domain, user);
} else if (NT_STATUS_EQUAL(status,
NT_STATUS_MORE_PROCESSING_REQUIRED)) {
response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
reply_code = "TT";
- pstr_sprintf(reply_argument, "*");
+ reply_argument = talloc_strdup(ctx, "*");
} else {
response.negTokenTarg.negResult = SPNEGO_REJECT;
reply_code = "NA";
- pstrcpy(reply_argument, nt_errstr(status));
+ reply_argument = talloc_strdup(ctx, nt_errstr(status));
+ }
+
+ if (!reply_argument) {
+ DEBUG(1, ("Could not write SPNEGO data blob\n"));
+ x_fprintf(x_stdout, "BH\n");
+ return;
}
SAFE_FREE(user);
return;
}
- reply_base64 = base64_encode_data_blob(token);
+ reply_base64 = base64_encode_data_blob(talloc_tos(), token);
x_fprintf(x_stdout, "%s %s %s\n",
reply_code, reply_base64, reply_argument);
- SAFE_FREE(reply_base64);
+ TALLOC_FREE(reply_base64);
data_blob_free(&token);
return;
static NTLMSSP_STATE *client_ntlmssp_state = NULL;
-static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego)
+static bool manage_client_ntlmssp_init(SPNEGO_DATA spnego)
{
NTSTATUS status;
- DATA_BLOB null_blob = data_blob(NULL, 0);
+ DATA_BLOB null_blob = data_blob_null;
DATA_BLOB to_server;
char *to_server_base64;
const char *my_mechs[] = {OID_NTLMSSP, NULL};
write_spnego_data(&to_server, &spnego);
data_blob_free(&spnego.negTokenInit.mechToken);
- to_server_base64 = base64_encode_data_blob(to_server);
+ to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server);
data_blob_free(&to_server);
x_fprintf(x_stdout, "KK %s\n", to_server_base64);
- SAFE_FREE(to_server_base64);
+ TALLOC_FREE(to_server_base64);
return True;
}
static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego)
{
NTSTATUS status;
- DATA_BLOB null_blob = data_blob(NULL, 0);
+ DATA_BLOB null_blob = data_blob_null;
DATA_BLOB request;
DATA_BLOB to_server;
char *to_server_base64;
if (client_ntlmssp_state == NULL) {
DEBUG(1, ("Got NTLMSSP tArg without a client state\n"));
x_fprintf(x_stdout, "BH\n");
- ntlmssp_end(&client_ntlmssp_state);
return;
}
write_spnego_data(&to_server, &spnego);
data_blob_free(&request);
- to_server_base64 = base64_encode_data_blob(to_server);
+ to_server_base64 = base64_encode_data_blob(talloc_tos(), to_server);
data_blob_free(&to_server);
x_fprintf(x_stdout, "KK %s\n", to_server_base64);
- SAFE_FREE(to_server_base64);
+ TALLOC_FREE(to_server_base64);
return;
}
#ifdef HAVE_KRB5
-static BOOL manage_client_krb5_init(SPNEGO_DATA spnego)
+static bool manage_client_krb5_init(SPNEGO_DATA spnego)
{
char *principal;
DATA_BLOB tkt, to_server;
- DATA_BLOB session_key_krb5 = data_blob(NULL, 0);
+ DATA_BLOB session_key_krb5 = data_blob_null;
SPNEGO_DATA reply;
char *reply_base64;
int retval;
-
+
const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
ssize_t len;
return False;
}
- principal = SMB_MALLOC(spnego.negTokenInit.mechListMIC.length+1);
+ principal = (char *)SMB_MALLOC(
+ spnego.negTokenInit.mechListMIC.length+1);
if (principal == NULL) {
DEBUG(1, ("Could not malloc principal\n"));
spnego.negTokenInit.mechListMIC.length);
principal[spnego.negTokenInit.mechListMIC.length] = '\0';
- retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL);
+ retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL);
if (retval) {
-
- pstring user;
+ char *user = NULL;
/* Let's try to first get the TGT, for that we need a
password. */
return True;
}
- pstr_sprintf(user, "%s@%s", opt_username, opt_domain);
+ user = talloc_asprintf(talloc_tos(), "%s@%s", opt_username, opt_domain);
+ if (!user) {
+ return false;
+ }
if ((retval = kerberos_kinit_password(user, opt_password, 0, NULL))) {
DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval)));
return False;
}
- retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL);
+ retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL);
if (retval) {
DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval)));
reply.negTokenInit.mechTypes = my_mechs;
reply.negTokenInit.reqFlags = 0;
reply.negTokenInit.mechToken = tkt;
- reply.negTokenInit.mechListMIC = data_blob(NULL, 0);
+ reply.negTokenInit.mechListMIC = data_blob_null;
len = write_spnego_data(&to_server, &reply);
data_blob_free(&tkt);
return False;
}
- reply_base64 = base64_encode_data_blob(to_server);
+ reply_base64 = base64_encode_data_blob(talloc_tos(), to_server);
x_fprintf(x_stdout, "KK %s *\n", reply_base64);
- SAFE_FREE(reply_base64);
+ TALLOC_FREE(reply_base64);
data_blob_free(&to_server);
DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n"));
return True;
SPNEGO_DATA spnego;
ssize_t len;
+ if (!opt_username || !*opt_username) {
+ x_fprintf(x_stderr, "username must be specified!\n\n");
+ exit(1);
+ }
+
if (strlen(buf) <= 3) {
DEBUG(1, ("SPNEGO query [%s] too short\n", buf));
x_fprintf(x_stdout, "BH\n");
static char *username;
static char *domain;
static char *plaintext_password;
- static BOOL ntlm_server_1_user_session_key;
- static BOOL ntlm_server_1_lm_session_key;
+ static bool ntlm_server_1_user_session_key;
+ static bool ntlm_server_1_lm_session_key;
if (strequal(buf, ".")) {
if (!full_username && !username) {
}
}
/* clear out the state */
- challenge = data_blob(NULL, 0);
- nt_response = data_blob(NULL, 0);
- lm_response = data_blob(NULL, 0);
+ challenge = data_blob_null;
+ nt_response = data_blob_null;
+ lm_response = data_blob_null;
SAFE_FREE(full_username);
SAFE_FREE(username);
SAFE_FREE(domain);
x_fprintf(x_stdout, "Error: hex decode of %s failed! (got %d bytes, expected 8)\n.\n",
parameter,
(int)challenge.length);
- challenge = data_blob(NULL, 0);
+ challenge = data_blob_null;
}
} else if (strequal(request, "NT-Response")) {
nt_response = strhex_to_data_blob(NULL, parameter);
x_fprintf(x_stdout, "Error: hex decode of %s failed! (only got %d bytes, needed at least 24)\n.\n",
parameter,
(int)nt_response.length);
- nt_response = data_blob(NULL, 0);
+ nt_response = data_blob_null;
}
} else if (strequal(request, "LANMAN-Response")) {
lm_response = strhex_to_data_blob(NULL, parameter);
x_fprintf(x_stdout, "Error: hex decode of %s failed! (got %d bytes, expected 24)\n.\n",
parameter,
(int)lm_response.length);
- lm_response = data_blob(NULL, 0);
+ lm_response = data_blob_null;
}
} else if (strequal(request, "Password")) {
plaintext_password = smb_xstrdup(parameter);
SAFE_FREE(error_string);
}
/* clear out the state */
- new_nt_pswd = data_blob(NULL, 0);
- old_nt_hash_enc = data_blob(NULL, 0);
- new_lm_pswd = data_blob(NULL, 0);
- old_nt_hash_enc = data_blob(NULL, 0);
+ new_nt_pswd = data_blob_null;
+ old_nt_hash_enc = data_blob_null;
+ new_lm_pswd = data_blob_null;
+ old_nt_hash_enc = data_blob_null;
SAFE_FREE(full_username);
SAFE_FREE(username);
SAFE_FREE(domain);
"(got %d bytes, expected 516)\n.\n",
parameter,
(int)new_nt_pswd.length);
- new_nt_pswd = data_blob(NULL, 0);
+ new_nt_pswd = data_blob_null;
}
} else if (strequal(request, "old-nt-hash-blob")) {
old_nt_hash_enc = strhex_to_data_blob(NULL, parameter);
"(got %d bytes, expected 16)\n.\n",
parameter,
(int)old_nt_hash_enc.length);
- old_nt_hash_enc = data_blob(NULL, 0);
+ old_nt_hash_enc = data_blob_null;
}
} else if (strequal(request, "new-lm-password-blob")) {
new_lm_pswd = strhex_to_data_blob(NULL, parameter);
"(got %d bytes, expected 516)\n.\n",
parameter,
(int)new_lm_pswd.length);
- new_lm_pswd = data_blob(NULL, 0);
+ new_lm_pswd = data_blob_null;
}
}
else if (strequal(request, "old-lm-hash-blob")) {
"(got %d bytes, expected 16)\n.\n",
parameter,
(int)old_lm_hash_enc.length);
- old_lm_hash_enc = data_blob(NULL, 0);
+ old_lm_hash_enc = data_blob_null;
}
} else if (strequal(request, "nt-domain")) {
domain = smb_xstrdup(parameter);
char buf[SQUID_BUFFER_SIZE+1];
int length;
char *c;
- static BOOL err;
+ static bool err;
/* this is not a typo - x_fgets doesn't work too well under squid */
if (fgets(buf, sizeof(buf)-1, stdin) == NULL) {
exit(0);
}
- c=memchr(buf,'\n',sizeof(buf)-1);
+ c=(char *)memchr(buf,'\n',sizeof(buf)-1);
if (c) {
*c = '\0';
length = c-buf;
/* Authenticate a user with a challenge/response */
-static BOOL check_auth_crap(void)
+static bool check_auth_crap(void)
{
NTSTATUS nt_status;
uint32 flags = 0;
OPT_LM_KEY,
OPT_USER_SESSION_KEY,
OPT_DIAGNOSTICS,
- OPT_REQUIRE_MEMBERSHIP
+ OPT_REQUIRE_MEMBERSHIP,
+ OPT_USE_CACHED_CREDS
};
int main(int argc, const char **argv)
{
+ TALLOC_CTX *frame = talloc_stackframe();
int opt;
static const char *helper_protocol;
static int diagnostics;
{ "password", 0, POPT_ARG_STRING, &opt_password, OPT_PASSWORD, "User's plaintext password"},
{ "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retrieve LM session key"},
{ "request-nt-key", 0, POPT_ARG_NONE, &request_user_session_key, OPT_USER_SESSION_KEY, "Retrieve User (NT) session key"},
+ { "use-cached-creds", 0, POPT_ARG_NONE, &use_cached_creds, OPT_USE_CACHED_CREDS, "Use cached credentials if no password is given"},
{ "diagnostics", 0, POPT_ARG_NONE, &diagnostics, OPT_DIAGNOSTICS, "Perform diagnostics on the authentictaion chain"},
{ "require-membership-of", 0, POPT_ARG_STRING, &require_membership_of, OPT_REQUIRE_MEMBERSHIP, "Require that a user be a member of this group (either name or SID) for authentication to succeed" },
POPT_COMMON_SAMBA
/* Samba client initialisation */
- if (!lp_load(dyn_CONFIGFILE, True, False, False, True)) {
+ if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, True)) {
d_fprintf(stderr, "ntlm_auth: error opening config file %s. Error was %s\n",
- dyn_CONFIGFILE, strerror(errno));
+ get_dyn_CONFIGFILE(), strerror(errno));
exit(1);
}
}
}
+ if (opt_username) {
+ char *domain = SMB_STRDUP(opt_username);
+ char *p = strchr_m(domain, *lp_winbind_separator());
+ if (p) {
+ opt_username = p+1;
+ *p = '\0';
+ if (opt_domain && !strequal(opt_domain, domain)) {
+ x_fprintf(x_stderr, "Domain specified in username (%s) "
+ "doesn't match specified domain (%s)!\n\n",
+ domain, opt_domain);
+ poptPrintHelp(pc, stderr, 0);
+ exit(1);
+ }
+ opt_domain = domain;
+ } else {
+ SAFE_FREE(domain);
+ }
+ }
+
+ /* Note: if opt_domain is "" then send no domain */
+ if (opt_domain == NULL) {
+ opt_domain = get_winbind_domain();
+ }
+
+ if (opt_workstation == NULL) {
+ opt_workstation = "";
+ }
+
if (helper_protocol) {
int i;
for (i=0; i<NUM_HELPER_MODES; i++) {
exit(1);
}
- if (!opt_username) {
+ if (!opt_username || !*opt_username) {
x_fprintf(x_stderr, "username must be specified!\n\n");
poptPrintHelp(pc, stderr, 0);
exit(1);
}
- if (opt_domain == NULL) {
- opt_domain = get_winbind_domain();
- }
-
- if (opt_workstation == NULL) {
- opt_workstation = "";
- }
-
if (opt_challenge.length) {
if (!check_auth_crap()) {
exit(1);
/* Exit code */
poptFreeContext(pc);
+ TALLOC_FREE(frame);
return 0;
}