summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-07-13 09:29:25 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:19:17 -0500
commit0dc8f720e195c29d4d0422f9ae49df44543a1b6c (patch)
tree3365713c2eedc7e3018410d11eb822277b9f1c48
parentde5d9675052e311290211ce3656bb050497ae8cf (diff)
downloadsamba-0dc8f720e195c29d4d0422f9ae49df44543a1b6c.tar.gz
samba-0dc8f720e195c29d4d0422f9ae49df44543a1b6c.tar.bz2
samba-0dc8f720e195c29d4d0422f9ae49df44543a1b6c.zip
r17005: Add a new helper mode to ntlm_auth: ntlm-change-password-1
This mode proxies pre-calculated blobs from a remote (probably VPN) client into the domain. This allows clients to change their password over a PPTP connection (where they would not be able to connect to SAMR directly). The precalculated blobs do not reveal the plaintext password. Original patch by Alexey Kobozev <cobedump@gmail.com> (This used to be commit 967292b7136c5100c0b9a2783c34b1948b16dad4)
-rw-r--r--source3/nsswitch/winbindd.c1
-rw-r--r--source3/nsswitch/winbindd_dual.c1
-rw-r--r--source3/nsswitch/winbindd_nss.h13
-rw-r--r--source3/nsswitch/winbindd_pam.c148
-rw-r--r--source3/rpc_client/cli_samr.c44
-rw-r--r--source3/utils/ntlm_auth.c296
6 files changed, 502 insertions, 1 deletions
diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c
index e5582915b2..a4cd724e00 100644
--- a/source3/nsswitch/winbindd.c
+++ b/source3/nsswitch/winbindd.c
@@ -214,6 +214,7 @@ static struct winbindd_dispatch_table {
{ WINBINDD_PAM_AUTH_CRAP, winbindd_pam_auth_crap, "AUTH_CRAP" },
{ WINBINDD_PAM_CHAUTHTOK, winbindd_pam_chauthtok, "CHAUTHTOK" },
{ WINBINDD_PAM_LOGOFF, winbindd_pam_logoff, "PAM_LOGOFF" },
+ { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, winbindd_pam_chng_pswd_auth_crap, "CHNG_PSWD_AUTH_CRAP" },
/* Enumeration functions */
diff --git a/source3/nsswitch/winbindd_dual.c b/source3/nsswitch/winbindd_dual.c
index 5908c78d9a..b4d4a794ae 100644
--- a/source3/nsswitch/winbindd_dual.c
+++ b/source3/nsswitch/winbindd_dual.c
@@ -353,6 +353,7 @@ static struct winbindd_child_dispatch_table child_dispatch_table[] = {
{ WINBINDD_PAM_AUTH, winbindd_dual_pam_auth, "PAM_AUTH" },
{ WINBINDD_PAM_AUTH_CRAP, winbindd_dual_pam_auth_crap, "AUTH_CRAP" },
{ WINBINDD_PAM_LOGOFF, winbindd_dual_pam_logoff, "PAM_LOGOFF" },
+ { WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,winbindd_dual_pam_chng_pswd_auth_crap,"CHNG_PSWD_AUTH_CRAP" },
{ WINBINDD_CHECK_MACHACC, winbindd_dual_check_machine_acct, "CHECK_MACHACC" },
{ WINBINDD_DUAL_SID2UID, winbindd_dual_sid2uid, "DUAL_SID2UID" },
{ WINBINDD_DUAL_SID2GID, winbindd_dual_sid2gid, "DUAL_SID2GID" },
diff --git a/source3/nsswitch/winbindd_nss.h b/source3/nsswitch/winbindd_nss.h
index 6167a10c46..be0bb11948 100644
--- a/source3/nsswitch/winbindd_nss.h
+++ b/source3/nsswitch/winbindd_nss.h
@@ -65,6 +65,7 @@ enum winbindd_cmd {
WINBINDD_PAM_AUTH_CRAP,
WINBINDD_PAM_CHAUTHTOK,
WINBINDD_PAM_LOGOFF,
+ WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP,
/* List various things */
@@ -227,6 +228,18 @@ struct winbindd_request {
} chauthtok; /* pam_winbind passwd module */
struct {
fstring user;
+ fstring domain;
+ unsigned char new_nt_pswd[516];
+ uint16 new_nt_pswd_len;
+ unsigned char old_nt_hash_enc[16];
+ uint16 old_nt_hash_enc_len;
+ unsigned char new_lm_pswd[516];
+ uint16 new_lm_pswd_len;
+ unsigned char old_lm_hash_enc[16];
+ uint16 old_lm_hash_enc_len;
+ } chng_pswd_auth_crap;/* pam_winbind passwd module */
+ struct {
+ fstring user;
fstring krb5ccname;
uid_t uid;
} logoff; /* pam_winbind session module */
diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c
index 34d23ebf8f..6af8e31bc0 100644
--- a/source3/nsswitch/winbindd_pam.c
+++ b/source3/nsswitch/winbindd_pam.c
@@ -1901,3 +1901,151 @@ process_result:
return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
+/* Change user password with auth crap*/
+
+void winbindd_pam_chng_pswd_auth_crap(struct winbindd_cli_state *state)
+{
+ struct winbindd_domain *domain = NULL;
+ const char *domain_name = NULL;
+
+ /* Ensure null termination */
+ state->request.data.chng_pswd_auth_crap.user[
+ sizeof(state->request.data.chng_pswd_auth_crap.user)-1]=0;
+ state->request.data.chng_pswd_auth_crap.domain[
+ sizeof(state->request.data.chng_pswd_auth_crap.domain)-1]=0;
+
+ DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",
+ (unsigned long)state->pid,
+ state->request.data.chng_pswd_auth_crap.domain,
+ state->request.data.chng_pswd_auth_crap.user));
+
+ if (*state->request.data.chng_pswd_auth_crap.domain != '\0') {
+ domain_name = state->request.data.chng_pswd_auth_crap.domain;
+ } else if (lp_winbind_use_default_domain()) {
+ domain_name = lp_workgroup();
+ }
+
+ if (domain_name != NULL)
+ domain = find_domain_from_name(domain_name);
+
+ if (domain != NULL) {
+ DEBUG(7, ("[%5lu]: pam auth crap changing pswd in domain: "
+ "%s\n", (unsigned long)state->pid,domain->name));
+ sendto_domain(state, domain);
+ return;
+ }
+
+ set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER);
+ DEBUG(5, ("CRAP change password for %s\\%s returned %s (PAM: %d)\n",
+ state->request.data.chng_pswd_auth_crap.domain,
+ state->request.data.chng_pswd_auth_crap.user,
+ state->response.data.auth.nt_status_string,
+ state->response.data.auth.pam_error));
+ request_error(state);
+ return;
+}
+
+enum winbindd_result winbindd_dual_pam_chng_pswd_auth_crap(struct winbindd_domain *domainSt, struct winbindd_cli_state *state)
+{
+ NTSTATUS result;
+ DATA_BLOB new_nt_password;
+ DATA_BLOB old_nt_hash_enc;
+ DATA_BLOB new_lm_password;
+ DATA_BLOB old_lm_hash_enc;
+ fstring domain,user;
+ POLICY_HND dom_pol;
+ struct winbindd_domain *contact_domain = domainSt;
+ struct rpc_pipe_client *cli;
+
+ /* Ensure null termination */
+ state->request.data.chng_pswd_auth_crap.user[
+ sizeof(state->request.data.chng_pswd_auth_crap.user)-1]=0;
+ state->request.data.chng_pswd_auth_crap.domain[
+ sizeof(state->request.data.chng_pswd_auth_crap.domain)-1]=0;
+ *domain = 0;
+ *user = 0;
+
+ DEBUG(3, ("[%5lu]: pam change pswd auth crap domain: %s user: %s\n",
+ (unsigned long)state->pid,
+ state->request.data.chng_pswd_auth_crap.domain,
+ state->request.data.chng_pswd_auth_crap.user));
+
+ if (*state->request.data.chng_pswd_auth_crap.domain) {
+ fstrcpy(domain,state->request.data.chng_pswd_auth_crap.domain);
+ } else {
+ parse_domain_user(state->request.data.chng_pswd_auth_crap.user,
+ domain, user);
+
+ if(!*domain) {
+ DEBUG(3,("no domain specified with username (%s) - "
+ "failing auth\n",
+ state->request.data.chng_pswd_auth_crap.user));
+ result = NT_STATUS_NO_SUCH_USER;
+ goto done;
+ }
+ }
+
+ if (!*domain && lp_winbind_use_default_domain()) {
+ fstrcpy(domain,(char *)lp_workgroup());
+ }
+
+ if(!*user) {
+ fstrcpy(user, state->request.data.chng_pswd_auth_crap.user);
+ }
+
+ DEBUG(3, ("[%5lu]: pam auth crap domain: %s user: %s\n",
+ (unsigned long)state->pid, domain, user));
+
+ /* Change password */
+ new_nt_password = data_blob_talloc(
+ state->mem_ctx,
+ state->request.data.chng_pswd_auth_crap.new_nt_pswd,
+ state->request.data.chng_pswd_auth_crap.new_nt_pswd_len);
+
+ old_nt_hash_enc = data_blob_talloc(
+ state->mem_ctx,
+ state->request.data.chng_pswd_auth_crap.old_nt_hash_enc,
+ state->request.data.chng_pswd_auth_crap.old_nt_hash_enc_len);
+
+ if(state->request.data.chng_pswd_auth_crap.new_lm_pswd_len > 0) {
+ new_lm_password = data_blob_talloc(
+ state->mem_ctx,
+ state->request.data.chng_pswd_auth_crap.new_lm_pswd,
+ state->request.data.chng_pswd_auth_crap.new_lm_pswd_len);
+
+ old_lm_hash_enc = data_blob_talloc(
+ state->mem_ctx,
+ state->request.data.chng_pswd_auth_crap.old_lm_hash_enc,
+ state->request.data.chng_pswd_auth_crap.old_lm_hash_enc_len);
+ } else {
+ new_lm_password.length = 0;
+ old_lm_hash_enc.length = 0;
+ }
+
+ /* Get sam handle */
+
+ result = cm_connect_sam(contact_domain, state->mem_ctx, &cli, &dom_pol);
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(1, ("could not get SAM handle on DC for %s\n", domain));
+ goto done;
+ }
+
+ result = rpccli_samr_chng_pswd_auth_crap(
+ cli, state->mem_ctx, user, new_nt_password, old_nt_hash_enc,
+ new_lm_password, old_lm_hash_enc);
+
+ done:
+ state->response.data.auth.nt_status = NT_STATUS_V(result);
+ fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));
+ fstrcpy(state->response.data.auth.error_string,
+ get_friendly_nt_error_msg(result));
+ state->response.data.auth.pam_error = nt_status_to_pam(result);
+
+ DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2,
+ ("Password change for user [%s]\\[%s] returned %s (PAM: %d)\n",
+ domain, user,
+ state->response.data.auth.nt_status_string,
+ state->response.data.auth.pam_error));
+
+ return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
+}
diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c
index ea8db63642..4c6a868e7f 100644
--- a/source3/rpc_client/cli_samr.c
+++ b/source3/rpc_client/cli_samr.c
@@ -1288,6 +1288,50 @@ NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
return result;
}
+/* User change passwd with auth crap */
+
+NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx,
+ const char *username,
+ DATA_BLOB new_nt_password,
+ DATA_BLOB old_nt_hash_enc,
+ DATA_BLOB new_lm_password,
+ DATA_BLOB old_lm_hash_enc)
+{
+ prs_struct qbuf, rbuf;
+ SAMR_Q_CHGPASSWD_USER q;
+ SAMR_R_CHGPASSWD_USER r;
+ char *srv_name_slash;
+
+ if (!(srv_name_slash = talloc_asprintf(mem_ctx, "\\\\%s",
+ cli->cli->desthost))) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ DEBUG(5,("rpccli_samr_chng_pswd_auth_crap on server: %s\n",
+ srv_name_slash));
+
+ ZERO_STRUCT(q);
+ ZERO_STRUCT(r);
+
+ /* Marshall data and send request */
+
+ init_samr_q_chgpasswd_user(&q, srv_name_slash, username,
+ new_nt_password.data,
+ old_nt_hash_enc.data,
+ new_lm_password.data,
+ old_lm_hash_enc.data);
+
+ CLI_DO_RPC(cli, mem_ctx, PI_SAMR, SAMR_CHGPASSWD_USER,
+ q, r,
+ qbuf, rbuf,
+ samr_io_q_chgpasswd_user,
+ samr_io_r_chgpasswd_user,
+ NT_STATUS_UNSUCCESSFUL);
+
+ return r.status;
+}
+
/* change password 3 */
NTSTATUS rpccli_samr_chgpasswd3(struct rpc_pipe_client *cli,
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index fc9e3e9546..9e178ec945 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -38,6 +38,7 @@ enum stdio_helper_mode {
GSS_SPNEGO,
GSS_SPNEGO_CLIENT,
NTLM_SERVER_1,
+ NTLM_CHANGE_PASSWORD_1,
NUM_HELPER_MODES
};
@@ -62,6 +63,8 @@ static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helpe
static void manage_ntlm_server_1_request (enum stdio_helper_mode stdio_helper_mode,
char *buf, int length);
+static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_mode, char *buf, int length);
+
static const struct {
enum stdio_helper_mode mode;
const char *name;
@@ -74,6 +77,7 @@ static const struct {
{ GSS_SPNEGO, "gss-spnego", manage_gss_spnego_request},
{ GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gss_spnego_client_request},
{ NTLM_SERVER_1, "ntlm-server-1", manage_ntlm_server_1_request},
+ { NTLM_CHANGE_PASSWORD_1, "ntlm-change-password-1", manage_ntlm_change_password_1_request},
{ NUM_HELPER_MODES, NULL, NULL}
};
@@ -390,7 +394,87 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
free_response(&response);
return nt_status;
}
-
+
+/* contact server to change user password using auth crap */
+static NTSTATUS contact_winbind_change_pswd_auth_crap(const char *username,
+ const char *domain,
+ const DATA_BLOB new_nt_pswd,
+ const DATA_BLOB old_nt_hash_enc,
+ const DATA_BLOB new_lm_pswd,
+ const DATA_BLOB old_lm_hash_enc,
+ char **error_string)
+{
+ NTSTATUS nt_status;
+ NSS_STATUS result;
+ struct winbindd_request request;
+ struct winbindd_response response;
+
+ if (!get_require_membership_sid())
+ {
+ if(error_string)
+ *error_string = smb_xstrdup("Can't get membership sid.");
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ZERO_STRUCT(request);
+ ZERO_STRUCT(response);
+
+ if(username != NULL)
+ fstrcpy(request.data.chng_pswd_auth_crap.user, username);
+ if(domain != NULL)
+ fstrcpy(request.data.chng_pswd_auth_crap.domain,domain);
+
+ if(new_nt_pswd.length)
+ {
+ memcpy(request.data.chng_pswd_auth_crap.new_nt_pswd, new_nt_pswd.data, sizeof(request.data.chng_pswd_auth_crap.new_nt_pswd));
+ request.data.chng_pswd_auth_crap.new_nt_pswd_len = new_nt_pswd.length;
+ }
+
+ if(old_nt_hash_enc.length)
+ {
+ memcpy(request.data.chng_pswd_auth_crap.old_nt_hash_enc, old_nt_hash_enc.data, sizeof(request.data.chng_pswd_auth_crap.old_nt_hash_enc));
+ request.data.chng_pswd_auth_crap.old_nt_hash_enc_len = old_nt_hash_enc.length;
+ }
+
+ if(new_lm_pswd.length)
+ {
+ memcpy(request.data.chng_pswd_auth_crap.new_lm_pswd, new_lm_pswd.data, sizeof(request.data.chng_pswd_auth_crap.new_lm_pswd));
+ request.data.chng_pswd_auth_crap.new_lm_pswd_len = new_lm_pswd.length;
+ }
+
+ if(old_lm_hash_enc.length)
+ {
+ memcpy(request.data.chng_pswd_auth_crap.old_lm_hash_enc, old_lm_hash_enc.data, sizeof(request.data.chng_pswd_auth_crap.old_lm_hash_enc));
+ request.data.chng_pswd_auth_crap.old_lm_hash_enc_len = old_lm_hash_enc.length;
+ }
+
+ result = winbindd_request_response(WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, &request, &response);
+
+ /* Display response */
+
+ if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0))
+ {
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ if (error_string)
+ *error_string = smb_xstrdup("Reading winbind reply failed!");
+ free_response(&response);
+ return nt_status;
+ }
+
+ nt_status = (NT_STATUS(response.data.auth.nt_status));
+ if (!NT_STATUS_IS_OK(nt_status))
+ {
+ if (error_string)
+ *error_string = smb_xstrdup(response.data.auth.error_string);
+ free_response(&response);
+ return nt_status;
+ }
+
+ 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];
@@ -1580,6 +1664,216 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
}
}
+static void manage_ntlm_change_password_1_request(enum stdio_helper_mode helper_mode, char *buf, int length)
+{
+ char *request, *parameter;
+ static DATA_BLOB new_nt_pswd;
+ static DATA_BLOB old_nt_hash_enc;
+ static DATA_BLOB new_lm_pswd;
+ static DATA_BLOB old_lm_hash_enc;
+ static char *full_username = NULL;
+ static char *username = NULL;
+ static char *domain = NULL;
+ static char *newpswd = NULL;
+ static char *oldpswd = NULL;
+
+ if (strequal(buf, ".")) {
+ if(newpswd && oldpswd) {
+ uchar old_nt_hash[16];
+ uchar old_lm_hash[16];
+ uchar new_nt_hash[16];
+ uchar new_lm_hash[16];
+
+ new_nt_pswd = data_blob(NULL, 516);
+ old_nt_hash_enc = data_blob(NULL, 16);
+
+ /* Calculate the MD4 hash (NT compatible) of the
+ * password */
+ E_md4hash(oldpswd, old_nt_hash);
+ E_md4hash(newpswd, new_nt_hash);
+
+ /* E_deshash returns false for 'long'
+ passwords (> 14 DOS chars).
+
+ Therefore, don't send a buffer
+ encrypted with the truncated hash
+ (it could allow an even easier
+ attack on the password)
+
+ Likewise, obey the admin's restriction
+ */
+
+ if (lp_client_lanman_auth() &&
+ E_deshash(newpswd, new_lm_hash) &&
+ E_deshash(oldpswd, old_lm_hash)) {
+ new_lm_pswd = data_blob(NULL, 516);
+ old_lm_hash_enc = data_blob(NULL, 16);
+ encode_pw_buffer(new_lm_pswd.data, newpswd,
+ STR_UNICODE);
+
+ SamOEMhash(new_lm_pswd.data, old_nt_hash, 516);
+ E_old_pw_hash(new_nt_hash, old_lm_hash,
+ old_lm_hash_enc.data);
+ } else {
+ new_lm_pswd.data = NULL;
+ new_lm_pswd.length = 0;
+ old_lm_hash_enc.data = NULL;
+ old_lm_hash_enc.length = 0;
+ }
+
+ encode_pw_buffer(new_nt_pswd.data, newpswd,
+ STR_UNICODE);
+
+ SamOEMhash(new_nt_pswd.data, old_nt_hash, 516);
+ E_old_pw_hash(new_nt_hash, old_nt_hash,
+ old_nt_hash_enc.data);
+ }
+
+ if (!full_username && !username) {
+ x_fprintf(x_stdout, "Error: No username supplied!\n");
+ } else if ((!new_nt_pswd.data || !old_nt_hash_enc.data) &&
+ (!new_lm_pswd.data || old_lm_hash_enc.data) ) {
+ x_fprintf(x_stdout, "Error: No NT or LM password "
+ "blobs supplied!\n");
+ } else {
+ char *error_string = NULL;
+
+ if (full_username && !username) {
+ fstring fstr_user;
+ fstring fstr_domain;
+
+ if (!parse_ntlm_auth_domain_user(full_username,
+ fstr_user,
+ fstr_domain)) {
+ /* username might be 'tainted', don't
+ * print into our new-line
+ * deleimianted stream */
+ x_fprintf(x_stdout, "Error: Could not "
+ "parse into domain and "
+ "username\n");
+ SAFE_FREE(username);
+ username = smb_xstrdup(full_username);
+ } else {
+ SAFE_FREE(username);
+ SAFE_FREE(domain);
+ username = smb_xstrdup(fstr_user);
+ domain = smb_xstrdup(fstr_domain);
+ }
+
+ }
+
+ if(!NT_STATUS_IS_OK(contact_winbind_change_pswd_auth_crap(
+ username, domain,
+ new_nt_pswd,
+ old_nt_hash_enc,
+ new_lm_pswd,
+ old_lm_hash_enc,
+ &error_string))) {
+ x_fprintf(x_stdout, "Password-Change: No\n");
+ x_fprintf(x_stdout, "Password-Change-Error: "
+ "%s\n.\n", error_string);
+ } else {
+ x_fprintf(x_stdout, "Password-Change: Yes\n");
+ }
+
+ 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);
+ SAFE_FREE(full_username);
+ SAFE_FREE(username);
+ SAFE_FREE(domain);
+ SAFE_FREE(newpswd);
+ SAFE_FREE(oldpswd);
+ x_fprintf(x_stdout, ".\n");
+
+ return;
+ }
+
+ request = buf;
+
+ /* Indicates a base64 encoded structure */
+ parameter = strstr_m(request, ":: ");
+ if (!parameter) {
+ parameter = strstr_m(request, ": ");
+
+ if (!parameter) {
+ DEBUG(0, ("Parameter not found!\n"));
+ x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
+ return;
+ }
+
+ parameter[0] ='\0';
+ parameter++;
+ parameter[0] ='\0';
+ parameter++;
+ } else {
+ parameter[0] ='\0';
+ parameter++;
+ parameter[0] ='\0';
+ parameter++;
+ parameter[0] ='\0';
+ parameter++;
+
+ base64_decode_inplace(parameter);
+ }
+
+ if (strequal(request, "new-nt-password-blob")) {
+ new_nt_pswd = strhex_to_data_blob(NULL, parameter);
+ if (new_nt_pswd.length != 516) {
+ x_fprintf(x_stdout, "Error: hex decode of %s failed! "
+ "(got %d bytes, expected 516)\n.\n",
+ parameter,
+ (int)new_nt_pswd.length);
+ new_nt_pswd = data_blob(NULL, 0);
+ }
+ } else if (strequal(request, "old-nt-hash-blob")) {
+ old_nt_hash_enc = strhex_to_data_blob(NULL, parameter);
+ if (old_nt_hash_enc.length != 16) {
+ x_fprintf(x_stdout, "Error: hex decode of %s failed! "
+ "(got %d bytes, expected 16)\n.\n",
+ parameter,
+ (int)old_nt_hash_enc.length);
+ old_nt_hash_enc = data_blob(NULL, 0);
+ }
+ } else if (strequal(request, "new-lm-password-blob")) {
+ new_lm_pswd = strhex_to_data_blob(NULL, parameter);
+ if (new_lm_pswd.length != 516) {
+ x_fprintf(x_stdout, "Error: hex decode of %s failed! "
+ "(got %d bytes, expected 516)\n.\n",
+ parameter,
+ (int)new_lm_pswd.length);
+ new_lm_pswd = data_blob(NULL, 0);
+ }
+ }
+ else if (strequal(request, "old-lm-hash-blob")) {
+ old_lm_hash_enc = strhex_to_data_blob(NULL, parameter);
+ if (old_lm_hash_enc.length != 16)
+ {
+ x_fprintf(x_stdout, "Error: hex decode of %s failed! "
+ "(got %d bytes, expected 16)\n.\n",
+ parameter,
+ (int)old_lm_hash_enc.length);
+ old_lm_hash_enc = data_blob(NULL, 0);
+ }
+ } else if (strequal(request, "nt-domain")) {
+ domain = smb_xstrdup(parameter);
+ } else if(strequal(request, "username")) {
+ username = smb_xstrdup(parameter);
+ } else if(strequal(request, "full-username")) {
+ username = smb_xstrdup(parameter);
+ } else if(strequal(request, "new-password")) {
+ newpswd = smb_xstrdup(parameter);
+ } else if (strequal(request, "old-password")) {
+ oldpswd = smb_xstrdup(parameter);
+ } else {
+ x_fprintf(x_stdout, "Error: Unknown request %s\n.\n", request);
+ }
+}
+
static void manage_squid_request(enum stdio_helper_mode helper_mode, stdio_helper_function fn)
{
char buf[SQUID_BUFFER_SIZE+1];