summaryrefslogtreecommitdiff
path: root/source4/utils/ntlm_auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/utils/ntlm_auth.c')
-rw-r--r--source4/utils/ntlm_auth.c832
1 files changed, 70 insertions, 762 deletions
diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c
index d70b0b5d2b..7690a549f7 100644
--- a/source4/utils/ntlm_auth.c
+++ b/source4/utils/ntlm_auth.c
@@ -34,7 +34,6 @@ enum stdio_helper_mode {
SQUID_2_5_BASIC,
SQUID_2_5_NTLMSSP,
NTLMSSP_CLIENT_1,
- GSS_SPNEGO,
GSS_SPNEGO_CLIENT,
NTLM_SERVER_1,
NUM_HELPER_MODES
@@ -53,14 +52,8 @@ static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode
static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode,
char *buf, int length);
-static void manage_client_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
-
-static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
-
-static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length);
+static void manage_gensec_client_request (enum stdio_helper_mode stdio_helper_mode,
+ char *buf, int length);
static void manage_ntlm_server_1_request (enum stdio_helper_mode stdio_helper_mode,
char *buf, int length);
@@ -73,9 +66,8 @@ static const struct {
{ SQUID_2_4_BASIC, "squid-2.4-basic", manage_squid_basic_request},
{ SQUID_2_5_BASIC, "squid-2.5-basic", manage_squid_basic_request},
{ SQUID_2_5_NTLMSSP, "squid-2.5-ntlmssp", manage_squid_ntlmssp_request},
- { NTLMSSP_CLIENT_1, "ntlmssp-client-1", manage_client_ntlmssp_request},
- { GSS_SPNEGO, "gss-spnego", manage_gss_spnego_request},
- { GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gss_spnego_client_request},
+ { NTLMSSP_CLIENT_1, "ntlmssp-client-1", manage_gensec_client_request},
+ { GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gensec_client_request},
{ NTLM_SERVER_1, "ntlm-server-1", manage_ntlm_server_1_request},
{ NUM_HELPER_MODES, NULL, NULL}
};
@@ -218,52 +210,6 @@ static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *u
return nt_status;
}
-static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntlmssp_state)
-{
- NTSTATUS status;
- if ( (opt_username == NULL) || (opt_domain == NULL) ) {
- DEBUG(1, ("Need username and domain for NTLMSSP\n"));
- return status;
- }
-
- status = ntlmssp_client_start(client_ntlmssp_state);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not start NTLMSSP client: %s\n",
- nt_errstr(status)));
- ntlmssp_end(client_ntlmssp_state);
- return status;
- }
-
- status = ntlmssp_set_username(*client_ntlmssp_state, opt_username);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not set username: %s\n",
- nt_errstr(status)));
- ntlmssp_end(client_ntlmssp_state);
- return status;
- }
-
- status = ntlmssp_set_domain(*client_ntlmssp_state, opt_domain);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Could not set domain: %s\n",
- nt_errstr(status)));
- ntlmssp_end(client_ntlmssp_state);
- return status;
- }
-
- 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;
- }
- return NT_STATUS_OK;
-}
-
static NTSTATUS ntlm_auth_start_ntlmssp_server(struct ntlmssp_state **ntlmssp_state)
{
NTSTATUS status = ntlmssp_server_start(ntlmssp_state);
@@ -367,102 +313,6 @@ static void manage_squid_ntlmssp_request(enum stdio_helper_mode stdio_helper_mod
data_blob_free(&request);
}
-static void manage_client_ntlmssp_request(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length)
-{
- static struct ntlmssp_state *ntlmssp_state = NULL;
- DATA_BLOB request, reply;
- NTSTATUS nt_status;
- BOOL first = False;
-
- if (strlen(buf) < 2) {
- DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (strlen(buf) > 3) {
- request = base64_decode_data_blob(buf + 3);
- } else {
- request = data_blob(NULL, 0);
- }
-
- if (strncmp(buf, "PW ", 3) == 0) {
- /* We asked for a password and obviously got it :-) */
-
- opt_password = strndup((const char *)request.data, request.length);
-
- if (opt_password == NULL) {
- DEBUG(1, ("Out of memory\n"));
- x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
- return;
- }
-
- x_fprintf(x_stdout, "OK\n");
- data_blob_free(&request);
- return;
- }
-
- if (opt_password == NULL) {
-
- /* Request a password from the calling process. After
- sending it, the calling process should retry asking for the negotiate. */
-
- DEBUG(10, ("Requesting password\n"));
- x_fprintf(x_stdout, "PW\n");
- return;
- }
-
- if (strncmp(buf, "YR", 2) == 0) {
- if (ntlmssp_state)
- ntlmssp_end(&ntlmssp_state);
- } else if (strncmp(buf, "TT", 2) == 0) {
-
- } else {
- DEBUG(1, ("NTLMSSP query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (!ntlmssp_state) {
- if (!NT_STATUS_IS_OK(nt_status = ntlm_auth_start_ntlmssp_client(&ntlmssp_state))) {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
- return;
- }
- first = True;
- }
-
- DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, (const char *)request.data, request.length);
-
- nt_status = ntlmssp_update(ntlmssp_state, NULL, request, &reply);
-
- if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- char *reply_base64 = base64_encode_data_blob(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);
- DEBUG(10, ("NTLMSSP challenge\n"));
- } else if (NT_STATUS_IS_OK(nt_status)) {
- x_fprintf(x_stdout, "AF\n");
- DEBUG(10, ("NTLMSSP OK!\n"));
- if (ntlmssp_state)
- ntlmssp_end(&ntlmssp_state);
- } else {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
- DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
- if (ntlmssp_state)
- ntlmssp_end(&ntlmssp_state);
- }
-
- data_blob_free(&request);
-}
-
static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode,
char *buf, int length)
{
@@ -490,654 +340,111 @@ static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode,
}
}
-static void offer_gss_spnego_mechs(void) {
-
- DATA_BLOB token;
- struct spnego_data spnego;
- ssize_t len;
- char *reply_base64;
-
- pstring principal;
- pstring myname_lower;
-
- ZERO_STRUCT(spnego);
-
- pstrcpy(myname_lower, global_myname());
- strlower_m(myname_lower);
-
- pstr_sprintf(principal, "%s$@%s", myname_lower, lp_realm());
-
- /* Server negTokenInit (mech offerings) */
- spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = smb_xmalloc(sizeof(char *) * 3);
-#ifdef HAVE_KRB5
- spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_KERBEROS5_OLD);
- spnego.negTokenInit.mechTypes[1] = smb_xstrdup(OID_NTLMSSP);
- spnego.negTokenInit.mechTypes[2] = NULL;
-#else
- spnego.negTokenInit.mechTypes[0] = smb_xstrdup(OID_NTLMSSP);
- spnego.negTokenInit.mechTypes[1] = NULL;
-#endif
-
-
- spnego.negTokenInit.mechListMIC = data_blob(principal,
- strlen(principal));
-
- len = write_spnego_data(&token, &spnego);
- free_spnego_data(&spnego);
-
- if (len == -1) {
- DEBUG(1, ("Could not write SPNEGO data blob\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- reply_base64 = base64_encode_data_blob(token);
- x_fprintf(x_stdout, "TT %s *\n", reply_base64);
-
- SAFE_FREE(reply_base64);
- data_blob_free(&token);
- DEBUG(10, ("sent SPNEGO negTokenInit\n"));
- return;
-}
-
-static void manage_gss_spnego_request(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length)
+static void manage_gensec_client_request(enum stdio_helper_mode stdio_helper_mode,
+ char *buf, int length)
{
- static struct ntlmssp_state *ntlmssp_state = NULL;
- struct spnego_data request, response;
- DATA_BLOB token;
- NTSTATUS status;
- ssize_t len;
-
- char *user = NULL;
- char *domain = NULL;
-
- const char *reply_code;
- char *reply_base64;
- pstring reply_argument;
+ DATA_BLOB in;
+ DATA_BLOB out;
+ char *out_base64;
+ static struct gensec_security gensec_state;
+ NTSTATUS nt_status;
+ BOOL first = False;
if (strlen(buf) < 2) {
- DEBUG(1, ("SPENGO query [%s] invalid", buf));
+ DEBUG(1, ("query [%s] invalid", buf));
x_fprintf(x_stdout, "BH\n");
return;
}
- if (strncmp(buf, "YR", 2) == 0) {
- 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");
- return;
- }
-
- if ( (strlen(buf) == 2)) {
-
- /* no client data, get the negTokenInit offering
- mechanisms */
-
- offer_gss_spnego_mechs();
- return;
- }
-
- /* All subsequent requests have a blob. This might be negTokenInit or negTokenTarg */
-
- if (strlen(buf) <= 3) {
- DEBUG(1, ("GSS-SPNEGO query [%s] invalid\n", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- token = base64_decode_data_blob(buf + 3);
- len = read_spnego_data(token, &request);
- data_blob_free(&token);
-
- if (len == -1) {
- DEBUG(1, ("GSS-SPNEGO query [%s] invalid", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (request.type == SPNEGO_NEG_TOKEN_INIT) {
-
- /* Second request from Client. This is where the
- client offers its mechanism to use. */
-
- if ( (request.negTokenInit.mechTypes == NULL) ||
- (request.negTokenInit.mechTypes[0] == NULL) ) {
- DEBUG(1, ("Client did not offer any mechanism"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (strcmp(request.negTokenInit.mechTypes[0], OID_NTLMSSP) == 0) {
-
- if ( request.negTokenInit.mechToken.data == NULL ) {
- DEBUG(1, ("Client did not provide NTLMSSP data\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if ( ntlmssp_state != NULL ) {
- DEBUG(1, ("Client wants a new NTLMSSP challenge, but "
- "already got one\n"));
- x_fprintf(x_stdout, "BH\n");
- ntlmssp_end(&ntlmssp_state);
- return;
- }
-
- if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_server(&ntlmssp_state))) {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(status));
- return;
- }
-
- DEBUG(10, ("got NTLMSSP packet:\n"));
- dump_data(10, (const char *)request.negTokenInit.mechToken.data,
- request.negTokenInit.mechToken.length);
-
- response.type = SPNEGO_NEG_TOKEN_TARG;
- response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
-
- status = ntlmssp_update(ntlmssp_state,
- NULL,
- request.negTokenInit.mechToken,
- &response.negTokenTarg.responseToken);
- }
-
-#ifdef HAVE_KRB5
- if (strcmp(request.negTokenInit.mechTypes[0], OID_KERBEROS5_OLD) == 0) {
-
- char *principal;
- DATA_BLOB auth_data;
- DATA_BLOB ap_rep;
- DATA_BLOB session_key;
-
- if ( request.negTokenInit.mechToken.data == NULL ) {
- DEBUG(1, ("Client did not provide Kerberos data\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- response.type = SPNEGO_NEG_TOKEN_TARG;
- response.negTokenTarg.supportedMech = strdup(OID_KERBEROS5_OLD);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
- response.negTokenTarg.responseToken = data_blob(NULL, 0);
-
- status = ads_verify_ticket(lp_realm(),
- &request.negTokenInit.mechToken,
- &principal, &auth_data, &ap_rep,
- &session_key);
-
- /* Now in "principal" we have the name we are
- authenticated as. */
-
- if (NT_STATUS_IS_OK(status)) {
-
- domain = strchr(principal, '@');
-
- if (domain == NULL) {
- DEBUG(1, ("Did not get a valid principal "
- "from ads_verify_ticket\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- *domain++ = '\0';
- domain = strdup(domain);
- user = strdup(principal);
-
- data_blob_free(&ap_rep);
- data_blob_free(&auth_data);
-
- SAFE_FREE(principal);
- }
- }
-#endif
-
- } else {
-
- if ( (request.negTokenTarg.supportedMech == NULL) ||
- ( strcmp(request.negTokenTarg.supportedMech, OID_NTLMSSP) != 0 ) ) {
- /* Kerberos should never send a negTokenTarg, OID_NTLMSSP
- is the only one we support that sends this stuff */
- DEBUG(1, ("Got a negTokenTarg for something non-NTLMSSP: %s\n",
- request.negTokenTarg.supportedMech));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- if (request.negTokenTarg.responseToken.data == NULL) {
- DEBUG(1, ("Got a negTokenTarg without a responseToken!\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- status = ntlmssp_update(ntlmssp_state,
- NULL,
- request.negTokenTarg.responseToken,
- &response.negTokenTarg.responseToken);
-
- response.type = SPNEGO_NEG_TOKEN_TARG;
- response.negTokenTarg.supportedMech = strdup(OID_NTLMSSP);
- response.negTokenTarg.mechListMIC = data_blob(NULL, 0);
-
- if (NT_STATUS_IS_OK(status)) {
- user = strdup(ntlmssp_state->user);
- domain = strdup(ntlmssp_state->domain);
- ntlmssp_end(&ntlmssp_state);
- }
- }
-
- free_spnego_data(&request);
-
- if (NT_STATUS_IS_OK(status)) {
- response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;
- reply_code = "AF";
- pstr_sprintf(reply_argument, "%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, "*");
+ if (strlen(buf) > 3) {
+ in = base64_decode_data_blob(buf + 3);
} else {
- response.negTokenTarg.negResult = SPNEGO_REJECT;
- reply_code = "NA";
- pstrcpy(reply_argument, nt_errstr(status));
- }
-
- SAFE_FREE(user);
- SAFE_FREE(domain);
-
- len = write_spnego_data(&token, &response);
- free_spnego_data(&response);
-
- if (len == -1) {
- DEBUG(1, ("Could not write SPNEGO data blob\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- reply_base64 = base64_encode_data_blob(token);
-
- x_fprintf(x_stdout, "%s %s %s\n",
- reply_code, reply_base64, reply_argument);
-
- SAFE_FREE(reply_base64);
- data_blob_free(&token);
-
- return;
-}
-
-static struct ntlmssp_state *client_ntlmssp_state = NULL;
-
-static BOOL manage_client_ntlmssp_init(struct spnego_data spnego)
-{
- NTSTATUS status;
- DATA_BLOB null_blob = data_blob(NULL, 0);
- DATA_BLOB to_server;
- char *to_server_base64;
- const char *my_mechs[] = {OID_NTLMSSP, NULL};
-
- DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n"));
-
- if (client_ntlmssp_state != NULL) {
- DEBUG(1, ("Request for initial SPNEGO request where "
- "we already have a state\n"));
- return False;
- }
-
- if (!client_ntlmssp_state) {
- if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_client(&client_ntlmssp_state))) {
- x_fprintf(x_stdout, "BH %s\n", nt_errstr(status));
- return False;
- }
- }
-
-
- if (opt_password == NULL) {
-
- /* Request a password from the calling process. After
- sending it, the calling process should retry with
- the negTokenInit. */
-
- DEBUG(10, ("Requesting password\n"));
- x_fprintf(x_stdout, "PW\n");
- return True;
- }
-
- spnego.type = SPNEGO_NEG_TOKEN_INIT;
- spnego.negTokenInit.mechTypes = my_mechs;
- spnego.negTokenInit.reqFlags = 0;
- spnego.negTokenInit.mechListMIC = null_blob;
-
- status = ntlmssp_update(client_ntlmssp_state,
- NULL,
- null_blob,
- &spnego.negTokenInit.mechToken);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n",
- nt_errstr(status)));
- ntlmssp_end(&client_ntlmssp_state);
- return False;
- }
-
- write_spnego_data(&to_server, &spnego);
- data_blob_free(&spnego.negTokenInit.mechToken);
-
- to_server_base64 = base64_encode_data_blob(to_server);
- data_blob_free(&to_server);
- x_fprintf(x_stdout, "KK %s\n", to_server_base64);
- SAFE_FREE(to_server_base64);
- return True;
-}
-
-static void manage_client_ntlmssp_targ(struct spnego_data spnego)
-{
- NTSTATUS status;
- DATA_BLOB null_blob = data_blob(NULL, 0);
- DATA_BLOB request;
- DATA_BLOB to_server;
- char *to_server_base64;
-
- DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n"));
-
- 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;
- }
-
- if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) {
- x_fprintf(x_stdout, "NA\n");
- ntlmssp_end(&client_ntlmssp_state);
- return;
- }
-
- if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
- x_fprintf(x_stdout, "AF\n");
- ntlmssp_end(&client_ntlmssp_state);
- return;
- }
-
- status = ntlmssp_update(client_ntlmssp_state,
- NULL,
- spnego.negTokenTarg.responseToken,
- &request);
-
- if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from "
- "ntlmssp_update, got: %s\n",
- nt_errstr(status)));
- x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
- ntlmssp_end(&client_ntlmssp_state);
- return;
- }
-
- spnego.type = SPNEGO_NEG_TOKEN_TARG;
- spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;
- spnego.negTokenTarg.supportedMech = OID_NTLMSSP;
- spnego.negTokenTarg.responseToken = request;
- spnego.negTokenTarg.mechListMIC = null_blob;
-
- write_spnego_data(&to_server, &spnego);
- data_blob_free(&request);
-
- to_server_base64 = base64_encode_data_blob(to_server);
- data_blob_free(&to_server);
- x_fprintf(x_stdout, "KK %s\n", to_server_base64);
- SAFE_FREE(to_server_base64);
- return;
-}
-
-#ifdef HAVE_KRB5
-
-static BOOL manage_client_krb5_init(struct spnego_data spnego)
-{
- char *principal;
- DATA_BLOB tkt, to_server;
- DATA_BLOB session_key_krb5 = data_blob(NULL, 0);
- struct spnego_data reply;
- char *reply_base64;
- int retval;
-
- const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};
- ssize_t len;
-
- if ( (spnego.negTokenInit.mechListMIC.data == NULL) ||
- (spnego.negTokenInit.mechListMIC.length == 0) ) {
- DEBUG(1, ("Did not get a principal for krb5\n"));
- return False;
+ in = data_blob(NULL, 0);
}
- principal = malloc(spnego.negTokenInit.mechListMIC.length+1);
-
- if (principal == NULL) {
- DEBUG(1, ("Could not malloc principal\n"));
- return False;
- }
-
- memcpy(principal, spnego.negTokenInit.mechListMIC.data,
- spnego.negTokenInit.mechListMIC.length);
- principal[spnego.negTokenInit.mechListMIC.length] = '\0';
-
- retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5);
-
- if (retval) {
-
- pstring user;
-
- /* Let's try to first get the TGT, for that we need a
- password. */
-
- if (opt_password == NULL) {
- DEBUG(10, ("Requesting password\n"));
- x_fprintf(x_stdout, "PW\n");
- return True;
- }
-
- pstr_sprintf(user, "%s@%s", opt_username, opt_domain);
-
- 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);
-
- if (retval) {
- DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval)));
- return False;
- }
- }
-
- data_blob_free(&session_key_krb5);
-
- ZERO_STRUCT(reply);
-
- reply.type = SPNEGO_NEG_TOKEN_INIT;
- reply.negTokenInit.mechTypes = my_mechs;
- reply.negTokenInit.reqFlags = 0;
- reply.negTokenInit.mechToken = tkt;
- reply.negTokenInit.mechListMIC = data_blob(NULL, 0);
-
- len = write_spnego_data(&to_server, &reply);
- data_blob_free(&tkt);
-
- if (len == -1) {
- DEBUG(1, ("Could not write SPNEGO data blob\n"));
- return False;
- }
-
- reply_base64 = base64_encode_data_blob(to_server);
- x_fprintf(x_stdout, "KK %s *\n", reply_base64);
-
- SAFE_FREE(reply_base64);
- data_blob_free(&to_server);
- DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n"));
- return True;
-}
-
-static void manage_client_krb5_targ(struct spnego_data spnego)
-{
- switch (spnego.negTokenTarg.negResult) {
- case SPNEGO_ACCEPT_INCOMPLETE:
- DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n"));
- x_fprintf(x_stdout, "BH\n");
- break;
- case SPNEGO_ACCEPT_COMPLETED:
- DEBUG(10, ("Accept completed\n"));
- x_fprintf(x_stdout, "AF\n");
- break;
- case SPNEGO_REJECT:
- DEBUG(10, ("Rejected\n"));
- x_fprintf(x_stdout, "NA\n");
- break;
- default:
- DEBUG(1, ("Got an invalid negTokenTarg\n"));
- x_fprintf(x_stdout, "AF\n");
- }
-}
-
-#endif
-
-static void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode,
- char *buf, int length)
-{
- DATA_BLOB request;
- struct spnego_data spnego;
- ssize_t len;
-
- if (strlen(buf) <= 3) {
- DEBUG(1, ("SPNEGO query [%s] too short\n", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
- }
-
- request = base64_decode_data_blob(buf+3);
-
if (strncmp(buf, "PW ", 3) == 0) {
/* We asked for a password and obviously got it :-) */
- opt_password = strndup((const char *)request.data, request.length);
+ opt_password = strndup((const char *)in.data, in.length);
if (opt_password == NULL) {
DEBUG(1, ("Out of memory\n"));
x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
+ data_blob_free(&in);
return;
}
x_fprintf(x_stdout, "OK\n");
- data_blob_free(&request);
+ data_blob_free(&in);
return;
}
-
- if ( (strncmp(buf, "TT ", 3) != 0) &&
+ if (strncmp(buf, "YR", 2) == 0) {
+ if (gensec_state.ops) {
+ gensec_state.ops->end(&gensec_state);
+ gensec_state.ops = NULL;
+ }
+ } else if ( (strncmp(buf, "TT ", 3) != 0) &&
(strncmp(buf, "AF ", 3) != 0) &&
(strncmp(buf, "NA ", 3) != 0) ) {
DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));
x_fprintf(x_stdout, "BH\n");
- data_blob_free(&request);
+ data_blob_free(&in);
return;
}
- /* So we got a server challenge to generate a SPNEGO
- client-to-server request... */
-
- len = read_spnego_data(request, &spnego);
- data_blob_free(&request);
-
- if (len == -1) {
- DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf));
- x_fprintf(x_stdout, "BH\n");
+ if (!opt_password) {
+ x_fprintf(x_stdout, "PW\n");
+ data_blob_free(&in);
return;
}
- if (spnego.type == SPNEGO_NEG_TOKEN_INIT) {
-
- /* The server offers a list of mechanisms */
-
- char **mechType = spnego.negTokenInit.mechTypes;
-
- while (*mechType != NULL) {
-
-#ifdef HAVE_KRB5
- if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) ||
- (strcmp(*mechType, OID_KERBEROS5) == 0) ) {
- if (manage_client_krb5_init(spnego))
- goto out;
- }
-#endif
-
- if (strcmp(*mechType, OID_NTLMSSP) == 0) {
- if (manage_client_ntlmssp_init(spnego))
- goto out;
- }
-
- mechType++;
+ /* setup gensec */
+ if (!gensec_state.ops) {
+ if (stdio_helper_mode == GSS_SPNEGO_CLIENT) {
+ gensec_state.ops = gensec_security_by_oid(OID_SPNEGO);
+ } else if (stdio_helper_mode == NTLMSSP_CLIENT_1) {
+ gensec_state.ops = gensec_security_by_oid(OID_NTLMSSP);
+ } else {
+ exit(1);
}
+ gensec_state.user.name = opt_username;
+ gensec_state.user.domain = opt_domain;
+ gensec_state.user.password = opt_password;
+ nt_status = gensec_state.ops->client_start(&gensec_state);
- DEBUG(1, ("Server offered no compatible mechanism\n"));
- x_fprintf(x_stdout, "BH\n");
- return;
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1, ("SPENGO login failed to initialise: %s\n", nt_errstr(nt_status)));
+ x_fprintf(x_stdout, "BH\n");
+ return;
+ }
+ if (!in.length) {
+ first = True;
+ }
}
+
+ /* update */
- if (spnego.type == SPNEGO_NEG_TOKEN_TARG) {
-
- if (spnego.negTokenTarg.supportedMech == NULL) {
- /* On accept/reject Windows does not send the
- mechanism anymore. Handle that here and
- shut down the mechanisms. */
-
- switch (spnego.negTokenTarg.negResult) {
- case SPNEGO_ACCEPT_COMPLETED:
- x_fprintf(x_stdout, "AF\n");
- break;
- case SPNEGO_REJECT:
- x_fprintf(x_stdout, "NA\n");
- break;
- default:
- DEBUG(1, ("Got a negTokenTarg with no mech and an "
- "unknown negResult: %d\n",
- spnego.negTokenTarg.negResult));
- x_fprintf(x_stdout, "BH\n");
- }
-
- ntlmssp_end(&client_ntlmssp_state);
- goto out;
- }
+ nt_status = gensec_state.ops->update(&gensec_state, NULL, in, &out);
+
+ if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- if (strcmp(spnego.negTokenTarg.supportedMech,
- OID_NTLMSSP) == 0) {
- manage_client_ntlmssp_targ(spnego);
- goto out;
+ out_base64 = base64_encode_data_blob(out);
+ if (first) {
+ x_fprintf(x_stdout, "YR %s\n", out_base64);
+ } else {
+ x_fprintf(x_stdout, "KK %s\n", out_base64);
}
+ SAFE_FREE(out_base64);
-#if HAVE_KRB5
- if (strcmp(spnego.negTokenTarg.supportedMech,
- OID_KERBEROS5_OLD) == 0) {
- manage_client_krb5_targ(spnego);
- goto out;
- }
-#endif
+ } else if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(1, ("SPENGO login failed: %s\n", nt_errstr(nt_status)));
+ x_fprintf(x_stdout, "BH\n");
+ } else {
+ x_fprintf(x_stdout, "AF\n");
}
- DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf));
- x_fprintf(x_stdout, "BH\n");
- return;
-
- out:
- free_spnego_data(&spnego);
return;
}
@@ -1428,6 +735,7 @@ enum {
{ "helper-protocol", 0, POPT_ARG_STRING, &helper_protocol, OPT_DOMAIN, "operate as a stdio-based helper", "helper protocol to use"},
{ "domain", 0, POPT_ARG_STRING, &opt_domain, OPT_DOMAIN, "domain name"},
{ "workstation", 0, POPT_ARG_STRING, &opt_workstation, OPT_WORKSTATION, "workstation"},
+ { "username", 0, POPT_ARG_STRING, &opt_username, OPT_PASSWORD, "Username"},
{ "password", 0, POPT_ARG_STRING, &opt_password, OPT_PASSWORD, "User's plaintext password"},
POPT_COMMON_SAMBA
POPT_TABLEEND
@@ -1469,6 +777,10 @@ enum {
return 1;
}
+ if (opt_domain == NULL) {
+ opt_domain = lp_workgroup();
+ }
+
if (helper_protocol) {
int i;
for (i=0; i<NUM_HELPER_MODES; i++) {
@@ -1492,10 +804,6 @@ enum {
exit(1);
}
- if (opt_domain == NULL) {
- opt_domain = lp_workgroup();
- }
-
if (opt_workstation == NULL) {
opt_workstation = lp_netbios_name();
}