mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
I've decided to move the auth code around a bit more...
The auth_authsupplied_info typedef is now just a plain struct - auth_context, but it has been modified to contain the function pointers to the rest of the auth subsystem's components. (Who needs non-static functions anyway?) In working all this mess out, I fixed a number of memory leaks and moved the entire auth subsystem over to talloc(). Note that the TALLOC_CTX attached to the auth_context can be rather long-lived, it is provided for things that are intended to live as long. (The global_negprot_auth_context lasts the whole life of the smbd). I've also adjusted a few things in auth_domain.c, mainly passing the domain as a paramater to a few functions instead of looking up lp_workgroup(). I'm hopign to make this entire thing a bit more trusted domains (as PDC) freindly in the near future. Other than that, I moved a bit of the code around, hence the rather messy diff. Andrew Bartlett
This commit is contained in:
parent
207ee8aac4
commit
12f5515f55
@ -201,7 +201,7 @@ PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
|
|||||||
|
|
||||||
AUTH_OBJ = auth/auth.o auth/auth_sam.o auth/auth_server.o auth/auth_domain.o \
|
AUTH_OBJ = auth/auth.o auth/auth_sam.o auth/auth_server.o auth/auth_domain.o \
|
||||||
auth/auth_rhosts.o auth/auth_unix.o auth/auth_util.o auth/auth_winbind.o \
|
auth/auth_rhosts.o auth/auth_unix.o auth/auth_util.o auth/auth_winbind.o \
|
||||||
auth/auth_info.o auth/auth_builtin.o $(PLAINTEXT_AUTH_OBJ)
|
auth/auth_builtin.o auth/auth_compat.o $(PLAINTEXT_AUTH_OBJ)
|
||||||
|
|
||||||
|
|
||||||
SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
|
SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
Unix SMB/Netbios implementation.
|
Unix SMB/Netbios implementation.
|
||||||
Version 1.9.
|
Version 3.0.
|
||||||
Password and authentication handling
|
Password and authentication handling
|
||||||
Copyright (C) Andrew Tridgell 1992-2000
|
Copyright (C) Andrew Bartlett 2001-2002
|
||||||
Copyright (C) Luke Kenneth Casson Leighton 1996-2000
|
|
||||||
Copyright (C) Andrew Bartlett 2001
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -23,6 +21,95 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
|
/** List of various built-in authenticaion modules */
|
||||||
|
|
||||||
|
const struct auth_init_function builtin_auth_init_functions[] = {
|
||||||
|
{ "guest", auth_init_guest },
|
||||||
|
{ "rhosts", auth_init_rhosts },
|
||||||
|
{ "hostsequiv", auth_init_hostsequiv },
|
||||||
|
{ "sam", auth_init_sam },
|
||||||
|
{ "samstrict", auth_init_samstrict },
|
||||||
|
{ "unix", auth_init_unix },
|
||||||
|
{ "smbserver", auth_init_smbserver },
|
||||||
|
{ "ntdomain", auth_init_ntdomain },
|
||||||
|
{ "winbind", auth_init_winbind },
|
||||||
|
#ifdef DEVELOPER
|
||||||
|
{ "name_to_ntstatus", auth_init_name_to_ntstatus },
|
||||||
|
#endif
|
||||||
|
{ NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
Try to get a challenge out of the various authenticaion modules.
|
||||||
|
Returns a const char of length 8 bytes.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static const uint8 *get_ntlm_challenge(struct auth_context *auth_context)
|
||||||
|
{
|
||||||
|
DATA_BLOB challenge = data_blob(NULL, 0);
|
||||||
|
char *challenge_set_by = NULL;
|
||||||
|
auth_methods *auth_method;
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
|
||||||
|
if (auth_context->challenge.length) {
|
||||||
|
DEBUG(5, ("get_ntlm_challange (auth subsystem): returning previous challenge (normal)\n"));
|
||||||
|
return auth_context->challenge.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auth_method = auth_context->auth_method_list; auth_method; auth_method = auth_method->next)
|
||||||
|
{
|
||||||
|
if (auth_method->get_chal == NULL) {
|
||||||
|
DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG(5, ("auth_get_challenge: getting challenge from module %s\n", auth_method->name));
|
||||||
|
if (challenge_set_by != NULL) {
|
||||||
|
DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authenticaion method %s has already specified a challenge. Challenge by %s ignored.\n",
|
||||||
|
challenge_set_by, auth_method->name));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_ctx = talloc_init_named("auth_get_challange for module %s", auth_method->name);
|
||||||
|
if (!mem_ctx) {
|
||||||
|
smb_panic("talloc_init_named() failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx);
|
||||||
|
if (!challenge.length) {
|
||||||
|
DEBUG(3, ("auth_get_challenge: getting challenge from authenticaion method %s FAILED.\n",
|
||||||
|
auth_method->name));
|
||||||
|
} else {
|
||||||
|
DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name));
|
||||||
|
auth_context->challenge = challenge;
|
||||||
|
challenge_set_by = auth_method->name;
|
||||||
|
auth_context->challenge_set_method = auth_method;
|
||||||
|
}
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!challenge_set_by) {
|
||||||
|
uchar chal[8];
|
||||||
|
|
||||||
|
generate_random_buffer(chal, sizeof(chal), False);
|
||||||
|
auth_context->challenge = data_blob_talloc(auth_context->mem_ctx,
|
||||||
|
chal, sizeof(chal));
|
||||||
|
|
||||||
|
challenge_set_by = "random";
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by));
|
||||||
|
DEBUG(5, ("challenge is: \n"));
|
||||||
|
dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
|
||||||
|
|
||||||
|
SMB_ASSERT(auth_context->challenge.length == 8);
|
||||||
|
|
||||||
|
auth_context->challenge_set_by=challenge_set_by;
|
||||||
|
|
||||||
|
return auth_context->challenge.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check user is in correct domain (if required)
|
* Check user is in correct domain (if required)
|
||||||
*
|
*
|
||||||
@ -81,9 +168,9 @@ static BOOL check_domain_match(const char *user, const char *domain)
|
|||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
NTSTATUS check_password(const auth_usersupplied_info *user_info,
|
static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
|
||||||
const auth_authsupplied_info *auth_info,
|
const struct auth_usersupplied_info *user_info,
|
||||||
auth_serversupplied_info **server_info)
|
struct auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
|
|
||||||
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
||||||
@ -91,7 +178,7 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
|
|||||||
auth_methods *auth_method;
|
auth_methods *auth_method;
|
||||||
TALLOC_CTX *mem_ctx;
|
TALLOC_CTX *mem_ctx;
|
||||||
|
|
||||||
if (!user_info || !auth_info || !server_info) {
|
if (!user_info || !auth_context || !server_info) {
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,11 +187,11 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
|
|||||||
|
|
||||||
DEBUG(3, ("check_password: mapped user is: [%s]\\[%s]@[%s]\n",
|
DEBUG(3, ("check_password: mapped user is: [%s]\\[%s]@[%s]\n",
|
||||||
user_info->domain.str, user_info->internal_username.str, user_info->wksta_name.str));
|
user_info->domain.str, user_info->internal_username.str, user_info->wksta_name.str));
|
||||||
if (auth_info->challenge_set_by) {
|
if (auth_context->challenge_set_by) {
|
||||||
DEBUG(10, ("auth_info challenge created by %s\n", auth_info->challenge_set_by));
|
DEBUG(10, ("auth_context challenge created by %s\n", auth_context->challenge_set_by));
|
||||||
}
|
}
|
||||||
DEBUG(10, ("challenge is: \n"));
|
DEBUG(10, ("challenge is: \n"));
|
||||||
dump_data(5, (auth_info)->challenge.data, (auth_info)->challenge.length);
|
dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
|
||||||
|
|
||||||
#ifdef DEBUG_PASSWORD
|
#ifdef DEBUG_PASSWORD
|
||||||
DEBUG(100, ("user_info has passwords of length %d and %d\n",
|
DEBUG(100, ("user_info has passwords of length %d and %d\n",
|
||||||
@ -120,12 +207,12 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
|
|||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auth_method = auth_info->auth_method_list;auth_method; auth_method = auth_method->next)
|
for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next)
|
||||||
{
|
{
|
||||||
mem_ctx = talloc_init_named("%s authentication for user %s\\%s", auth_method->name,
|
mem_ctx = talloc_init_named("%s authentication for user %s\\%s", auth_method->name,
|
||||||
user_info->domain.str, user_info->smb_name.str);
|
user_info->domain.str, user_info->smb_name.str);
|
||||||
|
|
||||||
nt_status = auth_method->auth(auth_method->private_data, mem_ctx, user_info, auth_info, server_info);
|
nt_status = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info);
|
||||||
if (NT_STATUS_IS_OK(nt_status)) {
|
if (NT_STATUS_IS_OK(nt_status)) {
|
||||||
DEBUG(3, ("check_password: %s authentication for user [%s] suceeded\n",
|
DEBUG(3, ("check_password: %s authentication for user [%s] suceeded\n",
|
||||||
auth_method->name, user_info->smb_name.str));
|
auth_method->name, user_info->smb_name.str));
|
||||||
@ -182,124 +269,188 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
|
|||||||
ZERO_STRUCTP(server_info);
|
ZERO_STRUCTP(server_info);
|
||||||
}
|
}
|
||||||
return nt_status;
|
return nt_status;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/***************************************************************************
|
||||||
* Squash an NT_STATUS in line with security requirements.
|
Clear out a auth_context, and destroy the attached TALLOC_CTX
|
||||||
* 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)
|
static void free_auth_context(struct auth_context **auth_context)
|
||||||
{
|
{
|
||||||
if NT_STATUS_IS_OK(nt_status) {
|
if (*auth_context != NULL) {
|
||||||
return nt_status;
|
talloc_destroy((*auth_context)->mem_ctx);
|
||||||
} else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
|
}
|
||||||
/* Match WinXP and don't give the game away */
|
*auth_context = NULL;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
Make a auth_info struct
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
static NTSTATUS make_auth_context(struct auth_context **auth_context)
|
||||||
/****************************************************************************
|
|
||||||
COMPATABILITY INTERFACES:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
check if a username/password is OK assuming the password is a 24 byte
|
|
||||||
SMB hash
|
|
||||||
return True if the password is correct, False otherwise
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static NTSTATUS pass_check_smb(char *smb_name,
|
|
||||||
char *domain,
|
|
||||||
DATA_BLOB lm_pwd,
|
|
||||||
DATA_BLOB nt_pwd,
|
|
||||||
DATA_BLOB plaintext_password,
|
|
||||||
BOOL encrypted)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
|
||||||
|
mem_ctx = talloc_init_named("authentication context");
|
||||||
|
|
||||||
|
*auth_context = talloc(mem_ctx, sizeof(**auth_context));
|
||||||
|
if (!*auth_context) {
|
||||||
|
DEBUG(0,("make_auth_context: talloc failed!\n"));
|
||||||
|
talloc_destroy(mem_ctx);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
ZERO_STRUCTP(*auth_context);
|
||||||
|
|
||||||
|
(*auth_context)->mem_ctx = mem_ctx;
|
||||||
|
(*auth_context)->check_ntlm_password = check_ntlm_password;
|
||||||
|
(*auth_context)->get_ntlm_challenge = get_ntlm_challenge;
|
||||||
|
(*auth_context)->free = free_auth_context;
|
||||||
|
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
Make a auth_info struct for the auth subsystem
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, char **text_list)
|
||||||
|
{
|
||||||
|
auth_methods *list = NULL;
|
||||||
|
auth_methods *t = NULL;
|
||||||
|
auth_methods *tmp;
|
||||||
|
int i;
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
auth_usersupplied_info *user_info = NULL;
|
|
||||||
extern auth_authsupplied_info *negprot_global_auth_info;
|
|
||||||
auth_serversupplied_info *server_info = NULL;
|
|
||||||
if (encrypted) {
|
|
||||||
make_user_info_for_reply_enc(&user_info, smb_name,
|
|
||||||
domain,
|
|
||||||
lm_pwd,
|
|
||||||
nt_pwd,
|
|
||||||
plaintext_password);
|
|
||||||
nt_status = check_password(user_info, negprot_global_auth_info, &server_info);
|
|
||||||
} else {
|
|
||||||
auth_authsupplied_info *plaintext_auth_info = NULL;
|
|
||||||
DATA_BLOB chal;
|
|
||||||
if (!make_auth_info_subsystem(&plaintext_auth_info)) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
chal = auth_get_challenge(plaintext_auth_info);
|
if (!text_list) {
|
||||||
|
DEBUG(2,("No auth method list!?\n"));
|
||||||
if (!make_user_info_for_reply(&user_info,
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
smb_name, domain, chal.data,
|
}
|
||||||
plaintext_password)) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context))) {
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;*text_list; text_list++)
|
||||||
|
{
|
||||||
|
DEBUG(5,("Attempting to find an auth method to match %s\n", *text_list));
|
||||||
|
for (i = 0; builtin_auth_init_functions[i].name; i++)
|
||||||
|
{
|
||||||
|
if (strequal(builtin_auth_init_functions[i].name, *text_list))
|
||||||
|
{
|
||||||
|
DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i));
|
||||||
|
if (builtin_auth_init_functions[i].init(*auth_context, &t)) {
|
||||||
|
DEBUG(5,("auth method %s has a valid init\n", *text_list));
|
||||||
|
t->name = builtin_auth_init_functions[i].name;
|
||||||
|
DLIST_ADD_END(list, t, tmp);
|
||||||
|
} else {
|
||||||
|
DEBUG(0,("auth method %s did not correctly init\n", *text_list));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
nt_status = check_password(user_info, plaintext_auth_info, &server_info);
|
|
||||||
|
(*auth_context)->auth_method_list = list;
|
||||||
data_blob_free(&chal);
|
|
||||||
free_auth_info(&plaintext_auth_info);
|
|
||||||
}
|
|
||||||
free_user_info(&user_info);
|
|
||||||
free_server_info(&server_info);
|
|
||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/***************************************************************************
|
||||||
check if a username/password pair is OK either via the system password
|
Make a auth_context struct for the auth subsystem
|
||||||
database or the encrypted SMB password database
|
***************************************************************************/
|
||||||
return True if the password is correct, False otherwise
|
|
||||||
****************************************************************************/
|
|
||||||
BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
|
|
||||||
{
|
|
||||||
|
|
||||||
DATA_BLOB null_password = data_blob(NULL, 0);
|
NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context)
|
||||||
extern BOOL global_encrypted_passwords_negotiated;
|
{
|
||||||
BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
|
char **auth_method_list = NULL;
|
||||||
|
NTSTATUS nt_status;
|
||||||
if (encrypted) {
|
|
||||||
/*
|
if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) {
|
||||||
* The password could be either NTLM or plain LM. Try NTLM first,
|
return NT_STATUS_NO_MEMORY;
|
||||||
* but fall-through as required.
|
|
||||||
* NTLMv2 makes no sense here.
|
|
||||||
*/
|
|
||||||
if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return False;
|
if (auth_method_list == NULL) {
|
||||||
|
switch (lp_security())
|
||||||
|
{
|
||||||
|
case SEC_DOMAIN:
|
||||||
|
DEBUG(5,("Making default auth method list for security=domain\n"));
|
||||||
|
auth_method_list = lp_list_make("guest samstrict ntdomain");
|
||||||
|
break;
|
||||||
|
case SEC_SERVER:
|
||||||
|
DEBUG(5,("Making default auth method list for security=server\n"));
|
||||||
|
auth_method_list = lp_list_make("guest samstrict smbserver");
|
||||||
|
break;
|
||||||
|
case SEC_USER:
|
||||||
|
if (lp_encrypted_passwords()) {
|
||||||
|
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
|
||||||
|
auth_method_list = lp_list_make("guest sam");
|
||||||
|
} else {
|
||||||
|
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
|
||||||
|
auth_method_list = lp_list_make("guest unix");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SEC_SHARE:
|
||||||
|
if (lp_encrypted_passwords()) {
|
||||||
|
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
|
||||||
|
auth_method_list = lp_list_make("guest sam");
|
||||||
|
} else {
|
||||||
|
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
|
||||||
|
auth_method_list = lp_list_make("guest unix");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SEC_ADS:
|
||||||
|
DEBUG(5,("Making default auth method list for security=ADS\n"));
|
||||||
|
auth_method_list = lp_list_make("guest samstrict ads ntdomain");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DEBUG(5,("Unknown auth method!\n"));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DEBUG(5,("Using specified auth order\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_text_list(auth_context, auth_method_list))) {
|
||||||
|
lp_list_free(&auth_method_list);
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
lp_list_free(&auth_method_list);
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
Make a auth_info struct with a random challenge
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS make_auth_context_random(struct auth_context **auth_context)
|
||||||
|
{
|
||||||
|
uchar chal[8];
|
||||||
|
NTSTATUS nt_status;
|
||||||
|
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) {
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
generate_random_buffer(chal, sizeof(chal), False);
|
||||||
|
(*auth_context)->challenge = data_blob(chal, sizeof(chal));
|
||||||
|
|
||||||
|
(*auth_context)->challenge_set_by = "random";
|
||||||
|
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
Make a auth_info struct with a fixed challenge
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[8])
|
||||||
|
{
|
||||||
|
NTSTATUS nt_status;
|
||||||
|
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) {
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*auth_context)->challenge = data_blob(chal, 8);
|
||||||
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@
|
|||||||
* and pass onto the next module.
|
* and pass onto the next module.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
static NTSTATUS check_guest_security(void *my_private_data,
|
static NTSTATUS check_guest_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
||||||
@ -50,9 +50,9 @@ static NTSTATUS check_guest_security(void *my_private_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Guest modules initialisation */
|
/* Guest modules initialisation */
|
||||||
BOOL auth_init_guest(auth_methods **auth_method)
|
BOOL auth_init_guest(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
if (!make_auth_methods(auth_method)) {
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,10 +73,10 @@ BOOL auth_init_guest(auth_methods **auth_method)
|
|||||||
* @return An NTSTATUS value based on the username
|
* @return An NTSTATUS value based on the username
|
||||||
**/
|
**/
|
||||||
|
|
||||||
static NTSTATUS check_name_to_ntstatus_security(void *my_private_data,
|
static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
@ -100,9 +100,9 @@ static NTSTATUS check_name_to_ntstatus_security(void *my_private_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Module initailisation function */
|
/** Module initailisation function */
|
||||||
BOOL auth_init_name_to_ntstatus(auth_methods **auth_method)
|
BOOL auth_init_name_to_ntstatus(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
if (!make_auth_methods(auth_method)) {
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +110,3 @@ BOOL auth_init_name_to_ntstatus(auth_methods **auth_method)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
111
source/auth/auth_compat.c
Normal file
111
source/auth/auth_compat.c
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
Unix SMB/Netbios implementation.
|
||||||
|
Version 3.0.
|
||||||
|
Password and authentication handling
|
||||||
|
Copyright (C) Andrew Bartlett 2001-2002
|
||||||
|
|
||||||
|
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
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "includes.h"
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
COMPATABILITY INTERFACES:
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
check if a username/password is OK assuming the password is a 24 byte
|
||||||
|
SMB hash
|
||||||
|
return True if the password is correct, False otherwise
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static NTSTATUS pass_check_smb(char *smb_name,
|
||||||
|
char *domain,
|
||||||
|
DATA_BLOB lm_pwd,
|
||||||
|
DATA_BLOB nt_pwd,
|
||||||
|
DATA_BLOB plaintext_password,
|
||||||
|
BOOL encrypted)
|
||||||
|
|
||||||
|
{
|
||||||
|
NTSTATUS nt_status;
|
||||||
|
auth_usersupplied_info *user_info = NULL;
|
||||||
|
extern struct auth_context *negprot_global_auth_context;
|
||||||
|
auth_serversupplied_info *server_info = NULL;
|
||||||
|
if (encrypted) {
|
||||||
|
make_user_info_for_reply_enc(&user_info, smb_name,
|
||||||
|
domain,
|
||||||
|
lm_pwd,
|
||||||
|
nt_pwd);
|
||||||
|
nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context,
|
||||||
|
user_info, &server_info);
|
||||||
|
} else {
|
||||||
|
struct auth_context *plaintext_auth_context = NULL;
|
||||||
|
const uint8 *chal;
|
||||||
|
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
|
||||||
|
|
||||||
|
if (!make_user_info_for_reply(&user_info,
|
||||||
|
smb_name, domain, chal,
|
||||||
|
plaintext_password)) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context,
|
||||||
|
user_info, &server_info);
|
||||||
|
|
||||||
|
plaintext_auth_context->free(&plaintext_auth_context);
|
||||||
|
}
|
||||||
|
free_user_info(&user_info);
|
||||||
|
free_server_info(&server_info);
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
check if a username/password pair is ok via the auth subsystem.
|
||||||
|
return True if the password is correct, False otherwise
|
||||||
|
****************************************************************************/
|
||||||
|
BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
|
||||||
|
{
|
||||||
|
|
||||||
|
DATA_BLOB null_password = data_blob(NULL, 0);
|
||||||
|
extern BOOL global_encrypted_passwords_negotiated;
|
||||||
|
BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
|
||||||
|
|
||||||
|
if (encrypted) {
|
||||||
|
/*
|
||||||
|
* The password could be either NTLM or plain LM. Try NTLM first,
|
||||||
|
* but fall-through as required.
|
||||||
|
* NTLMv2 makes no sense here.
|
||||||
|
*/
|
||||||
|
if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -125,8 +125,10 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
|
|||||||
Utility function to attempt a connection to an IP address of a DC.
|
Utility function to attempt a connection to an IP address of a DC.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, struct in_addr *ip,
|
static NTSTATUS attempt_connect_to_dc(struct cli_state **cli,
|
||||||
unsigned char *trust_passwd)
|
const char *domain,
|
||||||
|
struct in_addr *ip,
|
||||||
|
unsigned char *trust_passwd)
|
||||||
{
|
{
|
||||||
fstring dc_name;
|
fstring dc_name;
|
||||||
|
|
||||||
@ -137,7 +139,7 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, struct in_addr *ip
|
|||||||
if (is_zero_ip(*ip))
|
if (is_zero_ip(*ip))
|
||||||
return NT_STATUS_UNSUCCESSFUL;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
if (!lookup_dc_name(global_myname, lp_workgroup(), ip, dc_name))
|
if (!lookup_dc_name(global_myname, domain, ip, dc_name))
|
||||||
return NT_STATUS_UNSUCCESSFUL;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
return connect_to_domain_password_server(cli, dc_name, trust_passwd);
|
return connect_to_domain_password_server(cli, dc_name, trust_passwd);
|
||||||
@ -145,11 +147,12 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, struct in_addr *ip
|
|||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
We have been asked to dynamcially determine the IP addresses of
|
We have been asked to dynamcially determine the IP addresses of
|
||||||
the PDC and BDC's for this DOMAIN, and query them in turn.
|
the PDC and BDC's for DOMAIN, and query them in turn.
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
||||||
unsigned char *trust_passwd,
|
const char *domain,
|
||||||
time_t last_change_time)
|
unsigned char *trust_passwd,
|
||||||
|
time_t last_change_time)
|
||||||
{
|
{
|
||||||
struct in_addr *ip_list = NULL;
|
struct in_addr *ip_list = NULL;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@ -169,7 +172,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
|||||||
if (time_now - last_change_time < 3600)
|
if (time_now - last_change_time < 3600)
|
||||||
use_pdc_only = True;
|
use_pdc_only = True;
|
||||||
|
|
||||||
if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count))
|
if (!get_dc_list(use_pdc_only, domain, &ip_list, &count))
|
||||||
return NT_STATUS_UNSUCCESSFUL;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -180,7 +183,9 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
|||||||
if(!is_local_net(ip_list[i]))
|
if(!is_local_net(ip_list[i]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, &ip_list[i], trust_passwd)))
|
if(NT_STATUS_IS_OK(nt_status =
|
||||||
|
attempt_connect_to_dc(cli, domain,
|
||||||
|
&ip_list[i], trust_passwd)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
zero_ip(&ip_list[i]); /* Tried and failed. */
|
zero_ip(&ip_list[i]); /* Tried and failed. */
|
||||||
@ -192,7 +197,9 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
|||||||
if(!NT_STATUS_IS_OK(nt_status)) {
|
if(!NT_STATUS_IS_OK(nt_status)) {
|
||||||
i = (sys_random() % count);
|
i = (sys_random() % count);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, &ip_list[i], trust_passwd)))
|
if (!NT_STATUS_IS_OK(nt_status =
|
||||||
|
attempt_connect_to_dc(cli, domain,
|
||||||
|
&ip_list[i], trust_passwd)))
|
||||||
zero_ip(&ip_list[i]); /* Tried and failed. */
|
zero_ip(&ip_list[i]); /* Tried and failed. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +213,9 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
|||||||
* Note that from a WINS server the #1 IP address is the PDC.
|
* Note that from a WINS server the #1 IP address is the PDC.
|
||||||
*/
|
*/
|
||||||
for(i = 0; i < count; i++) {
|
for(i = 0; i < count; i++) {
|
||||||
if (NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, &ip_list[i], trust_passwd)))
|
if (NT_STATUS_IS_OK(nt_status =
|
||||||
|
attempt_connect_to_dc(cli, domain,
|
||||||
|
&ip_list[i], trust_passwd)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,6 +233,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
|
|||||||
|
|
||||||
static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
|
const char *domain,
|
||||||
uchar chal[8],
|
uchar chal[8],
|
||||||
auth_serversupplied_info **server_info,
|
auth_serversupplied_info **server_info,
|
||||||
char *server, unsigned char *trust_passwd,
|
char *server, unsigned char *trust_passwd,
|
||||||
@ -246,7 +256,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
|||||||
while (!NT_STATUS_IS_OK(nt_status) &&
|
while (!NT_STATUS_IS_OK(nt_status) &&
|
||||||
next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
|
next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
|
||||||
if(strequal(remote_machine, "*")) {
|
if(strequal(remote_machine, "*")) {
|
||||||
nt_status = find_connect_pdc(&cli, trust_passwd, last_change_time);
|
nt_status = find_connect_pdc(&cli, domain, trust_passwd, last_change_time);
|
||||||
} else {
|
} else {
|
||||||
nt_status = connect_to_domain_password_server(&cli, remote_machine, trust_passwd);
|
nt_status = connect_to_domain_password_server(&cli, remote_machine, trust_passwd);
|
||||||
}
|
}
|
||||||
@ -376,18 +386,19 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
|
|||||||
Check for a valid username and password in security=domain mode.
|
Check for a valid username and password in security=domain mode.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static NTSTATUS check_ntdomain_security(void *my_private_data,
|
static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
||||||
char *p, *pserver;
|
char *p, *pserver;
|
||||||
unsigned char trust_passwd[16];
|
unsigned char trust_passwd[16];
|
||||||
time_t last_change_time;
|
time_t last_change_time;
|
||||||
|
char *domain = lp_workgroup();
|
||||||
|
|
||||||
if (!user_info || !server_info || !auth_info) {
|
if (!user_info || !server_info || !auth_context) {
|
||||||
DEBUG(1,("check_ntdomain_security: Critical variables not present. Failing.\n"));
|
DEBUG(1,("check_ntdomain_security: Critical variables not present. Failing.\n"));
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
}
|
}
|
||||||
@ -409,7 +420,7 @@ static NTSTATUS check_ntdomain_security(void *my_private_data,
|
|||||||
* Get the machine account password for our primary domain
|
* Get the machine account password for our primary domain
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, &last_change_time))
|
if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time))
|
||||||
{
|
{
|
||||||
DEBUG(0, ("check_domain_security: could not fetch trust account password for domain %s\n", lp_workgroup()));
|
DEBUG(0, ("check_domain_security: could not fetch trust account password for domain %s\n", lp_workgroup()));
|
||||||
unbecome_root();
|
unbecome_root();
|
||||||
@ -433,18 +444,22 @@ static NTSTATUS check_ntdomain_security(void *my_private_data,
|
|||||||
if (! *pserver) pserver = "*";
|
if (! *pserver) pserver = "*";
|
||||||
p = pserver;
|
p = pserver;
|
||||||
|
|
||||||
nt_status = domain_client_validate(mem_ctx, user_info, (uchar *)auth_info->challenge.data,server_info,
|
nt_status = domain_client_validate(mem_ctx, user_info, domain,
|
||||||
|
(uchar *)auth_context->challenge.data,
|
||||||
|
server_info,
|
||||||
p, trust_passwd, last_change_time);
|
p, trust_passwd, last_change_time);
|
||||||
|
|
||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL auth_init_ntdomain(auth_methods **auth_method)
|
/* module initialisation */
|
||||||
|
BOOL auth_init_ntdomain(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
if (!make_auth_methods(auth_method)) {
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*auth_method)->auth = check_ntdomain_security;
|
(*auth_method)->auth = check_ntdomain_security;
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,313 +0,0 @@
|
|||||||
/*
|
|
||||||
Unix SMB/Netbios implementation.
|
|
||||||
Version 3.0.
|
|
||||||
Authentication utility functions
|
|
||||||
Copyright (C) Andrew Bartlett 2001
|
|
||||||
|
|
||||||
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
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "includes.h"
|
|
||||||
|
|
||||||
/** List of various built-in authenticaion modules */
|
|
||||||
|
|
||||||
const struct auth_init_function builtin_auth_init_functions[] = {
|
|
||||||
{ "guest", auth_init_guest },
|
|
||||||
{ "rhosts", auth_init_rhosts },
|
|
||||||
{ "hostsequiv", auth_init_hostsequiv },
|
|
||||||
{ "sam", auth_init_sam },
|
|
||||||
{ "samstrict", auth_init_samstrict },
|
|
||||||
{ "unix", auth_init_unix },
|
|
||||||
{ "smbserver", auth_init_smbserver },
|
|
||||||
{ "ntdomain", auth_init_ntdomain },
|
|
||||||
{ "winbind", auth_init_winbind },
|
|
||||||
#ifdef DEVELOPER
|
|
||||||
{ "name_to_ntstatus", auth_init_name_to_ntstatus },
|
|
||||||
#endif
|
|
||||||
{ NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Free a linked list of auth methods
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
static void free_auth_methods_list(auth_methods **list)
|
|
||||||
{
|
|
||||||
if (list != NULL) {
|
|
||||||
while (*list) {
|
|
||||||
auth_methods *old_head = *list;
|
|
||||||
if ((*list)->free_private_data) {
|
|
||||||
(*list)->free_private_data(&((*list)->private_data));
|
|
||||||
}
|
|
||||||
DLIST_REMOVE(*list, *list);
|
|
||||||
SAFE_FREE(old_head);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Make a auth_info struct
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
static BOOL make_auth_info(auth_authsupplied_info **auth_info)
|
|
||||||
{
|
|
||||||
*auth_info = malloc(sizeof(**auth_info));
|
|
||||||
if (!*auth_info) {
|
|
||||||
DEBUG(0,("make_auth_info: malloc failed!\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
ZERO_STRUCTP(*auth_info);
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Make a auth_info struct with a specified list.
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
BOOL make_auth_info_list(auth_authsupplied_info **auth_info, auth_methods *list)
|
|
||||||
{
|
|
||||||
if (!make_auth_info(auth_info)) {
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*auth_info)->auth_method_list = list;
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Make a auth_info struct for the auth subsystem
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char **text_list)
|
|
||||||
{
|
|
||||||
auth_methods *list = NULL;
|
|
||||||
auth_methods *t = NULL;
|
|
||||||
auth_methods *tmp;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!text_list) {
|
|
||||||
DEBUG(2,("No auth method list!?\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;*text_list; text_list++)
|
|
||||||
{
|
|
||||||
DEBUG(5,("Attempting to find an auth method to match %s\n", *text_list));
|
|
||||||
for (i = 0; builtin_auth_init_functions[i].name; i++)
|
|
||||||
{
|
|
||||||
if (strequal(builtin_auth_init_functions[i].name, *text_list))
|
|
||||||
{
|
|
||||||
DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i));
|
|
||||||
if (builtin_auth_init_functions[i].init(&t)) {
|
|
||||||
DEBUG(5,("auth method %s has a valid init\n", *text_list));
|
|
||||||
t->name = builtin_auth_init_functions[i].name;
|
|
||||||
DLIST_ADD_END(list, t, tmp);
|
|
||||||
} else {
|
|
||||||
DEBUG(5,("auth method %s DOES NOT have a valid init\n", *text_list));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!make_auth_info_list(auth_info, list)) {
|
|
||||||
free_auth_methods_list(&list);
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Make a auth_info struct for the auth subsystem
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
BOOL make_auth_info_subsystem(auth_authsupplied_info **auth_info)
|
|
||||||
{
|
|
||||||
char **auth_method_list = NULL;
|
|
||||||
|
|
||||||
if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) {
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth_method_list == NULL) {
|
|
||||||
switch (lp_security())
|
|
||||||
{
|
|
||||||
case SEC_DOMAIN:
|
|
||||||
DEBUG(5,("Making default auth method list for security=domain\n"));
|
|
||||||
auth_method_list = lp_list_make("guest samstrict ntdomain");
|
|
||||||
break;
|
|
||||||
case SEC_SERVER:
|
|
||||||
DEBUG(5,("Making default auth method list for security=server\n"));
|
|
||||||
auth_method_list = lp_list_make("guest samstrict smbserver");
|
|
||||||
break;
|
|
||||||
case SEC_USER:
|
|
||||||
if (lp_encrypted_passwords()) {
|
|
||||||
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n"));
|
|
||||||
auth_method_list = lp_list_make("guest sam");
|
|
||||||
} else {
|
|
||||||
DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
|
|
||||||
auth_method_list = lp_list_make("guest unix");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SEC_SHARE:
|
|
||||||
if (lp_encrypted_passwords()) {
|
|
||||||
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
|
|
||||||
auth_method_list = lp_list_make("guest sam");
|
|
||||||
} else {
|
|
||||||
DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n"));
|
|
||||||
auth_method_list = lp_list_make("guest unix");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SEC_ADS:
|
|
||||||
DEBUG(5,("Making default auth method list for security=ADS\n"));
|
|
||||||
auth_method_list = lp_list_make("guest samstrict ads ntdomain");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DEBUG(5,("Unknown auth method!\n"));
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DEBUG(5,("Using specified auth order\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!make_auth_info_text_list(auth_info, auth_method_list)) {
|
|
||||||
lp_list_free(&auth_method_list);
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
lp_list_free(&auth_method_list);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Make a auth_info struct with a random challenge
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
BOOL make_auth_info_random(auth_authsupplied_info **auth_info)
|
|
||||||
{
|
|
||||||
uchar chal[8];
|
|
||||||
if (!make_auth_info_subsystem(auth_info)) {
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_random_buffer(chal, sizeof(chal), False);
|
|
||||||
(*auth_info)->challenge = data_blob(chal, sizeof(chal));
|
|
||||||
|
|
||||||
(*auth_info)->challenge_set_by = "random";
|
|
||||||
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Make a auth_info struct with a fixed challenge
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8])
|
|
||||||
{
|
|
||||||
if (!make_auth_info_subsystem(auth_info)) {
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
|
|
||||||
(*auth_info)->challenge = data_blob(chal, 8);
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Clear out a auth_info struct that has been allocated
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
void free_auth_info(auth_authsupplied_info **auth_info)
|
|
||||||
{
|
|
||||||
if (*auth_info != NULL) {
|
|
||||||
free_auth_methods_list(&(*auth_info)->auth_method_list);
|
|
||||||
|
|
||||||
data_blob_free(&(*auth_info)->challenge);
|
|
||||||
ZERO_STRUCT(**auth_info);
|
|
||||||
}
|
|
||||||
SAFE_FREE(*auth_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
Try to get a challenge out of the various authenticaion modules.
|
|
||||||
It is up to the caller to free it.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
DATA_BLOB auth_get_challenge(auth_authsupplied_info *auth_info)
|
|
||||||
{
|
|
||||||
DATA_BLOB challenge = data_blob(NULL, 0);
|
|
||||||
char *challenge_set_by = NULL;
|
|
||||||
auth_methods *auth_method;
|
|
||||||
TALLOC_CTX *mem_ctx;
|
|
||||||
|
|
||||||
if (auth_info->challenge.length) {
|
|
||||||
DEBUG(5, ("auth_get_challenge: returning previous challenge (normal)\n"));
|
|
||||||
return data_blob(auth_info->challenge.data, auth_info->challenge.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auth_method = auth_info->auth_method_list; auth_method; auth_method = auth_method->next)
|
|
||||||
{
|
|
||||||
if (auth_method->get_chal) {
|
|
||||||
DEBUG(5, ("auth_get_challenge: getting challenge from module %s\n", auth_method->name));
|
|
||||||
if (challenge_set_by) {
|
|
||||||
DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authenticaion method %s has already specified a challenge. Challenge by %s ignored.\n",
|
|
||||||
challenge_set_by, auth_method->name));
|
|
||||||
} else {
|
|
||||||
mem_ctx = talloc_init_named("auth_get_challange for module %s", auth_method->name);
|
|
||||||
if (!mem_ctx) {
|
|
||||||
smb_panic("talloc_init_named() failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
challenge = auth_method->get_chal(&auth_method->private_data, mem_ctx, auth_info);
|
|
||||||
if (challenge.length) {
|
|
||||||
DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name));
|
|
||||||
auth_info->challenge = challenge;
|
|
||||||
challenge_set_by = auth_method->name;
|
|
||||||
auth_info->challenge_set_method = auth_method;
|
|
||||||
} else {
|
|
||||||
DEBUG(3, ("auth_get_challenge: getting challenge from authenticaion method %s FAILED.\n",
|
|
||||||
auth_method->name));
|
|
||||||
}
|
|
||||||
talloc_destroy(mem_ctx);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!challenge_set_by) {
|
|
||||||
uchar chal[8];
|
|
||||||
|
|
||||||
generate_random_buffer(chal, sizeof(chal), False);
|
|
||||||
auth_info->challenge = data_blob(chal, sizeof(chal));
|
|
||||||
|
|
||||||
challenge_set_by = "random";
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(5, ("auth_info challenge created by %s\n", challenge_set_by));
|
|
||||||
DEBUG(5, ("challenge is: \n"));
|
|
||||||
dump_data(5, auth_info->challenge.data, (auth_info)->challenge.length);
|
|
||||||
|
|
||||||
SMB_ASSERT(auth_info->challenge.length == 8);
|
|
||||||
|
|
||||||
auth_info->challenge_set_by=challenge_set_by;
|
|
||||||
|
|
||||||
return data_blob(auth_info->challenge.data, auth_info->challenge.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -155,10 +155,10 @@ static BOOL check_hosts_equiv(struct passwd *pass)
|
|||||||
Check for a valid .rhosts/hosts.equiv entry for this user
|
Check for a valid .rhosts/hosts.equiv entry for this user
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static NTSTATUS check_hostsequiv_security(void *my_private_data,
|
static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
||||||
@ -176,15 +176,26 @@ static NTSTATUS check_hostsequiv_security(void *my_private_data,
|
|||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* module initialisation */
|
||||||
|
BOOL auth_init_hostsequiv(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
|
{
|
||||||
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
|
return False;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*auth_method)->auth = check_hostsequiv_security;
|
||||||
|
return True;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Check for a valid .rhosts/hosts.equiv entry for this user
|
Check for a valid .rhosts/hosts.equiv entry for this user
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static NTSTATUS check_rhosts_security(void *my_private_data,
|
static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
|
||||||
@ -209,22 +220,13 @@ static NTSTATUS check_rhosts_security(void *my_private_data,
|
|||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL auth_init_hostsequiv(auth_methods **auth_method)
|
/* module initialisation */
|
||||||
|
BOOL auth_init_rhosts(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
if (!make_auth_methods(auth_method)) {
|
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
(*auth_method)->auth = check_hostsequiv_security;
|
|
||||||
return True;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL auth_init_rhosts(auth_methods **auth_method)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (!make_auth_methods(auth_method)) {
|
|
||||||
return False;
|
|
||||||
}
|
|
||||||
(*auth_method)->auth = check_rhosts_security;
|
(*auth_method)->auth = check_rhosts_security;
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,9 @@
|
|||||||
core of smb password checking routine.
|
core of smb password checking routine.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
|
static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
|
||||||
const uchar *part_passwd,
|
const uchar *part_passwd,
|
||||||
DATA_BLOB sec_blob,
|
DATA_BLOB sec_blob,
|
||||||
uint8 user_sess_key[16])
|
uint8 user_sess_key[16])
|
||||||
{
|
{
|
||||||
/* Finish the encryption of part_passwd. */
|
/* Finish the encryption of part_passwd. */
|
||||||
uchar p24[24];
|
uchar p24[24];
|
||||||
@ -75,10 +75,10 @@ static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
|
|||||||
core of smb password checking routine.
|
core of smb password checking routine.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
|
static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
|
||||||
const uchar *part_passwd,
|
const uchar *part_passwd,
|
||||||
const DATA_BLOB sec_blob,
|
const DATA_BLOB sec_blob,
|
||||||
const char *user, const char *domain,
|
const char *user, const char *domain,
|
||||||
uint8 user_sess_key[16])
|
uint8 user_sess_key[16])
|
||||||
{
|
{
|
||||||
/* Finish the encryption of part_passwd. */
|
/* Finish the encryption of part_passwd. */
|
||||||
uchar kr[16];
|
uchar kr[16];
|
||||||
@ -132,10 +132,10 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
|
|||||||
Do a specific test for an smb password being correct, given a smb_password and
|
Do a specific test for an smb password being correct, given a smb_password and
|
||||||
the lanman and NT responses.
|
the lanman and NT responses.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
|
static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
|
||||||
|
TALLOC_CTX *mem_ctx,
|
||||||
SAM_ACCOUNT *sampass,
|
SAM_ACCOUNT *sampass,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
uint8 user_sess_key[16])
|
uint8 user_sess_key[16])
|
||||||
{
|
{
|
||||||
uint16 acct_ctrl;
|
uint16 acct_ctrl;
|
||||||
@ -175,7 +175,7 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
|
|||||||
*/
|
*/
|
||||||
DEBUG(4,("sam_password_ok: Checking NTLMv2 password\n"));
|
DEBUG(4,("sam_password_ok: Checking NTLMv2 password\n"));
|
||||||
if (smb_pwd_check_ntlmv2( user_info->nt_resp,
|
if (smb_pwd_check_ntlmv2( user_info->nt_resp,
|
||||||
nt_pw, auth_info->challenge,
|
nt_pw, auth_context->challenge,
|
||||||
user_info->smb_name.str,
|
user_info->smb_name.str,
|
||||||
user_info->client_domain.str,
|
user_info->client_domain.str,
|
||||||
user_sess_key))
|
user_sess_key))
|
||||||
@ -192,7 +192,7 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
|
|||||||
*/
|
*/
|
||||||
DEBUG(4,("sam_password_ok: Checking NT MD4 password\n"));
|
DEBUG(4,("sam_password_ok: Checking NT MD4 password\n"));
|
||||||
if (smb_pwd_check_ntlmv1(user_info->nt_resp,
|
if (smb_pwd_check_ntlmv1(user_info->nt_resp,
|
||||||
nt_pw, auth_info->challenge,
|
nt_pw, auth_context->challenge,
|
||||||
user_sess_key))
|
user_sess_key))
|
||||||
{
|
{
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
@ -225,7 +225,7 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
|
|||||||
|
|
||||||
DEBUG(4,("sam_password_ok: Checking LM password\n"));
|
DEBUG(4,("sam_password_ok: Checking LM password\n"));
|
||||||
if (smb_pwd_check_ntlmv1(user_info->lm_resp,
|
if (smb_pwd_check_ntlmv1(user_info->lm_resp,
|
||||||
lm_pw, auth_info->challenge,
|
lm_pw, auth_context->challenge,
|
||||||
user_sess_key))
|
user_sess_key))
|
||||||
{
|
{
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
@ -337,10 +337,10 @@ SMB hash supplied in the user_info structure
|
|||||||
return an NT_STATUS constant.
|
return an NT_STATUS constant.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static NTSTATUS check_sam_security(void *my_private_data,
|
static NTSTATUS check_sam_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
SAM_ACCOUNT *sampass=NULL;
|
SAM_ACCOUNT *sampass=NULL;
|
||||||
@ -349,8 +349,8 @@ static NTSTATUS check_sam_security(void *my_private_data,
|
|||||||
uint8 user_sess_key[16];
|
uint8 user_sess_key[16];
|
||||||
const uint8* lm_hash;
|
const uint8* lm_hash;
|
||||||
|
|
||||||
if (!user_info || !auth_info) {
|
if (!user_info || !auth_context) {
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pdb_init_sam(&sampass)) {
|
if (!pdb_init_sam(&sampass)) {
|
||||||
@ -370,7 +370,7 @@ static NTSTATUS check_sam_security(void *my_private_data,
|
|||||||
return NT_STATUS_NO_SUCH_USER;
|
return NT_STATUS_NO_SUCH_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
nt_status = sam_password_ok(mem_ctx, sampass, user_info, auth_info, user_sess_key);
|
nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||||
pdb_free_sam(&sampass);
|
pdb_free_sam(&sampass);
|
||||||
@ -399,9 +399,10 @@ static NTSTATUS check_sam_security(void *my_private_data,
|
|||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL auth_init_sam(auth_methods **auth_method)
|
/* module initialisation */
|
||||||
|
BOOL auth_init_sam(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
if (!make_auth_methods(auth_method)) {
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,20 +410,19 @@ BOOL auth_init_sam(auth_methods **auth_method)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
check if a username/password is OK assuming the password is a 24 byte
|
Check SAM security (above) but with a few extra checks.
|
||||||
SMB hash supplied in the user_info structure
|
|
||||||
return an NT_STATUS constant.
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static NTSTATUS check_samstrict_security(void *my_private_data,
|
static NTSTATUS check_samstrict_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!user_info || !auth_info) {
|
if (!user_info || !auth_context) {
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,12 +434,13 @@ static NTSTATUS check_samstrict_security(void *my_private_data,
|
|||||||
return NT_STATUS_NO_SUCH_USER;
|
return NT_STATUS_NO_SUCH_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return check_sam_security(my_private_data, mem_ctx, user_info, auth_info, server_info);
|
return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL auth_init_samstrict(auth_methods **auth_method)
|
/* module initialisation */
|
||||||
|
BOOL auth_init_samstrict(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
if (!make_auth_methods(auth_method)) {
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,3 +448,4 @@ BOOL auth_init_samstrict(auth_methods **auth_method)
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,9 +134,9 @@ static void send_server_keepalive(void **private_data_pointer)
|
|||||||
Get the challenge out of a password server.
|
Get the challenge out of a password server.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static DATA_BLOB auth_get_challenge_server(void **my_private_data,
|
static DATA_BLOB auth_get_challenge_server(const struct auth_context *auth_context,
|
||||||
TALLOC_CTX *mem_ctx,
|
void **my_private_data,
|
||||||
const struct authsupplied_info *auth_info)
|
TALLOC_CTX *mem_ctx)
|
||||||
{
|
{
|
||||||
struct cli_state *cli = server_cryptkey(mem_ctx);
|
struct cli_state *cli = server_cryptkey(mem_ctx);
|
||||||
|
|
||||||
@ -161,8 +161,10 @@ static DATA_BLOB auth_get_challenge_server(void **my_private_data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*my_private_data = (void *)cli;
|
*my_private_data = (void *)cli;
|
||||||
|
|
||||||
return data_blob(cli->secblob.data,8);
|
/* The return must be allocated on the caller's mem_ctx, as our own will be
|
||||||
|
destoyed just after the call. */
|
||||||
|
return data_blob_talloc(auth_context->mem_ctx, cli->secblob.data,8);
|
||||||
} else {
|
} else {
|
||||||
return data_blob(NULL, 0);
|
return data_blob(NULL, 0);
|
||||||
}
|
}
|
||||||
@ -174,10 +176,10 @@ static DATA_BLOB auth_get_challenge_server(void **my_private_data,
|
|||||||
- Validate a password with the password server.
|
- Validate a password with the password server.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static NTSTATUS check_smbserver_security(void *my_private_data,
|
static NTSTATUS check_smbserver_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
struct cli_state *cli;
|
struct cli_state *cli;
|
||||||
@ -218,7 +220,7 @@ static NTSTATUS check_smbserver_security(void *my_private_data,
|
|||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (memcmp(cli->secblob.data, auth_info->challenge.data, 8) != 0) {
|
if (memcmp(cli->secblob.data, auth_context->challenge.data, 8) != 0) {
|
||||||
DEBUG(1,("the challenge that the password server (%s) supplied us is not the one we gave our client. This just can't work :-(\n", cli->desthost));
|
DEBUG(1,("the challenge that the password server (%s) supplied us is not the one we gave our client. This just can't work :-(\n", cli->desthost));
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_LOGON_FAILURE;
|
||||||
}
|
}
|
||||||
@ -353,9 +355,9 @@ use this machine as the password server.\n"));
|
|||||||
return(nt_status);
|
return(nt_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL auth_init_smbserver(auth_methods **auth_method)
|
BOOL auth_init_smbserver(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
if (!make_auth_methods(auth_method)) {
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
(*auth_method)->auth = check_smbserver_security;
|
(*auth_method)->auth = check_smbserver_security;
|
||||||
|
@ -83,10 +83,10 @@ static BOOL update_smbpassword_file(char *user, char *password)
|
|||||||
* unless the account has a null password.
|
* unless the account has a null password.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
NTSTATUS check_unix_security(void *my_private_data,
|
static NTSTATUS check_unix_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
@ -120,11 +120,13 @@ NTSTATUS check_unix_security(void *my_private_data,
|
|||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL auth_init_unix(auth_methods **auth_method)
|
/* module initialisation */
|
||||||
|
BOOL auth_init_unix(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
if (!make_auth_methods(auth_method)) {
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*auth_method)->auth = check_unix_security;
|
(*auth_method)->auth = check_unix_security;
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
@ -276,13 +276,13 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
|
BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
|
||||||
char *smb_name,
|
const char *smb_name,
|
||||||
char *client_domain,
|
const char *client_domain,
|
||||||
char *wksta_name,
|
const char *wksta_name,
|
||||||
uchar chal[8],
|
const uchar chal[8],
|
||||||
uchar lm_interactive_pwd[16],
|
const uchar lm_interactive_pwd[16],
|
||||||
uchar nt_interactive_pwd[16],
|
const uchar nt_interactive_pwd[16],
|
||||||
uchar *dc_sess_key)
|
const uchar *dc_sess_key)
|
||||||
{
|
{
|
||||||
char lm_pwd[16];
|
char lm_pwd[16];
|
||||||
char nt_pwd[16];
|
char nt_pwd[16];
|
||||||
@ -360,7 +360,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
|
|||||||
BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
|
BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
|
||||||
char *smb_name,
|
char *smb_name,
|
||||||
char *client_domain,
|
char *client_domain,
|
||||||
unsigned char chal[8],
|
const uint8 chal[8],
|
||||||
DATA_BLOB plaintext_password)
|
DATA_BLOB plaintext_password)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -383,7 +383,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
|
|||||||
dump_data(100, plaintext_password.data, plaintext_password.length);
|
dump_data(100, plaintext_password.data, plaintext_password.length);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
|
SMBencrypt( (const uchar *)plaintext_password.data, (const uchar*)chal, local_lm_response);
|
||||||
local_lm_blob = data_blob(local_lm_response, 24);
|
local_lm_blob = data_blob(local_lm_response, 24);
|
||||||
|
|
||||||
/* We can't do an NT hash here, as the password needs to be
|
/* We can't do an NT hash here, as the password needs to be
|
||||||
@ -415,8 +415,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
|
|||||||
BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
|
BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
|
||||||
char *smb_name,
|
char *smb_name,
|
||||||
char *client_domain,
|
char *client_domain,
|
||||||
DATA_BLOB lm_resp, DATA_BLOB nt_resp,
|
DATA_BLOB lm_resp, DATA_BLOB nt_resp)
|
||||||
DATA_BLOB plaintext_password)
|
|
||||||
{
|
{
|
||||||
uint32 ntlmssp_flags = 0;
|
uint32 ntlmssp_flags = 0;
|
||||||
|
|
||||||
@ -572,9 +571,17 @@ BOOL make_server_info_guest(auth_serversupplied_info **server_info)
|
|||||||
Make an auth_methods struct
|
Make an auth_methods struct
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
BOOL make_auth_methods(auth_methods **auth_method)
|
BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
*auth_method = malloc(sizeof(**auth_method));
|
if (!auth_context) {
|
||||||
|
smb_panic("no auth_context supplied to make_auth_methods()!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!auth_method) {
|
||||||
|
smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
*auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
|
||||||
if (!*auth_method) {
|
if (!*auth_method) {
|
||||||
DEBUG(0,("make_auth_method: malloc failed!\n"));
|
DEBUG(0,("make_auth_method: malloc failed!\n"));
|
||||||
return False;
|
return False;
|
||||||
@ -623,3 +630,33 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
|
|||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,10 +33,10 @@ NSS_STATUS winbindd_request(int req_type,
|
|||||||
|
|
||||||
/* Authenticate a user with a challenge/response */
|
/* Authenticate a user with a challenge/response */
|
||||||
|
|
||||||
static NTSTATUS check_winbind_security(void *my_private_data,
|
static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const auth_usersupplied_info *user_info,
|
||||||
const auth_authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info)
|
auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
struct winbindd_request request;
|
struct winbindd_request request;
|
||||||
@ -46,13 +46,13 @@ static NTSTATUS check_winbind_security(void *my_private_data,
|
|||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
|
|
||||||
if (!user_info) {
|
if (!user_info) {
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!auth_info) {
|
if (!auth_context) {
|
||||||
DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
|
DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n",
|
||||||
user_info->internal_username.str));
|
user_info->internal_username.str));
|
||||||
return NT_STATUS_LOGON_FAILURE;
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send off request */
|
/* Send off request */
|
||||||
@ -63,7 +63,7 @@ static NTSTATUS check_winbind_security(void *my_private_data,
|
|||||||
snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user),
|
snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user),
|
||||||
"%s\\%s", user_info->domain.str, user_info->smb_name.str);
|
"%s\\%s", user_info->domain.str, user_info->smb_name.str);
|
||||||
|
|
||||||
memcpy(request.data.auth_crap.chal, auth_info->challenge.data, sizeof(request.data.auth_crap.chal));
|
memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
|
||||||
|
|
||||||
request.data.auth_crap.lm_resp_len = MIN(user_info->lm_resp.length,
|
request.data.auth_crap.lm_resp_len = MIN(user_info->lm_resp.length,
|
||||||
sizeof(request.data.auth_crap.lm_resp));
|
sizeof(request.data.auth_crap.lm_resp));
|
||||||
@ -97,16 +97,13 @@ static NTSTATUS check_winbind_security(void *my_private_data,
|
|||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL auth_init_winbind(auth_methods **auth_method)
|
/* module initialisation */
|
||||||
|
BOOL auth_init_winbind(struct auth_context *auth_context, auth_methods **auth_method)
|
||||||
{
|
{
|
||||||
if (!make_auth_methods(auth_method)) {
|
if (!make_auth_methods(auth_context, auth_method)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*auth_method)->auth = check_winbind_security;
|
(*auth_method)->auth = check_winbind_security;
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ typedef struct interactive_password
|
|||||||
OWF_INFO nt_owf; /* NT OWF Password */
|
OWF_INFO nt_owf; /* NT OWF Password */
|
||||||
} auth_interactive_password;
|
} auth_interactive_password;
|
||||||
|
|
||||||
typedef struct usersupplied_info
|
typedef struct auth_usersupplied_info
|
||||||
{
|
{
|
||||||
|
|
||||||
DATA_BLOB lm_resp;
|
DATA_BLOB lm_resp;
|
||||||
@ -67,7 +67,7 @@ typedef struct usersupplied_info
|
|||||||
#define SAM_FILL_UNIX 0x08
|
#define SAM_FILL_UNIX 0x08
|
||||||
#define SAM_FILL_ALL (SAM_FILL_NAME | SAM_FILL_INFO3 | SAM_FILL_SAM | SAM_FILL_UNIX)
|
#define SAM_FILL_ALL (SAM_FILL_NAME | SAM_FILL_INFO3 | SAM_FILL_SAM | SAM_FILL_UNIX)
|
||||||
|
|
||||||
typedef struct serversupplied_info
|
typedef struct auth_serversupplied_info
|
||||||
{
|
{
|
||||||
BOOL guest;
|
BOOL guest;
|
||||||
|
|
||||||
@ -91,7 +91,7 @@ typedef struct serversupplied_info
|
|||||||
|
|
||||||
} auth_serversupplied_info;
|
} auth_serversupplied_info;
|
||||||
|
|
||||||
typedef struct authsupplied_info {
|
struct auth_context {
|
||||||
DATA_BLOB challenge;
|
DATA_BLOB challenge;
|
||||||
|
|
||||||
/* Who set this up in the first place? */
|
/* Who set this up in the first place? */
|
||||||
@ -100,22 +100,30 @@ typedef struct authsupplied_info {
|
|||||||
struct auth_methods *challenge_set_method;
|
struct auth_methods *challenge_set_method;
|
||||||
/* What order are the various methods in? Try to stop it changing under us */
|
/* What order are the various methods in? Try to stop it changing under us */
|
||||||
struct auth_methods *auth_method_list;
|
struct auth_methods *auth_method_list;
|
||||||
} auth_authsupplied_info;
|
|
||||||
|
TALLOC_CTX *mem_ctx;
|
||||||
|
const uint8 *(*get_ntlm_challenge)(struct auth_context *auth_context);
|
||||||
|
NTSTATUS (*check_ntlm_password)(const struct auth_context *auth_context,
|
||||||
|
const struct auth_usersupplied_info *user_info,
|
||||||
|
struct auth_serversupplied_info **server_info);
|
||||||
|
NTSTATUS (*nt_status_squash)(NTSTATUS nt_status);
|
||||||
|
void (*free)(struct auth_context **auth_context);
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct auth_methods
|
typedef struct auth_methods
|
||||||
{
|
{
|
||||||
struct auth_methods *prev, *next;
|
struct auth_methods *prev, *next;
|
||||||
char *name; /* What name got this module */
|
char *name; /* What name got this module */
|
||||||
|
|
||||||
NTSTATUS (*auth)(void *my_private_data,
|
NTSTATUS (*auth)(const struct auth_context *auth_context,
|
||||||
|
void *my_private_data,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
const auth_usersupplied_info *user_info,
|
const struct auth_usersupplied_info *user_info,
|
||||||
const struct authsupplied_info *auth_info,
|
|
||||||
auth_serversupplied_info **server_info);
|
auth_serversupplied_info **server_info);
|
||||||
|
|
||||||
DATA_BLOB (*get_chal)(void **my_private_data,
|
DATA_BLOB (*get_chal)(const struct auth_context *auth_context,
|
||||||
TALLOC_CTX *mem_ctx,
|
void **my_private_data,
|
||||||
const struct authsupplied_info *auth_info);
|
TALLOC_CTX *mem_ctx);
|
||||||
|
|
||||||
/* Used to keep tabs on things like the cli for SMB server authentication */
|
/* Used to keep tabs on things like the cli for SMB server authentication */
|
||||||
void *private_data;
|
void *private_data;
|
||||||
@ -128,11 +136,11 @@ typedef struct auth_methods
|
|||||||
|
|
||||||
} auth_methods;
|
} auth_methods;
|
||||||
|
|
||||||
typedef struct auth_init_function {
|
struct auth_init_function {
|
||||||
char *name;
|
char *name;
|
||||||
/* Function to create a member of the authmethods list */
|
/* Function to create a member of the authmethods list */
|
||||||
BOOL (*init)(struct auth_methods **auth_method);
|
BOOL (*init)(struct auth_context *auth_context, struct auth_methods **auth_method);
|
||||||
} auth_init_function;
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* _SMBAUTH_H_ */
|
#endif /* _SMBAUTH_H_ */
|
||||||
|
@ -568,19 +568,24 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
|
|||||||
switch (ctr->switch_value) {
|
switch (ctr->switch_value) {
|
||||||
case NET_LOGON_TYPE:
|
case NET_LOGON_TYPE:
|
||||||
{
|
{
|
||||||
auth_authsupplied_info *auth_info = NULL;
|
struct auth_context *auth_context = NULL;
|
||||||
make_auth_info_fixed(&auth_info, ctr->auth.id2.lm_chal);
|
if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) {
|
||||||
/* Standard challenge/response authenticaion */
|
return status;
|
||||||
make_user_info_netlogon_network(&user_info,
|
}
|
||||||
nt_username, nt_domain,
|
|
||||||
nt_workstation,
|
|
||||||
ctr->auth.id2.lm_chal_resp.buffer,
|
|
||||||
ctr->auth.id2.lm_chal_resp.str_str_len,
|
|
||||||
ctr->auth.id2.nt_chal_resp.buffer,
|
|
||||||
ctr->auth.id2.nt_chal_resp.str_str_len);
|
|
||||||
|
|
||||||
status = check_password(user_info, auth_info, &server_info);
|
/* Standard challenge/response authenticaion */
|
||||||
free_auth_info(&auth_info);
|
if (!make_user_info_netlogon_network(&user_info,
|
||||||
|
nt_username, nt_domain,
|
||||||
|
nt_workstation,
|
||||||
|
ctr->auth.id2.lm_chal_resp.buffer,
|
||||||
|
ctr->auth.id2.lm_chal_resp.str_str_len,
|
||||||
|
ctr->auth.id2.nt_chal_resp.buffer,
|
||||||
|
ctr->auth.id2.nt_chal_resp.str_str_len)) {
|
||||||
|
status = NT_STATUS_NO_MEMORY;
|
||||||
|
} else {
|
||||||
|
status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
|
||||||
|
}
|
||||||
|
auth_context->free(&auth_context);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -590,23 +595,26 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
|
|||||||
convert this to chellange/responce for the auth
|
convert this to chellange/responce for the auth
|
||||||
subsystem to chew on */
|
subsystem to chew on */
|
||||||
{
|
{
|
||||||
auth_authsupplied_info *auth_info = NULL;
|
struct auth_context *auth_context = NULL;
|
||||||
DATA_BLOB chal;
|
const uint8 *chal;
|
||||||
if (!make_auth_info_subsystem(&auth_info)) {
|
if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) {
|
||||||
return NT_STATUS_NO_MEMORY;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
chal = auth_get_challenge(auth_info);
|
chal = auth_context->get_ntlm_challenge(auth_context);
|
||||||
|
|
||||||
make_user_info_netlogon_interactive(&user_info,
|
if (!make_user_info_netlogon_interactive(&user_info,
|
||||||
nt_username, nt_domain,
|
nt_username, nt_domain,
|
||||||
nt_workstation, chal.data,
|
nt_workstation, chal,
|
||||||
ctr->auth.id1.lm_owf.data,
|
ctr->auth.id1.lm_owf.data,
|
||||||
ctr->auth.id1.nt_owf.data,
|
ctr->auth.id1.nt_owf.data,
|
||||||
p->dc.sess_key);
|
p->dc.sess_key)) {
|
||||||
status = check_password(user_info, auth_info, &server_info);
|
status = NT_STATUS_NO_MEMORY;
|
||||||
data_blob_free(&chal);
|
} else {
|
||||||
free_auth_info(&auth_info);
|
status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
auth_context->free(&auth_context);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -270,8 +270,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
|
|||||||
|
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
|
|
||||||
|
struct auth_context *auth_context = NULL;
|
||||||
auth_usersupplied_info *user_info = NULL;
|
auth_usersupplied_info *user_info = NULL;
|
||||||
auth_authsupplied_info *auth_info = NULL;
|
|
||||||
auth_serversupplied_info *server_info = NULL;
|
auth_serversupplied_info *server_info = NULL;
|
||||||
|
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
@ -345,7 +345,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
make_auth_info_fixed(&auth_info, (uchar*)p->challenge);
|
make_auth_context_fixed(&auth_context, (uchar*)p->challenge);
|
||||||
|
|
||||||
if (!make_user_info_netlogon_network(&user_info,
|
if (!make_user_info_netlogon_network(&user_info,
|
||||||
user_name, domain, wks,
|
user_name, domain, wks,
|
||||||
@ -355,9 +355,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
|
|||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
nt_status = check_password(user_info, auth_info, &server_info);
|
nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
|
||||||
|
|
||||||
free_auth_info(&auth_info);
|
auth_context->free(&auth_context);
|
||||||
free_user_info(&user_info);
|
free_user_info(&user_info);
|
||||||
|
|
||||||
p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
|
p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
|
||||||
|
@ -27,7 +27,28 @@ extern fstring global_myworkgroup;
|
|||||||
extern fstring remote_machine;
|
extern fstring remote_machine;
|
||||||
BOOL global_encrypted_passwords_negotiated = False;
|
BOOL global_encrypted_passwords_negotiated = False;
|
||||||
BOOL global_spnego_negotiated = False;
|
BOOL global_spnego_negotiated = False;
|
||||||
auth_authsupplied_info *negprot_global_auth_info = NULL;
|
struct auth_context *negprot_global_auth_context = NULL;
|
||||||
|
|
||||||
|
static void get_challange(char buff[8])
|
||||||
|
{
|
||||||
|
NTSTATUS nt_status;
|
||||||
|
const uint8 *cryptkey;
|
||||||
|
|
||||||
|
/* We might be called more than once, muliple negprots are premitted */
|
||||||
|
if (negprot_global_auth_context) {
|
||||||
|
DEBUG(3, ("get challange: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
|
||||||
|
negprot_global_auth_context->free(&negprot_global_auth_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG(10, ("get challange: creating negprot_global_auth_context\n"));
|
||||||
|
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
|
||||||
|
DEBUG(0, ("make_auth_context_subsystem returned %s", get_nt_error_msg(nt_status)));
|
||||||
|
smb_panic("cannot make_negprot_global_auth_context!\n");
|
||||||
|
}
|
||||||
|
DEBUG(10, ("get challange: getting challange\n"));
|
||||||
|
cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context);
|
||||||
|
memcpy(buff, cryptkey, 8);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
reply for the core protocol
|
reply for the core protocol
|
||||||
@ -69,7 +90,6 @@ static int reply_lanman1(char *inbuf, char *outbuf)
|
|||||||
int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
|
int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
|
||||||
int secword=0;
|
int secword=0;
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
DATA_BLOB cryptkey;
|
|
||||||
|
|
||||||
global_encrypted_passwords_negotiated = lp_encrypted_passwords();
|
global_encrypted_passwords_negotiated = lp_encrypted_passwords();
|
||||||
|
|
||||||
@ -80,12 +100,7 @@ static int reply_lanman1(char *inbuf, char *outbuf)
|
|||||||
SSVAL(outbuf,smb_vwv1,secword);
|
SSVAL(outbuf,smb_vwv1,secword);
|
||||||
/* Create a token value and add it to the outgoing packet. */
|
/* Create a token value and add it to the outgoing packet. */
|
||||||
if (global_encrypted_passwords_negotiated) {
|
if (global_encrypted_passwords_negotiated) {
|
||||||
if (!make_auth_info_subsystem(&negprot_global_auth_info)) {
|
get_challange(smb_buf(outbuf));
|
||||||
smb_panic("cannot make_negprot_global_auth_info!\n");
|
|
||||||
}
|
|
||||||
cryptkey = auth_get_challenge(negprot_global_auth_info);
|
|
||||||
memcpy(smb_buf(outbuf), cryptkey.data, 8);
|
|
||||||
data_blob_free(&cryptkey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol = PROTOCOL_LANMAN1;
|
Protocol = PROTOCOL_LANMAN1;
|
||||||
@ -114,7 +129,6 @@ static int reply_lanman2(char *inbuf, char *outbuf)
|
|||||||
int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
|
int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
|
||||||
int secword=0;
|
int secword=0;
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
DATA_BLOB cryptkey;
|
|
||||||
|
|
||||||
global_encrypted_passwords_negotiated = lp_encrypted_passwords();
|
global_encrypted_passwords_negotiated = lp_encrypted_passwords();
|
||||||
|
|
||||||
@ -125,13 +139,9 @@ static int reply_lanman2(char *inbuf, char *outbuf)
|
|||||||
SSVAL(outbuf,smb_vwv1,secword);
|
SSVAL(outbuf,smb_vwv1,secword);
|
||||||
SIVAL(outbuf,smb_vwv6,sys_getpid());
|
SIVAL(outbuf,smb_vwv6,sys_getpid());
|
||||||
|
|
||||||
|
/* Create a token value and add it to the outgoing packet. */
|
||||||
if (global_encrypted_passwords_negotiated) {
|
if (global_encrypted_passwords_negotiated) {
|
||||||
if (!make_auth_info_subsystem(&negprot_global_auth_info)) {
|
get_challange(smb_buf(outbuf));
|
||||||
smb_panic("cannot make_negprot_global_auth_info!\n");
|
|
||||||
}
|
|
||||||
cryptkey = auth_get_challenge(negprot_global_auth_info);
|
|
||||||
memcpy(smb_buf(outbuf), cryptkey.data, 8);
|
|
||||||
data_blob_free(&cryptkey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol = PROTOCOL_LANMAN2;
|
Protocol = PROTOCOL_LANMAN2;
|
||||||
@ -216,7 +226,6 @@ static int reply_nt1(char *inbuf, char *outbuf)
|
|||||||
|
|
||||||
int secword=0;
|
int secword=0;
|
||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
DATA_BLOB cryptkey;
|
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
BOOL negotiate_spnego = False;
|
BOOL negotiate_spnego = False;
|
||||||
|
|
||||||
@ -275,13 +284,9 @@ static int reply_nt1(char *inbuf, char *outbuf)
|
|||||||
|
|
||||||
p = q = smb_buf(outbuf);
|
p = q = smb_buf(outbuf);
|
||||||
if (!negotiate_spnego) {
|
if (!negotiate_spnego) {
|
||||||
if (global_encrypted_passwords_negotiated) {
|
/* Create a token value and add it to the outgoing packet. */
|
||||||
if (!make_auth_info_subsystem(&negprot_global_auth_info)) {
|
if (global_encrypted_passwords_negotiated) {
|
||||||
smb_panic("cannot make_negprot_global_auth_info!\n");
|
get_challange(p);
|
||||||
}
|
|
||||||
cryptkey = auth_get_challenge(negprot_global_auth_info);
|
|
||||||
memcpy(p, cryptkey.data, 8);
|
|
||||||
data_blob_free(&cryptkey);
|
|
||||||
}
|
}
|
||||||
SSVALS(outbuf,smb_vwv16+1,8);
|
SSVALS(outbuf,smb_vwv16+1,8);
|
||||||
p += 8;
|
p += 8;
|
||||||
|
@ -1112,7 +1112,7 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
|
|||||||
|
|
||||||
if (keepalive && (t - last_keepalive_sent_time)>keepalive)
|
if (keepalive && (t - last_keepalive_sent_time)>keepalive)
|
||||||
{
|
{
|
||||||
extern auth_authsupplied_info *negprot_global_auth_info;
|
extern struct auth_context *negprot_global_auth_context;
|
||||||
if (!send_keepalive(smbd_server_fd())) {
|
if (!send_keepalive(smbd_server_fd())) {
|
||||||
DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
|
DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
|
||||||
return False;
|
return False;
|
||||||
@ -1121,11 +1121,11 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
|
|||||||
/* send a keepalive for a password server or the like.
|
/* send a keepalive for a password server or the like.
|
||||||
This is attached to the auth_info created in the
|
This is attached to the auth_info created in the
|
||||||
negprot */
|
negprot */
|
||||||
if (negprot_global_auth_info
|
if (negprot_global_auth_context
|
||||||
&& negprot_global_auth_info->challenge_set_method
|
&& negprot_global_auth_context->challenge_set_method
|
||||||
&& negprot_global_auth_info->challenge_set_method->send_keepalive) {
|
&& negprot_global_auth_context->challenge_set_method->send_keepalive) {
|
||||||
negprot_global_auth_info->challenge_set_method->send_keepalive
|
negprot_global_auth_context->challenge_set_method->send_keepalive
|
||||||
(&negprot_global_auth_info->challenge_set_method->private_data);
|
(&negprot_global_auth_context->challenge_set_method->private_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
last_keepalive_sent_time = t;
|
last_keepalive_sent_time = t;
|
||||||
|
@ -475,7 +475,7 @@ void exit_server(char *reason)
|
|||||||
{
|
{
|
||||||
static int firsttime=1;
|
static int firsttime=1;
|
||||||
extern char *last_inbuf;
|
extern char *last_inbuf;
|
||||||
extern auth_authsupplied_info *negprot_global_auth_info;
|
extern struct auth_context *negprot_global_auth_context;
|
||||||
|
|
||||||
if (!firsttime)
|
if (!firsttime)
|
||||||
exit(0);
|
exit(0);
|
||||||
@ -484,7 +484,9 @@ void exit_server(char *reason)
|
|||||||
change_to_root_user();
|
change_to_root_user();
|
||||||
DEBUG(2,("Closing connections\n"));
|
DEBUG(2,("Closing connections\n"));
|
||||||
|
|
||||||
free_auth_info(&negprot_global_auth_info);
|
if (negprot_global_auth_context) {
|
||||||
|
negprot_global_auth_context->free(&negprot_global_auth_context);
|
||||||
|
}
|
||||||
|
|
||||||
conn_close_all();
|
conn_close_all();
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
uint32 global_client_caps = 0;
|
uint32 global_client_caps = 0;
|
||||||
static auth_authsupplied_info *ntlmssp_auth_info;
|
static struct auth_context *ntlmssp_auth_context;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
on a logon error possibly map the error to success if "map to guest"
|
on a logon error possibly map the error to success if "map to guest"
|
||||||
@ -72,8 +72,7 @@ static void add_signature(char *outbuf)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
|
static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
|
||||||
{
|
{
|
||||||
|
struct auth_context *auth_context;
|
||||||
auth_authsupplied_info *auth_info;
|
|
||||||
auth_usersupplied_info *user_info = NULL;
|
auth_usersupplied_info *user_info = NULL;
|
||||||
|
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
@ -83,11 +82,17 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
|
|||||||
|
|
||||||
DEBUG(3,("Got anonymous request\n"));
|
DEBUG(3,("Got anonymous request\n"));
|
||||||
|
|
||||||
make_user_info_guest(&user_info);
|
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) {
|
||||||
make_auth_info_fixed(&auth_info, chal);
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!make_user_info_guest(&user_info)) {
|
||||||
|
auth_context->free(&auth_context);
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
nt_status = check_password(user_info, auth_info, server_info);
|
nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info);
|
||||||
free_auth_info(&auth_info);
|
auth_context->free(&auth_context);
|
||||||
free_user_info(&user_info);
|
free_user_info(&user_info);
|
||||||
return nt_status;
|
return nt_status;
|
||||||
}
|
}
|
||||||
@ -233,8 +238,9 @@ static int reply_spnego_negotiate(connection_struct *conn,
|
|||||||
int i;
|
int i;
|
||||||
uint32 ntlmssp_command, neg_flags;
|
uint32 ntlmssp_command, neg_flags;
|
||||||
DATA_BLOB sess_key, chal, spnego_chal;
|
DATA_BLOB sess_key, chal, spnego_chal;
|
||||||
DATA_BLOB cryptkey;
|
const uint8 *cryptkey;
|
||||||
BOOL got_kerberos = False;
|
BOOL got_kerberos = False;
|
||||||
|
NTSTATUS nt_status;
|
||||||
|
|
||||||
/* parse out the OIDs and the first sec blob */
|
/* parse out the OIDs and the first sec blob */
|
||||||
if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
|
if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
|
||||||
@ -282,11 +288,15 @@ static int reply_spnego_negotiate(connection_struct *conn,
|
|||||||
|
|
||||||
DEBUG(3,("Got neg_flags=%08x\n", neg_flags));
|
DEBUG(3,("Got neg_flags=%08x\n", neg_flags));
|
||||||
|
|
||||||
if (!make_auth_info_subsystem(&ntlmssp_auth_info)) {
|
if (!ntlmssp_auth_context) {
|
||||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
ntlmssp_auth_context->free(&ntlmssp_auth_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
cryptkey = auth_get_challenge(ntlmssp_auth_info);
|
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&ntlmssp_auth_context))) {
|
||||||
|
return ERROR_NT(nt_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
cryptkey = ntlmssp_auth_context->get_ntlm_challenge(ntlmssp_auth_context);
|
||||||
|
|
||||||
/* Give them the challenge. For now, ignore neg_flags and just
|
/* Give them the challenge. For now, ignore neg_flags and just
|
||||||
return the flags we want. Obviously this is not correct */
|
return the flags we want. Obviously this is not correct */
|
||||||
@ -301,7 +311,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
|
|||||||
0,
|
0,
|
||||||
0x30, /* ?? */
|
0x30, /* ?? */
|
||||||
neg_flags,
|
neg_flags,
|
||||||
cryptkey.data, cryptkey.length,
|
cryptkey, sizeof(cryptkey),
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
0x3000); /* ?? */
|
0x3000); /* ?? */
|
||||||
|
|
||||||
@ -314,7 +324,6 @@ static int reply_spnego_negotiate(connection_struct *conn,
|
|||||||
reply_sesssetup_blob(conn, outbuf, spnego_chal);
|
reply_sesssetup_blob(conn, outbuf, spnego_chal);
|
||||||
|
|
||||||
data_blob_free(&chal);
|
data_blob_free(&chal);
|
||||||
data_blob_free(&cryptkey);
|
|
||||||
data_blob_free(&spnego_chal);
|
data_blob_free(&spnego_chal);
|
||||||
|
|
||||||
/* and tell smbd that we have already replied to this packet */
|
/* and tell smbd that we have already replied to this packet */
|
||||||
@ -382,7 +391,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
|
|||||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
nt_status = check_password(user_info, ntlmssp_auth_info, &server_info);
|
nt_status = ntlmssp_auth_context->check_ntlm_password(ntlmssp_auth_context, user_info, &server_info);
|
||||||
|
|
||||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||||
nt_status = do_map_to_guest(nt_status, &server_info, user, workgroup);
|
nt_status = do_map_to_guest(nt_status, &server_info, user, workgroup);
|
||||||
@ -391,7 +400,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
|
|||||||
SAFE_FREE(workgroup);
|
SAFE_FREE(workgroup);
|
||||||
SAFE_FREE(machine);
|
SAFE_FREE(machine);
|
||||||
|
|
||||||
free_auth_info(&ntlmssp_auth_info);
|
ntlmssp_auth_context->free(&ntlmssp_auth_context);
|
||||||
|
|
||||||
free_user_info(&user_info);
|
free_user_info(&user_info);
|
||||||
|
|
||||||
@ -544,7 +553,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
|
|||||||
extern int max_send;
|
extern int max_send;
|
||||||
|
|
||||||
auth_usersupplied_info *user_info = NULL;
|
auth_usersupplied_info *user_info = NULL;
|
||||||
extern auth_authsupplied_info *negprot_global_auth_info;
|
extern struct auth_context *negprot_global_auth_context;
|
||||||
auth_serversupplied_info *server_info = NULL;
|
auth_serversupplied_info *server_info = NULL;
|
||||||
|
|
||||||
NTSTATUS nt_status;
|
NTSTATUS nt_status;
|
||||||
@ -671,13 +680,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
|
|||||||
|
|
||||||
DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
|
DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
|
||||||
|
|
||||||
if (*user) {
|
|
||||||
if (global_spnego_negotiated) {
|
|
||||||
DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
|
|
||||||
return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*user) {
|
if (*user) {
|
||||||
pstrcpy(sub_user, user);
|
pstrcpy(sub_user, user);
|
||||||
} else {
|
} else {
|
||||||
@ -702,37 +704,46 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!*user) {
|
if (!*user) {
|
||||||
|
if (global_spnego_negotiated) {
|
||||||
|
|
||||||
|
/* This has to be here, becouse this is a perfectly valid behaviour for guest logons :-( */
|
||||||
|
|
||||||
|
DEBUG(0,("reply_sesssetup_and_X: Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
|
||||||
|
return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
|
||||||
|
}
|
||||||
|
|
||||||
nt_status = check_guest_password(&server_info);
|
nt_status = check_guest_password(&server_info);
|
||||||
|
|
||||||
} else if (doencrypt) {
|
} else if (doencrypt) {
|
||||||
if (!make_user_info_for_reply_enc(&user_info,
|
if (!make_user_info_for_reply_enc(&user_info,
|
||||||
user, domain,
|
user, domain,
|
||||||
lm_resp, nt_resp,
|
lm_resp, nt_resp)) {
|
||||||
plaintext_password)) {
|
nt_status = NT_STATUS_NO_MEMORY;
|
||||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
} else {
|
||||||
|
nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context,
|
||||||
|
user_info,
|
||||||
|
&server_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
nt_status = check_password(user_info, negprot_global_auth_info, &server_info);
|
|
||||||
} else {
|
} else {
|
||||||
auth_authsupplied_info *plaintext_auth_info = NULL;
|
struct auth_context *plaintext_auth_context = NULL;
|
||||||
DATA_BLOB chal;
|
const uint8 *chal;
|
||||||
if (!make_auth_info_subsystem(&plaintext_auth_info)) {
|
if (NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
|
||||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
|
||||||
}
|
|
||||||
|
if (!make_user_info_for_reply(&user_info,
|
||||||
chal = auth_get_challenge(plaintext_auth_info);
|
user, domain, chal,
|
||||||
|
plaintext_password)) {
|
||||||
if (!make_user_info_for_reply(&user_info,
|
nt_status = NT_STATUS_NO_MEMORY;
|
||||||
user, domain, chal.data,
|
}
|
||||||
plaintext_password)) {
|
|
||||||
return ERROR_NT(NT_STATUS_NO_MEMORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
nt_status = check_password(user_info, plaintext_auth_info, &server_info);
|
if (NT_STATUS_IS_OK(nt_status)) {
|
||||||
|
nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context,
|
||||||
data_blob_free(&chal);
|
user_info,
|
||||||
free_auth_info(&plaintext_auth_info);
|
&server_info);
|
||||||
|
|
||||||
|
plaintext_auth_context->free(&plaintext_auth_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_user_info(&user_info);
|
free_user_info(&user_info);
|
||||||
|
Loading…
Reference in New Issue
Block a user