mirror of
https://github.com/samba-team/samba.git
synced 2025-01-10 01:18:15 +03:00
r84: Implement --required-membership-of=, an ntlm_auth option that restricts
all authentication to members of this particular group.
Also implement an option to allow ntlm_auth to get 'squashed' error codes,
which are safer to communicate to remote network clients.
Andrew Bartlett
(This used to be commit eb1c1b5eb0
)
This commit is contained in:
parent
bd04072585
commit
869348dfcb
@ -717,3 +717,31 @@ NTSTATUS nt_status_string_to_code(char *nt_status_str)
|
||||
}
|
||||
return NT_STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Squash an NT_STATUS in line with security requirements.
|
||||
* In an attempt to avoid giving the whole game away when users
|
||||
* are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and
|
||||
* NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations
|
||||
* (session setups in particular).
|
||||
*
|
||||
* @param nt_status NTSTATUS input for squashing.
|
||||
* @return the 'squashed' nt_status
|
||||
**/
|
||||
|
||||
NTSTATUS nt_status_squash(NTSTATUS nt_status)
|
||||
{
|
||||
if NT_STATUS_IS_OK(nt_status) {
|
||||
return nt_status;
|
||||
} else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
|
||||
/* Match WinXP and don't give the game away */
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
|
||||
} else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
|
||||
/* Match WinXP and don't give the game away */
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
} else {
|
||||
return nt_status;
|
||||
}
|
||||
}
|
||||
|
@ -157,6 +157,7 @@ typedef struct winbindd_gr {
|
||||
#define WBFLAG_ALLOCATE_RID 0x0040
|
||||
#define WBFLAG_PAM_UNIX_NAME 0x0080
|
||||
#define WBFLAG_PAM_AFS_TOKEN 0x0100
|
||||
#define WBFLAG_PAM_NT_STATUS_SQUASH 0x0200
|
||||
|
||||
/* Winbind request structure */
|
||||
|
||||
@ -179,6 +180,7 @@ struct winbindd_request {
|
||||
character is. */
|
||||
fstring user;
|
||||
fstring pass;
|
||||
fstring required_membership_sid;
|
||||
} auth; /* pam_winbind auth module */
|
||||
struct {
|
||||
unsigned char chal[8];
|
||||
@ -189,6 +191,7 @@ struct winbindd_request {
|
||||
fstring nt_resp;
|
||||
uint16 nt_resp_len;
|
||||
fstring workstation;
|
||||
fstring required_membership_sid;
|
||||
} auth_crap;
|
||||
struct {
|
||||
fstring user;
|
||||
|
@ -54,8 +54,98 @@ static NTSTATUS append_info3_as_ndr(TALLOC_CTX *mem_ctx,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
static NTSTATUS check_info3_in_group(TALLOC_CTX *mem_ctx,
|
||||
NET_USER_INFO_3 *info3,
|
||||
const char *group_sid)
|
||||
{
|
||||
DOM_SID required_membership_sid;
|
||||
DOM_SID *all_sids;
|
||||
size_t num_all_sids = (2 + info3->num_groups2 + info3->num_other_sids);
|
||||
size_t i, j = 0;
|
||||
|
||||
/* Parse the 'required group' SID */
|
||||
|
||||
if (!group_sid || !group_sid[0]) {
|
||||
/* NO sid supplied, all users may access */
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
if (!string_to_sid(&required_membership_sid, group_sid)) {
|
||||
DEBUG(0, ("winbindd_pam_auth: could not parse %s as a SID!",
|
||||
group_sid));
|
||||
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
all_sids = talloc(mem_ctx, sizeof(DOM_SID) * num_all_sids);
|
||||
if (!all_sids)
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
|
||||
/* and create (by appending rids) the 'domain' sids */
|
||||
|
||||
sid_copy(&all_sids[0], &(info3->dom_sid.sid));
|
||||
|
||||
if (!sid_append_rid(&all_sids[0], info3->user_rid)) {
|
||||
DEBUG(3,("could not append user's primary RID 0x%x\n",
|
||||
info3->user_rid));
|
||||
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
j++;
|
||||
|
||||
sid_copy(&all_sids[1], &(info3->dom_sid.sid));
|
||||
|
||||
if (!sid_append_rid(&all_sids[1], info3->group_rid)) {
|
||||
DEBUG(3,("could not append additional group rid 0x%x\n",
|
||||
info3->group_rid));
|
||||
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
j++;
|
||||
|
||||
for (i = 0; i < info3->num_groups2; i++) {
|
||||
|
||||
sid_copy(&all_sids[j], &(info3->dom_sid.sid));
|
||||
|
||||
if (!sid_append_rid(&all_sids[j], info3->gids[j].g_rid)) {
|
||||
DEBUG(3,("could not append additional group rid 0x%x\n",
|
||||
info3->gids[j].g_rid));
|
||||
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Copy 'other' sids. We need to do sid filtering here to
|
||||
prevent possible elevation of privileges. See:
|
||||
|
||||
http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
|
||||
*/
|
||||
|
||||
for (i = 0; i < info3->num_other_sids; j++) {
|
||||
sid_copy(&all_sids[info3->num_groups2 + i + 2],
|
||||
&info3->other_sids[j].sid);
|
||||
j++;
|
||||
}
|
||||
|
||||
for (i = 0; i < j; i++) {
|
||||
fstring sid1, sid2;
|
||||
DEBUG(10, ("User has SID: %s\n",
|
||||
sid_to_string(sid1, &all_sids[i])));
|
||||
if (sid_equal(&required_membership_sid, &all_sids[i])) {
|
||||
DEBUG(10, ("SID %s matches %s - user permitted to authenticate!\n",
|
||||
sid_to_string(sid1, &required_membership_sid), sid_to_string(sid2, &all_sids[i])));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do not distinguish this error from a wrong username/pw */
|
||||
|
||||
return NT_STATUS_LOGON_FAILURE;
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Authenticate a user with a clear test password
|
||||
Authenticate a user with a clear text password
|
||||
**********************************************************************/
|
||||
|
||||
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
@ -125,7 +215,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
}
|
||||
|
||||
if (!(contact_domain = find_our_domain())) {
|
||||
DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n",
|
||||
DEBUG(1, ("Authentication for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n",
|
||||
state->request.data.auth.user, name_domain, name_user));
|
||||
result = NT_STATUS_NO_SUCH_USER;
|
||||
goto done;
|
||||
@ -190,8 +280,16 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
|
||||
if (NT_STATUS_IS_OK(result)) {
|
||||
netsamlogon_cache_store( cli->mem_ctx, &info3 );
|
||||
wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3);
|
||||
|
||||
/* Check if the user is in the right group */
|
||||
|
||||
if (!NT_STATUS_IS_OK(result = check_info3_in_group(mem_ctx, &info3, state->request.data.auth.required_membership_sid))) {
|
||||
DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
|
||||
state->request.data.auth.user,
|
||||
state->request.data.auth.required_membership_sid));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
/* give us a more useful (more correct?) error code */
|
||||
if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
|
||||
@ -355,7 +453,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
if ( IS_DC ) {
|
||||
if (!(contact_domain = find_domain_from_name(name_domain))) {
|
||||
DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n",
|
||||
state->request.data.auth.user, name_domain, name_user, name_domain));
|
||||
state->request.data.auth_crap.user, name_domain, name_user, name_domain));
|
||||
result = NT_STATUS_NO_SUCH_USER;
|
||||
goto done;
|
||||
}
|
||||
@ -369,7 +467,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
|
||||
if (!(contact_domain = find_our_domain())) {
|
||||
DEBUG(1, ("Authenticatoin for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n",
|
||||
state->request.data.auth.user, name_domain, name_user));
|
||||
state->request.data.auth_crap.user, name_domain, name_user));
|
||||
result = NT_STATUS_NO_SUCH_USER;
|
||||
goto done;
|
||||
}
|
||||
@ -434,6 +532,13 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
|
||||
netsamlogon_cache_store( cli->mem_ctx, &info3 );
|
||||
wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3);
|
||||
|
||||
if (!NT_STATUS_IS_OK(result = check_info3_in_group(mem_ctx, &info3, state->request.data.auth_crap.required_membership_sid))) {
|
||||
DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
|
||||
state->request.data.auth_crap.user,
|
||||
state->request.data.auth_crap.required_membership_sid));
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (state->request.flags & WBFLAG_PAM_INFO3_NDR) {
|
||||
result = append_info3_as_ndr(mem_ctx, state, &info3);
|
||||
} else if (state->request.flags & WBFLAG_PAM_UNIX_NAME) {
|
||||
@ -477,6 +582,10 @@ done:
|
||||
if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
|
||||
result = NT_STATUS_NO_LOGON_SERVERS;
|
||||
}
|
||||
|
||||
if (state->request.flags & WBFLAG_PAM_NT_STATUS_SQUASH) {
|
||||
result = nt_status_squash(result);
|
||||
}
|
||||
|
||||
state->response.data.auth.nt_status = NT_STATUS_V(result);
|
||||
push_utf8_fstring(state->response.data.auth.nt_status_string, nt_errstr(result));
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
Winbind status program.
|
||||
|
||||
Copyright (C) Tim Potter 2000-2002
|
||||
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
|
||||
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
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -91,6 +91,8 @@ static DATA_BLOB opt_nt_response;
|
||||
static int request_lm_key;
|
||||
static int request_nt_key;
|
||||
|
||||
static const char *require_membership_of;
|
||||
static const char *require_membership_sid;
|
||||
|
||||
static char winbind_separator(void)
|
||||
{
|
||||
@ -138,7 +140,7 @@ static const char *get_winbind_domain(void)
|
||||
if (winbindd_request(WINBINDD_DOMAIN_NAME, NULL, &response) !=
|
||||
NSS_STATUS_SUCCESS) {
|
||||
DEBUG(0, ("could not obtain winbind domain name!\n"));
|
||||
return NULL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fstrcpy(winbind_domain, response.data.domain_name);
|
||||
@ -173,14 +175,79 @@ static const char *get_winbind_netbios_name(void)
|
||||
|
||||
}
|
||||
|
||||
/* 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,
|
||||
fstring user)
|
||||
{
|
||||
|
||||
char *p = strchr(domuser,winbind_separator());
|
||||
|
||||
if (!p) {
|
||||
return False;
|
||||
}
|
||||
|
||||
fstrcpy(user, p+1);
|
||||
fstrcpy(domain, domuser);
|
||||
domain[PTR_DIFF(p, domuser)] = 0;
|
||||
strupper_m(domain);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
static BOOL get_require_membership_sid(void) {
|
||||
struct winbindd_request request;
|
||||
struct winbindd_response response;
|
||||
|
||||
if (!require_membership_of) {
|
||||
return True;
|
||||
}
|
||||
|
||||
if (require_membership_sid) {
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Otherwise, ask winbindd for the name->sid request */
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
if (!parse_ntlm_auth_domain_user(require_membership_of,
|
||||
request.data.name.dom_name,
|
||||
request.data.name.name)) {
|
||||
DEBUG(0, ("Could not parse %s into seperate domain/name parts!\n",
|
||||
require_membership_of));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (winbindd_request(WINBINDD_LOOKUPNAME, &request, &response) !=
|
||||
NSS_STATUS_SUCCESS) {
|
||||
DEBUG(0, ("Winbindd lookupname failed to resolve %s into a SID!\n",
|
||||
require_membership_of));
|
||||
return False;
|
||||
}
|
||||
|
||||
require_membership_sid = strdup(response.data.sid.sid);
|
||||
|
||||
if (require_membership_sid)
|
||||
return True;
|
||||
|
||||
return False;
|
||||
}
|
||||
/* 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;
|
||||
NSS_STATUS result;
|
||||
|
||||
if (!get_require_membership_sid()) {
|
||||
return False;
|
||||
}
|
||||
|
||||
/* Send off request */
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
@ -188,6 +255,8 @@ static BOOL check_plaintext_auth(const char *user, const char *pass, BOOL stdout
|
||||
|
||||
fstrcpy(request.data.auth.user, user);
|
||||
fstrcpy(request.data.auth.pass, pass);
|
||||
if (require_membership_sid)
|
||||
fstrcpy(request.data.auth.required_membership_sid, require_membership_sid);
|
||||
|
||||
result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
|
||||
|
||||
@ -237,11 +306,18 @@ static NTSTATUS contact_winbind_auth_crap(const char *username,
|
||||
|
||||
static uint8 zeros[16];
|
||||
|
||||
if (!get_require_membership_sid()) {
|
||||
return NT_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(request);
|
||||
ZERO_STRUCT(response);
|
||||
|
||||
request.flags = flags;
|
||||
|
||||
if (require_membership_sid)
|
||||
fstrcpy(request.data.auth_crap.required_membership_sid, require_membership_sid);
|
||||
|
||||
if (push_utf8_fstring(request.data.auth_crap.user, username) == -1) {
|
||||
*error_string = smb_xstrdup(
|
||||
"unable to create utf8 string for username");
|
||||
@ -264,12 +340,16 @@ static NTSTATUS contact_winbind_auth_crap(const char *username,
|
||||
memcpy(request.data.auth_crap.chal, challenge->data, MIN(challenge->length, 8));
|
||||
|
||||
if (lm_response && lm_response->length) {
|
||||
memcpy(request.data.auth_crap.lm_resp, lm_response->data, MIN(lm_response->length, sizeof(request.data.auth_crap.lm_resp)));
|
||||
memcpy(request.data.auth_crap.lm_resp,
|
||||
lm_response->data,
|
||||
MIN(lm_response->length, sizeof(request.data.auth_crap.lm_resp)));
|
||||
request.data.auth_crap.lm_resp_len = lm_response->length;
|
||||
}
|
||||
|
||||
if (nt_response && nt_response->length) {
|
||||
memcpy(request.data.auth_crap.nt_resp, nt_response->data, MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp)));
|
||||
memcpy(request.data.auth_crap.nt_resp,
|
||||
nt_response->data,
|
||||
MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp)));
|
||||
request.data.auth_crap.nt_resp_len = nt_response->length;
|
||||
}
|
||||
|
||||
@ -346,7 +426,9 @@ static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB
|
||||
} else {
|
||||
DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3,
|
||||
("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n",
|
||||
ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, error_string ? error_string : "unknown error (NULL)"));
|
||||
ntlmssp_state->domain, ntlmssp_state->user,
|
||||
ntlmssp_state->workstation,
|
||||
error_string ? error_string : "unknown error (NULL)"));
|
||||
ntlmssp_state->auth_context = NULL;
|
||||
}
|
||||
return nt_status;
|
||||
@ -382,7 +464,10 @@ static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *u
|
||||
if (memcmp(nt_key, zeros, 16) != 0) {
|
||||
*user_session_key = data_blob(nt_key, 16);
|
||||
}
|
||||
ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state->mem_ctx, "%s%c%s", ntlmssp_state->domain, *lp_winbind_separator(), ntlmssp_state->user);
|
||||
ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state->mem_ctx,
|
||||
"%s%c%s", ntlmssp_state->domain,
|
||||
*lp_winbind_separator(),
|
||||
ntlmssp_state->user);
|
||||
} else {
|
||||
DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n",
|
||||
ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation,
|
||||
@ -1381,6 +1466,8 @@ static BOOL check_auth_crap(void)
|
||||
if (request_nt_key)
|
||||
flags |= WBFLAG_PAM_USER_SESSION_KEY;
|
||||
|
||||
flags |= WBFLAG_PAM_NT_STATUS_SQUASH;
|
||||
|
||||
nt_status = contact_winbind_auth_crap(opt_username, opt_domain,
|
||||
opt_workstation,
|
||||
&opt_challenge,
|
||||
@ -1773,7 +1860,7 @@ static BOOL test_lmv2_ntlmv2_broken(enum ntlm_break break_which)
|
||||
|
||||
if (break_which != NO_NT && break_which != BREAK_NT && memcmp(user_session_key.data, nt_key,
|
||||
sizeof(nt_key)) != 0) {
|
||||
DEBUG(1, ("USER Session Key does not match expectations!\n"));
|
||||
DEBUG(1, ("USER (NT) Session Key does not match expectations!\n"));
|
||||
DEBUG(1, ("nt_key:\n"));
|
||||
dump_data(1, (const char *)nt_key, 16);
|
||||
DEBUG(1, ("expected:\n"));
|
||||
@ -2008,7 +2095,8 @@ enum {
|
||||
OPT_PASSWORD,
|
||||
OPT_LM_KEY,
|
||||
OPT_NT_KEY,
|
||||
OPT_DIAGNOSTICS
|
||||
OPT_DIAGNOSTICS,
|
||||
OPT_REQUIRE_MEMBERSHIP
|
||||
};
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
@ -2020,12 +2108,6 @@ enum {
|
||||
static const char *hex_challenge;
|
||||
static const char *hex_lm_response;
|
||||
static const char *hex_nt_response;
|
||||
char *challenge;
|
||||
char *lm_response;
|
||||
char *nt_response;
|
||||
size_t challenge_len;
|
||||
size_t lm_response_len;
|
||||
size_t nt_response_len;
|
||||
|
||||
poptContext pc;
|
||||
|
||||
@ -2050,6 +2132,7 @@ enum {
|
||||
{ "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retreive LM session key"},
|
||||
{ "request-nt-key", 0, POPT_ARG_NONE, &request_nt_key, OPT_NT_KEY, "Retreive 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
|
||||
};
|
||||
@ -2083,40 +2166,32 @@ enum {
|
||||
while((opt = poptGetNextOpt(pc)) != -1) {
|
||||
switch (opt) {
|
||||
case OPT_CHALLENGE:
|
||||
challenge = smb_xmalloc((strlen(hex_challenge))/2+1);
|
||||
if ((challenge_len = strhex_to_str(challenge,
|
||||
strlen(hex_challenge),
|
||||
hex_challenge)) != 8) {
|
||||
x_fprintf(x_stderr, "hex decode of %s failed (only got %lu bytes)!\n",
|
||||
hex_challenge, (unsigned long)challenge_len);
|
||||
opt_challenge = strhex_to_data_blob(hex_challenge);
|
||||
if (opt_challenge.length != 8) {
|
||||
x_fprintf(x_stderr, "hex decode of %s failed!\n", hex_challenge);
|
||||
exit(1);
|
||||
}
|
||||
opt_challenge = data_blob(challenge, challenge_len);
|
||||
SAFE_FREE(challenge);
|
||||
break;
|
||||
case OPT_LM:
|
||||
lm_response = smb_xmalloc((strlen(hex_lm_response))/2+1);
|
||||
lm_response_len = strhex_to_str(lm_response,
|
||||
strlen(hex_lm_response),
|
||||
hex_lm_response);
|
||||
if (lm_response_len != 24) {
|
||||
opt_lm_response = strhex_to_data_blob(hex_lm_response);
|
||||
if (opt_lm_response.length != 24) {
|
||||
x_fprintf(x_stderr, "hex decode of %s failed!\n", hex_lm_response);
|
||||
exit(1);
|
||||
}
|
||||
opt_lm_response = data_blob(lm_response, lm_response_len);
|
||||
SAFE_FREE(lm_response);
|
||||
break;
|
||||
|
||||
case OPT_NT:
|
||||
nt_response = smb_xmalloc((strlen(hex_nt_response)+2)/2+1);
|
||||
nt_response_len = strhex_to_str(nt_response,
|
||||
strlen(hex_nt_response),
|
||||
hex_nt_response);
|
||||
if (nt_response_len < 24) {
|
||||
opt_nt_response = strhex_to_data_blob(hex_nt_response);
|
||||
if (opt_nt_response.length < 24) {
|
||||
x_fprintf(x_stderr, "hex decode of %s failed!\n", hex_nt_response);
|
||||
exit(1);
|
||||
}
|
||||
opt_nt_response = data_blob(nt_response, nt_response_len);
|
||||
SAFE_FREE(nt_response);
|
||||
break;
|
||||
|
||||
case OPT_REQUIRE_MEMBERSHIP:
|
||||
if (StrnCaseCmp("S-", require_membership_of, 2) == 0) {
|
||||
require_membership_sid = require_membership_of;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user