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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "auth/auth.h"
+#include "system/network.h"
#include "auth/ntlmssp/ntlmssp.h"
-#include "auth/ntlmssp/msrpc_parse.h"
-#include "lib/crypto/crypto.h"
-#include "pstring.h"
-#include "system/filesys.h"
-#include "libcli/auth/libcli_auth.h"
+#include "../librpc/gen_ndr/ntlmssp.h"
+#include "../libcli/auth/libcli_auth.h"
+#include "../lib/crypto/crypto.h"
+#include "auth/gensec/gensec.h"
+#include "auth/auth.h"
+#include "auth/ntlm/auth_proto.h"
+#include "param/param.h"
+#include "auth/session_proto.h"
/**
* Set a username on an NTLMSSP context - ensures it is talloc()ed
uint32_t neg_flags, uint32_t *chal_flags)
{
if (neg_flags & NTLMSSP_REQUEST_TARGET) {
- *chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
+ *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
*chal_flags |= NTLMSSP_REQUEST_TARGET;
if (gensec_ntlmssp_state->server_role == ROLE_STANDALONE) {
*chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
return gensec_ntlmssp_state->server_name;
} else {
*chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
- return gensec_ntlmssp_state->get_domain();
+ return gensec_ntlmssp_state->domain;
};
} else {
return "";
}
}
-/*
- Andrew, please remove these totally bogus calls when you get time
-*/
-static BOOL get_myfullname(char *my_name)
-{
- pstring hostname;
-
- *hostname = 0;
-
- /* get my host name */
- if (gethostname(hostname, sizeof(hostname)) == -1) {
- DEBUG(0,("gethostname failed\n"));
- return False;
- }
-
- /* Ensure null termination. */
- hostname[sizeof(hostname)-1] = '\0';
-
- if (my_name)
- fstrcpy(my_name, hostname);
- return True;
-}
-
-static BOOL get_mydomname(char *my_domname)
-{
- pstring hostname;
- char *p;
-
- /* arrgh! relies on full name in system */
-
- *hostname = 0;
- /* get my host name */
- if (gethostname(hostname, sizeof(hostname)) == -1) {
- DEBUG(0,("gethostname failed\n"));
- return False;
- }
-
- /* Ensure null termination. */
- hostname[sizeof(hostname)-1] = '\0';
-
- p = strchr_m(hostname, '.');
-
- if (!p)
- return False;
-
- p++;
-
- if (my_domname)
- fstrcpy(my_domname, p);
-
- return True;
-}
-
/**
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out)
{
- struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+ struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
DATA_BLOB struct_blob;
- fstring dnsname, dnsdomname;
uint32_t neg_flags = 0;
uint32_t ntlmssp_command, chal_flags;
const uint8_t *cryptkey;
#endif
if (in.length) {
- if ((in.length < 16) || !msrpc_parse(out_mem_ctx, &in, "Cdd",
+ if ((in.length < 16) || !msrpc_parse(out_mem_ctx,
+ &in, "Cdd",
"NTLMSSP",
&ntlmssp_command,
&neg_flags)) {
/* Ask our caller what challenge they would like in the packet */
cryptkey = gensec_ntlmssp_state->get_challenge(gensec_ntlmssp_state);
+ if (!cryptkey) {
+ DEBUG(1, ("ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
+ return NT_STATUS_INTERNAL_ERROR;
+ }
/* Check if we may set the challenge */
if (!gensec_ntlmssp_state->may_set_challenge(gensec_ntlmssp_state)) {
gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
gensec_ntlmssp_state->internal_chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
- /* This should be a 'netbios domain -> DNS domain' mapping */
- dnsdomname[0] = '\0';
- get_mydomname(dnsdomname);
- strlower_m(dnsdomname);
-
- dnsname[0] = '\0';
- get_myfullname(dnsname);
-
/* This creates the 'blob' of names that appears at the end of the packet */
- if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
- {
+ if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
+ char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN];
const char *target_name_dns = "";
+
+ /* Find out the DNS domain name */
+ dnsdomname[0] = '\0';
+ safe_strcpy(dnsdomname, lp_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
+
+ /* Find out the DNS host name */
+ safe_strcpy(dnsname, gensec_ntlmssp_state->server_name, sizeof(dnsname) - 1);
+ if (dnsdomname[0] != '\0') {
+ safe_strcat(dnsname, ".", sizeof(dnsname) - 1);
+ safe_strcat(dnsname, dnsdomname, sizeof(dnsname) - 1);
+ }
+ strlower_m(dnsname);
+
if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
target_name_dns = dnsdomname;
} else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
msrpc_gen(out_mem_ctx,
&struct_blob, "aaaaa",
- NTLMSSP_NAME_TYPE_DOMAIN, target_name,
- NTLMSSP_NAME_TYPE_SERVER, gensec_ntlmssp_state->server_name,
- NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
- NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
- 0, "");
+ MsvAvNbDomainName, target_name,
+ MsvAvNbComputerName, gensec_ntlmssp_state->server_name,
+ MsvAvDnsDomainName, dnsdomname,
+ MsvAvDnsComputerName, dnsname,
+ MsvAvEOL, "");
} else {
struct_blob = data_blob(NULL, 0);
}
{
- /* Marshel the packet in the right format, be it unicode or ASCII */
+ /* Marshal the packet in the right format, be it unicode or ASCII */
const char *gen_string;
if (gensec_ntlmssp_state->unicode) {
gen_string = "CdUdbddB";
SMB_ASSERT(gensec_ntlmssp_state->internal_chal.data
&& gensec_ntlmssp_state->internal_chal.length == 8);
- gensec_ntlmssp_state->doing_ntlm2 = True;
+ gensec_ntlmssp_state->doing_ntlm2 = true;
memcpy(gensec_ntlmssp_state->crypt.ntlm2.session_nonce, gensec_ntlmssp_state->internal_chal.data, 8);
memcpy(&gensec_ntlmssp_state->crypt.ntlm2.session_nonce[8], gensec_ntlmssp_state->lm_resp.data, 8);
DATA_BLOB *user_session_key,
DATA_BLOB *lm_session_key)
{
- struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+ struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
NTSTATUS nt_status;
DATA_BLOB session_key = data_blob(NULL, 0);
}
} else if (user_session_key && user_session_key->data) {
- session_key = *user_session_key;
+ session_key = data_blob_talloc(gensec_ntlmssp_state, user_session_key->data, user_session_key->length);
DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
} else if (lm_session_key && lm_session_key->data) {
/* Very weird to have LM key, but no user session key, but anyway.. */
- session_key = *lm_session_key;
+ session_key = data_blob_talloc(gensec_ntlmssp_state, lm_session_key->data, lm_session_key->length);
DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
gensec_ntlmssp_state->encrypted_session_key.length);
dump_data_pw("KEY_EXCH session key:\n", gensec_ntlmssp_state->encrypted_session_key.data,
gensec_ntlmssp_state->encrypted_session_key.length);
+ talloc_free(session_key.data);
}
} else {
gensec_ntlmssp_state->session_key = session_key;
}
- /* keep the session key around on the new context */
- talloc_steal(gensec_ntlmssp_state, session_key.data);
-
if ((gensec_security->want_features & GENSEC_FEATURE_SIGN)
|| (gensec_security->want_features & GENSEC_FEATURE_SEAL)) {
nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out)
{
- struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+ struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
DATA_BLOB user_session_key = data_blob(NULL, 0);
DATA_BLOB lm_session_key = data_blob(NULL, 0);
NTSTATUS nt_status;
NTSTATUS status;
const uint8_t *chal;
- status = auth_get_challenge(gensec_ntlmssp_state->auth_context, &chal);
+ status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, &chal);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
+ nt_errstr(status)));
return NULL;
}
*
* @return If the effective challenge used by the auth subsystem may be modified
*/
-static BOOL auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
+static bool auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
{
- return auth_challenge_may_be_modified(gensec_ntlmssp_state->auth_context);
+ return gensec_ntlmssp_state->auth_context->challenge_may_be_modified(gensec_ntlmssp_state->auth_context);
}
/**
chal = challenge->data;
- nt_status = auth_context_set_challenge(auth_context, chal, "NTLMSSP callback (NTLM2)");
+ nt_status = gensec_ntlmssp_state->auth_context->set_challenge(auth_context,
+ chal,
+ "NTLMSSP callback (NTLM2)");
return nt_status;
}
user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
user_info->flags = 0;
- user_info->mapped_state = False;
+ user_info->mapped_state = false;
user_info->client.account_name = gensec_ntlmssp_state->user;
user_info->client.domain_name = gensec_ntlmssp_state->domain;
user_info->workstation_name = gensec_ntlmssp_state->workstation;
user_info->password.response.nt = gensec_ntlmssp_state->nt_resp;
user_info->password.response.nt.data = talloc_steal(user_info, gensec_ntlmssp_state->nt_resp.data);
- nt_status = auth_check_password(gensec_ntlmssp_state->auth_context, mem_ctx,
- user_info, &gensec_ntlmssp_state->server_info);
+ nt_status = gensec_ntlmssp_state->auth_context->check_password(gensec_ntlmssp_state->auth_context,
+ mem_ctx,
+ user_info,
+ &gensec_ntlmssp_state->server_info);
talloc_free(user_info);
NT_STATUS_NOT_OK_RETURN(nt_status);
struct auth_session_info **session_info)
{
NTSTATUS nt_status;
- struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+ struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
- nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info, session_info);
+ nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, gensec_ntlmssp_state->server_info, session_info);
NT_STATUS_NOT_OK_RETURN(nt_status);
(*session_info)->session_key = data_blob_talloc(*session_info,
nt_status = gensec_ntlmssp_start(gensec_security);
NT_STATUS_NOT_OK_RETURN(nt_status);
- gensec_ntlmssp_state = gensec_security->private_data;
+ gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
gensec_ntlmssp_state->role = NTLMSSP_SERVER;
gensec_ntlmssp_state->workstation = NULL;
- gensec_ntlmssp_state->server_name = lp_netbios_name();
+ gensec_ntlmssp_state->server_name = lp_netbios_name(gensec_security->settings->lp_ctx);
- gensec_ntlmssp_state->get_domain = lp_workgroup;
+ gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx);
gensec_ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
- gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth()
- && lp_parm_bool(-1, "ntlmssp_server", "allow_lm_key", False));
+ gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth(gensec_security->settings->lp_ctx)
+ && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));
- gensec_ntlmssp_state->server_multiple_authentications = False;
+ gensec_ntlmssp_state->server_multiple_authentications = false;
gensec_ntlmssp_state->neg_flags =
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_UNKNOWN_02000000;
+ NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;
gensec_ntlmssp_state->lm_resp = data_blob(NULL, 0);
gensec_ntlmssp_state->nt_resp = data_blob(NULL, 0);
gensec_ntlmssp_state->encrypted_session_key = data_blob(NULL, 0);
- if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
+ if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
}
- if (lp_parm_bool(-1, "ntlmssp_server", "56bit", True)) {
+ if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
}
- if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
+ if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
}
- if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
+ if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
+ gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+ }
+
+ if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
}
gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
}
- nt_status = auth_context_create(gensec_ntlmssp_state, lp_auth_methods(),
- &gensec_ntlmssp_state->auth_context,
- gensec_security->event_ctx);
- NT_STATUS_NOT_OK_RETURN(nt_status);
+ gensec_ntlmssp_state->auth_context = gensec_security->auth_context;
gensec_ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
gensec_ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
gensec_ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
gensec_ntlmssp_state->check_password = auth_ntlmssp_check_password;
- gensec_ntlmssp_state->server_role = lp_server_role();
+ gensec_ntlmssp_state->server_role = lp_server_role(gensec_security->settings->lp_ctx);
return NT_STATUS_OK;
}