Exemple #1
0
static bool print_domain_groups(const char *domain)
{
	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
	uint32_t i;
	uint32_t num_groups = 0;
	const char **groups = NULL;

	/* Send request to winbind daemon */

	/* '.' is the special sign for our own domain */
	if (domain && strcmp(domain, ".") == 0) {
		domain = get_winbind_domain();
	}

	wbc_status = wbcListGroups(domain, &num_groups, &groups);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		return false;
	}

	for (i=0; i < num_groups; i++) {
		d_printf("%s\n", groups[i]);
	}

	wbcFreeMemory(groups);

	return true;
}
Exemple #2
0
int
main(int argc, char **argv)
{
    char *target_domain;
    if (argc > 0) {		/* should always be true */
	myname = strrchr(argv[0], '/');
	if (myname == NULL)
	    myname = argv[0];
	else
	    myname++;
    } else {
	myname = "(unknown)";
    }
    mypid = getpid();
    target_domain = process_options(argc, argv);
    debug("ntlm winbindd auth helper build " __DATE__ ", " __TIME__
	" starting up...\n");

    check_winbindd();

    if (target_domain == NULL) {
	target_domain = get_winbind_domain();
    }

    /* initialize FDescs */
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);
    init_random();
    while (manage_request(target_domain)) {
	/* everything is done within manage_request */
    }
    return 0;
}
Exemple #3
0
static bool parse_wbinfo_domain_user(const char *domuser, fstring domain,
				     fstring user)
{

	char *p = strchr(domuser,winbind_separator());

	if (!p) {
		/* Maybe it was a UPN? */
		if ((p = strchr(domuser, '@')) != NULL) {
			fstrcpy(domain, "");
			fstrcpy(user, domuser);
			return true;
		}

		fstrcpy(user, domuser);
		fstrcpy(domain, get_winbind_domain());
		return true;
	}

	fstrcpy(user, p+1);
	fstrcpy(domain, domuser);
	domain[PTR_DIFF(p, domuser)] = 0;
	strupper_m(domain);

	return true;
}
Exemple #4
0
static bool print_domain_groups(const char *domain)
{
	struct winbindd_request  request;
	struct winbindd_response response;
	const char *extra_data;
	fstring name;

	ZERO_STRUCT(request);
	ZERO_STRUCT(response);

	if (domain) {
		if ( strequal(domain, ".") )
			fstrcpy( request.domain_name, get_winbind_domain() );
		else
			fstrcpy( request.domain_name, domain );
	}

	if (winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response) !=
	    NSS_STATUS_SUCCESS)
		return false;

	/* Look through extra data */

	if (!response.extra_data.data)
		return false;

	extra_data = (const char *)response.extra_data.data;

	while(next_token(&extra_data, name, ",", sizeof(fstring)))
		d_printf("%s\n", name);

	SAFE_FREE(response.extra_data.data);

	return true;
}
Exemple #5
0
static bool wbinfo_get_sidaliases(const char *domain,
				  const char *user_sid_str)
{
	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
	struct wbcDomainInfo *dinfo = NULL;
	uint32_t i;
	struct wbcDomainSid user_sid;
	uint32_t *alias_rids = NULL;
	uint32_t num_alias_rids;
	char *domain_sid_str = NULL;

	/* Send request */
	if ((domain == NULL) || (strequal(domain, ".")) ||
           (domain[0] == '\0')) {
		domain = get_winbind_domain();
	}

	/* Send request */

	wbc_status = wbcDomainInfo(domain, &dinfo);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		d_printf("wbcDomainInfo(%s) failed: %s\n", domain,
			 wbcErrorString(wbc_status));
		goto done;
	}
	wbc_status = wbcStringToSid(user_sid_str, &user_sid);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		goto done;
	}

	wbc_status = wbcGetSidAliases(&dinfo->sid, &user_sid, 1,
	    &alias_rids, &num_alias_rids);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		goto done;
	}

	wbc_status = wbcSidToString(&dinfo->sid, &domain_sid_str);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		goto done;
	}

	for (i = 0; i < num_alias_rids; i++) {
		d_printf("%s-%d\n", domain_sid_str, alias_rids[i]);
	}

	wbcFreeMemory(alias_rids);

done:
	if (domain_sid_str) {
		wbcFreeMemory(domain_sid_str);
	}
	if (dinfo) {
		wbcFreeMemory(dinfo);
	}
	return (WBC_ERR_SUCCESS == wbc_status);
}
Exemple #6
0
static bool torture_winbind_struct_domain_name(struct torture_context *torture)
{
	const char *expected;
	char *domain;

	torture_comment(torture, "Running WINBINDD_DOMAIN_NAME (struct based)\n");

	expected = torture_setting_string(torture,
					  "winbindd_netbios_domain",
					  lpcfg_workgroup(torture->lp_ctx));

	get_winbind_domain(torture, &domain);

	torture_assert_str_equal(torture, domain, expected,
				 "winbindd's netbios domain doesn't match");

	return true;
}
Exemple #7
0
static bool wbinfo_domain_info(const char *domain)
{
	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
	struct wbcDomainInfo *dinfo = NULL;
	char *sid_str = NULL;

	if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')) {
		domain = get_winbind_domain();
	}

	/* Send request */

	wbc_status = wbcDomainInfo(domain, &dinfo);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		return false;
	}

	wbc_status = wbcSidToString(&dinfo->sid, &sid_str);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		wbcFreeMemory(dinfo);
		return false;
	}

	/* Display response */

	d_printf("Name              : %s\n", dinfo->short_name);
	d_printf("Alt_Name          : %s\n", dinfo->dns_name);

	d_printf("SID               : %s\n", sid_str);

	d_printf("Active Directory  : %s\n",
		 (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_AD) ? "Yes" : "No");
	d_printf("Native            : %s\n",
		 (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_NATIVE) ? "Yes" : "No");

	d_printf("Primary           : %s\n",
		 (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_PRIMARY) ? "Yes" : "No");

	wbcFreeMemory(sid_str);
	wbcFreeMemory(dinfo);

	return true;
}
Exemple #8
0
static bool wbinfo_domain_info(const char *domain_name)
{
	struct winbindd_request request;
	struct winbindd_response response;

	ZERO_STRUCT(request);
	ZERO_STRUCT(response);

	if ((strequal(domain_name, ".")) || (domain_name[0] == '\0'))
		fstrcpy(request.domain_name, get_winbind_domain());
	else
		fstrcpy(request.domain_name, domain_name);

	/* Send request */

	if (winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response) !=
	    NSS_STATUS_SUCCESS)
		return false;

	/* Display response */

	d_printf("Name              : %s\n", response.data.domain_info.name);
	d_printf("Alt_Name          : %s\n", response.data.domain_info.alt_name);

	d_printf("SID               : %s\n", response.data.domain_info.sid);

	d_printf("Active Directory  : %s\n",
		 response.data.domain_info.active_directory ? "Yes" : "No");
	d_printf("Native            : %s\n",
		 response.data.domain_info.native_mode ? "Yes" : "No");

	d_printf("Primary           : %s\n",
		 response.data.domain_info.primary ? "Yes" : "No");

	return true;
}
Exemple #9
0
static bool wbinfo_lookuprids(const char *domain, const char *arg)
{
	wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
	struct wbcDomainInfo *dinfo = NULL;
	char *domain_name = NULL;
	const char **names = NULL;
	enum wbcSidType *types = NULL;
	size_t i;
	int num_rids;
	uint32 *rids = NULL;
	const char *p;
	char *ridstr;
	TALLOC_CTX *mem_ctx = NULL;
	bool ret = false;

	if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')) {
		domain = get_winbind_domain();
	}

	/* Send request */

	wbc_status = wbcDomainInfo(domain, &dinfo);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		d_printf("wbcDomainInfo(%s) failed: %s\n", domain,
			 wbcErrorString(wbc_status));
		goto done;
	}

	mem_ctx = talloc_new(NULL);
	if (mem_ctx == NULL) {
		d_printf("talloc_new failed\n");
		goto done;
	}

	num_rids = 0;
	rids = NULL;
	p = arg;

	while (next_token_talloc(mem_ctx, &p, &ridstr, " ,\n")) {
		uint32 rid = strtoul(ridstr, NULL, 10);
		ADD_TO_ARRAY(mem_ctx, uint32, rid, &rids, &num_rids);
	}

	if (rids == NULL) {
		d_printf("no rids\n");
		goto done;
	}

	wbc_status = wbcLookupRids(&dinfo->sid, num_rids, rids,
				   (const char **)&domain_name, &names, &types);
	if (!WBC_ERROR_IS_OK(wbc_status)) {
		d_printf("winbind_lookup_rids failed: %s\n",
			 wbcErrorString(wbc_status));
		goto done;
	}

	d_printf("Domain: %s\n", domain_name);

	for (i=0; i<num_rids; i++) {
		d_printf("%8d: %s (%s)\n", rids[i], names[i],
			 sid_type_lookup(types[i]));
	}

	ret = true;
done:
	if (dinfo) {
		wbcFreeMemory(dinfo);
	}
	if (domain_name) {
		wbcFreeMemory(domain_name);
	}
	if (names) {
		wbcFreeMemory(names);
	}
	if (types) {
		wbcFreeMemory(types);
	}
	TALLOC_FREE(mem_ctx);
	return ret;
}
Exemple #10
0
static bool wbinfo_list_own_domain(void)
{
	d_printf("%s\n", get_winbind_domain());

	return true;
}
static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which) 
{
	bool pass = True;
	NTSTATUS nt_status;
	uint32 flags = 0;
	DATA_BLOB ntlmv2_response = data_blob_null;
	DATA_BLOB lmv2_response = data_blob_null;
	DATA_BLOB ntlmv2_session_key = data_blob_null;
	DATA_BLOB names_blob = NTLMv2_generate_names_blob(NULL, get_winbind_netbios_name(), get_winbind_domain());

	uchar user_session_key[16];
	DATA_BLOB chall = get_challenge();
	char *error_string;

	ZERO_STRUCT(user_session_key);
	
	flags |= WBFLAG_PAM_USER_SESSION_KEY;

	if (!SMBNTLMv2encrypt(NULL, opt_username, opt_domain, opt_password, &chall,
			      &names_blob,
			      &lmv2_response, &ntlmv2_response, NULL,
			      &ntlmv2_session_key)) {
		data_blob_free(&names_blob);
		return False;
	}
	data_blob_free(&names_blob);

	switch (break_which) {
	case BREAK_NONE:
		break;
	case BREAK_LM:
		lmv2_response.data[0]++;
		break;
	case BREAK_NT:
		ntlmv2_response.data[0]++;
		break;
	case NO_LM:
		data_blob_free(&lmv2_response);
		break;
	case NO_NT:
		data_blob_free(&ntlmv2_response);
		break;
	}

	nt_status = contact_winbind_auth_crap(opt_username, opt_domain, 
					      opt_workstation,
					      &chall,
					      &lmv2_response,
					      &ntlmv2_response,
					      flags,
					      NULL, 
					      user_session_key,
					      &error_string, NULL);
	
	data_blob_free(&lmv2_response);
	data_blob_free(&ntlmv2_response);

	if (!NT_STATUS_IS_OK(nt_status)) {
		d_printf("%s (0x%x)\n", 
			 error_string,
			 NT_STATUS_V(nt_status));
		SAFE_FREE(error_string);
		return break_which == BREAK_NT;
	}

	if (break_which != NO_NT && break_which != BREAK_NT && memcmp(ntlmv2_session_key.data, user_session_key, 
		   sizeof(user_session_key)) != 0) {
		DEBUG(1, ("USER (NTLMv2) Session Key does not match expectations!\n"));
 		DEBUG(1, ("user_session_key:\n"));
		dump_data(1, user_session_key, 16);
 		DEBUG(1, ("expected:\n"));
		dump_data(1, ntlmv2_session_key.data, ntlmv2_session_key.length);
		pass = False;
	}
        return pass;
}
Exemple #12
0
 int main(int argc, const char **argv)
{
	int opt;
	static const char *helper_protocol;
	static int diagnostics;

	static const char *hex_challenge;
	static const char *hex_lm_response;
	static const char *hex_nt_response;

	poptContext pc;

	/* NOTE: DO NOT change this interface without considering the implications!
	   This is an external interface, which other programs will use to interact 
	   with this helper.
	*/

	/* We do not use single-letter command abbreviations, because they harm future 
	   interface stability. */

	struct poptOption long_options[] = {
		POPT_AUTOHELP
		{ "helper-protocol", 0, POPT_ARG_STRING, &helper_protocol, OPT_DOMAIN, "operate as a stdio-based helper", "helper protocol to use"},
 		{ "username", 0, POPT_ARG_STRING, &opt_username, OPT_USERNAME, "username"},
 		{ "domain", 0, POPT_ARG_STRING, &opt_domain, OPT_DOMAIN, "domain name"},
 		{ "workstation", 0, POPT_ARG_STRING, &opt_workstation, OPT_WORKSTATION, "workstation"},
 		{ "challenge", 0, POPT_ARG_STRING, &hex_challenge, OPT_CHALLENGE, "challenge (HEX encoded)"},
		{ "lm-response", 0, POPT_ARG_STRING, &hex_lm_response, OPT_LM, "LM Response to the challenge (HEX encoded)"},
		{ "nt-response", 0, POPT_ARG_STRING, &hex_nt_response, OPT_NT, "NT or NTLMv2 Response to the challenge (HEX encoded)"},
		{ "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"},
		{ "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
		POPT_TABLEEND
	};

	/* Samba client initialisation */
	load_case_tables();

	dbf = x_stderr;
	
	/* Samba client initialisation */

	if (!lp_load(dyn_CONFIGFILE, True, False, False, True)) {
		d_fprintf(stderr, "ntlm_auth: error opening config file %s. Error was %s\n",
			dyn_CONFIGFILE, strerror(errno));
		exit(1);
	}

	/* Parse options */

	pc = poptGetContext("ntlm_auth", argc, argv, long_options, 0);

	/* Parse command line options */

	if (argc == 1) {
		poptPrintHelp(pc, stderr, 0);
		return 1;
	}

	pc = poptGetContext(NULL, argc, (const char **)argv, long_options, 
			    POPT_CONTEXT_KEEP_FIRST);

	while((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case OPT_CHALLENGE:
			opt_challenge = strhex_to_data_blob(NULL, hex_challenge);
			if (opt_challenge.length != 8) {
				x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", 
					  hex_challenge,
					  (int)opt_challenge.length);
				exit(1);
			}
			break;
		case OPT_LM: 
			opt_lm_response = strhex_to_data_blob(NULL, hex_lm_response);
			if (opt_lm_response.length != 24) {
				x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", 
					  hex_lm_response,
					  (int)opt_lm_response.length);
				exit(1);
			}
			break;

		case OPT_NT: 
			opt_nt_response = strhex_to_data_blob(NULL, hex_nt_response);
			if (opt_nt_response.length < 24) {
				x_fprintf(x_stderr, "hex decode of %s failed! (only got %d bytes)\n", 
					  hex_nt_response,
					  (int)opt_nt_response.length);
				exit(1);
			}
			break;

                case OPT_REQUIRE_MEMBERSHIP:
			if (StrnCaseCmp("S-", require_membership_of, 2) == 0) {
				require_membership_of_sid = require_membership_of;
			}
			break;
		}
	}

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

	if (opt_domain == NULL || !*opt_domain) {
		opt_domain = get_winbind_domain();
	}

	if (opt_workstation == NULL) {
		opt_workstation = "";
	}

	if (helper_protocol) {
		int i;
		for (i=0; i<NUM_HELPER_MODES; i++) {
			if (strcmp(helper_protocol, stdio_helper_protocols[i].name) == 0) {
				squid_stream(stdio_helper_protocols[i].mode, stdio_helper_protocols[i].fn);
				exit(0);
			}
		}
		x_fprintf(x_stderr, "unknown helper protocol [%s]\n\nValid helper protools:\n\n", helper_protocol);

		for (i=0; i<NUM_HELPER_MODES; i++) {
			x_fprintf(x_stderr, "%s\n", stdio_helper_protocols[i].name);
		}

		exit(1);
	}

	if (!opt_username || !*opt_username) {
		x_fprintf(x_stderr, "username must be specified!\n\n");
		poptPrintHelp(pc, stderr, 0);
		exit(1);
	}

	if (opt_challenge.length) {
		if (!check_auth_crap()) {
			exit(1);
		}
		exit(0);
	} 

	if (!opt_password) {
		opt_password = getpass("password: "******"%s%c%s", opt_domain, winbind_separator(), opt_username);
		if (!check_plaintext_auth(user, opt_password, True)) {
			return 1;
		}
	}

	/* Exit code */

	poptFreeContext(pc);
	return 0;
}
Exemple #13
0
static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mode, 
					 char *buf, int length) 
{
	char *request, *parameter;	
	static DATA_BLOB challenge;
	static DATA_BLOB lm_response;
	static DATA_BLOB nt_response;
	static char *full_username;
	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;
	
	if (strequal(buf, ".")) {
		if (!full_username && !username) {	
			x_fprintf(x_stdout, "Error: No username supplied!\n");
		} else if (plaintext_password) {
			/* handle this request as plaintext */
			if (!full_username) {
				if (asprintf(&full_username, "%s%c%s", domain, winbind_separator(), username) == -1) {
					x_fprintf(x_stdout, "Error: Out of memory in asprintf!\n.\n");
					return;
				}
			}
			if (check_plaintext_auth(full_username, plaintext_password, False)) {
				x_fprintf(x_stdout, "Authenticated: Yes\n");
			} else {
				x_fprintf(x_stdout, "Authenticated: No\n");
			}
		} else if (!lm_response.data && !nt_response.data) {
			x_fprintf(x_stdout, "Error: No password supplied!\n");
		} else if (!challenge.data) {	
			x_fprintf(x_stdout, "Error: No lanman-challenge supplied!\n");
		} else {
			char *error_string = NULL;
			uchar lm_key[8];
			uchar user_session_key[16];
			uint32 flags = 0;

			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);
				SAFE_FREE(domain);
				username = smb_xstrdup(fstr_user);
				domain = smb_xstrdup(fstr_domain);
			}

			if (!domain) {
				domain = smb_xstrdup(get_winbind_domain());
			}

			if (ntlm_server_1_lm_session_key) 
				flags |= WBFLAG_PAM_LMKEY;
			
			if (ntlm_server_1_user_session_key) 
				flags |= WBFLAG_PAM_USER_SESSION_KEY;

			if (!NT_STATUS_IS_OK(
				    contact_winbind_auth_crap(username, 
							      domain, 
							      global_myname(),
							      &challenge, 
							      &lm_response, 
							      &nt_response, 
							      flags, 
							      lm_key, 
							      user_session_key,
							      &error_string,
							      NULL))) {

				x_fprintf(x_stdout, "Authenticated: No\n");
				x_fprintf(x_stdout, "Authentication-Error: %s\n.\n", error_string);
				SAFE_FREE(error_string);
			} else {
				static char zeros[16];
				char *hex_lm_key;
				char *hex_user_session_key;

				x_fprintf(x_stdout, "Authenticated: Yes\n");

				if (ntlm_server_1_lm_session_key 
				    && (memcmp(zeros, lm_key, 
					       sizeof(lm_key)) != 0)) {
					hex_lm_key = hex_encode(NULL,
								(const unsigned char *)lm_key,
								sizeof(lm_key));
					x_fprintf(x_stdout, "LANMAN-Session-Key: %s\n", hex_lm_key);
					TALLOC_FREE(hex_lm_key);
				}

				if (ntlm_server_1_user_session_key 
				    && (memcmp(zeros, user_session_key, 
					       sizeof(user_session_key)) != 0)) {
					hex_user_session_key = hex_encode(NULL,
									  (const unsigned char *)user_session_key, 
									  sizeof(user_session_key));
					x_fprintf(x_stdout, "User-Session-Key: %s\n", hex_user_session_key);
					TALLOC_FREE(hex_user_session_key);
				}
			}
		}
		/* clear out the state */
		challenge = data_blob(NULL, 0);
		nt_response = data_blob(NULL, 0);
		lm_response = data_blob(NULL, 0);
		SAFE_FREE(full_username);
		SAFE_FREE(username);
		SAFE_FREE(domain);
		SAFE_FREE(plaintext_password);
		ntlm_server_1_user_session_key = False;
		ntlm_server_1_lm_session_key = False;
		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, "LANMAN-Challenge")) {
		challenge = strhex_to_data_blob(NULL, parameter);
		if (challenge.length != 8) {
			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);
		}
	} else if (strequal(request, "NT-Response")) {
		nt_response = strhex_to_data_blob(NULL, parameter);
		if (nt_response.length < 24) {
			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);
		}
	} else if (strequal(request, "LANMAN-Response")) {
		lm_response = strhex_to_data_blob(NULL, parameter);
		if (lm_response.length != 24) {
			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);
		}
	} else if (strequal(request, "Password")) {
		plaintext_password = smb_xstrdup(parameter);
	} 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")) {
		full_username = smb_xstrdup(parameter);
	} else if (strequal(request, "Request-User-Session-Key")) {
		ntlm_server_1_user_session_key = strequal(parameter, "Yes");
	} else if (strequal(request, "Request-LanMan-Session-Key")) {
		ntlm_server_1_lm_session_key = strequal(parameter, "Yes");
	} else {
		x_fprintf(x_stdout, "Error: Unknown request %s\n.\n", request);
	}
}