*/
#include "includes.h"
+#include "auth/auth.h"
+#include "lib/crypto/crypto.h"
static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
TALLOC_CTX *out_mem_ctx,
*/
static const struct ntlmssp_callbacks {
- enum NTLMSSP_ROLE role;
- enum NTLM_MESSAGE_TYPE ntlmssp_command;
+ enum ntlmssp_role role;
+ enum ntlmssp_message_type ntlmssp_command;
NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state,
TALLOC_CTX *out_mem_ctx,
DATA_BLOB in, DATA_BLOB *out);
* @param neg_flags The flags from the packet
*/
-void debug_ntlmssp_flags(uint32 neg_flags)
+void debug_ntlmssp_flags(uint32_t neg_flags)
{
DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
*
*/
-static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state)
+static const uint8_t *get_challenge(const struct ntlmssp_state *ntlmssp_state)
{
- static uchar chal[8];
- generate_random_buffer(chal, sizeof(chal), False);
+ uint8_t *chal = talloc(ntlmssp_state, 8);
+ generate_random_buffer(chal, 8);
return chal;
}
*
*/
-NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user)
+NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user)
{
- ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user);
+ ntlmssp_state->user = talloc_strdup(ntlmssp_state, user);
if (!ntlmssp_state->user) {
return NT_STATUS_NO_MEMORY;
}
* Set a password on an NTLMSSP context - ensures it is talloc()ed
*
*/
-NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password)
+NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
{
if (!password) {
ntlmssp_state->password = NULL;
} else {
- ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);
+ ntlmssp_state->password = talloc_strdup(ntlmssp_state, password);
if (!ntlmssp_state->password) {
return NT_STATUS_NO_MEMORY;
}
* Set a domain on an NTLMSSP context - ensures it is talloc()ed
*
*/
-NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain)
+NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain)
{
- ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain);
+ ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
if (!ntlmssp_state->domain) {
return NT_STATUS_NO_MEMORY;
}
* Set a workstation on an NTLMSSP context - ensures it is talloc()ed
*
*/
-NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation)
+NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation)
{
- ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation);
+ ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
if (!ntlmssp_state->domain) {
return NT_STATUS_NO_MEMORY;
}
* This copies the data blob
*/
-NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,
+NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
DATA_BLOB response)
{
- ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx,
+ ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state,
response.data, response.length);
return NT_STATUS_OK;
}
* or NT_STATUS_OK if the user is authenticated.
*/
-NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state,
+NTSTATUS ntlmssp_update(struct ntlmssp_state *ntlmssp_state,
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out)
{
DATA_BLOB input;
- uint32 ntlmssp_command;
+ uint32_t ntlmssp_command;
int i;
*out = data_blob(NULL, 0);
if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
- return NT_STATUS_INVALID_PARAMETER;
+ return NT_STATUS_OK;
}
if (!out_mem_ctx) {
/* if the caller doesn't want to manage/own the memory,
we can put it on our context */
- out_mem_ctx = ntlmssp_state->mem_ctx;
+ out_mem_ctx = ntlmssp_state;
}
if (!in.length && ntlmssp_state->stored_response.length) {
break;
}
} else {
- if (!msrpc_parse(ntlmssp_state->mem_ctx,
+ if (!msrpc_parse(ntlmssp_state,
&input, "Cd",
"NTLMSSP",
&ntlmssp_command)) {
DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));
- dump_data(2, (const char *)input.data, input.length);
+ dump_data(2, input.data, input.length);
return NT_STATUS_INVALID_PARAMETER;
}
}
return NT_STATUS_INVALID_PARAMETER;
}
+/**
+ * Return the NTLMSSP master session key
+ *
+ * @param ntlmssp_state NTLMSSP State
+ */
+
+NTSTATUS ntlmssp_session_key(struct ntlmssp_state *ntlmssp_state,
+ DATA_BLOB *session_key)
+{
+ if (!ntlmssp_state->session_key.data) {
+ return NT_STATUS_NO_USER_SESSION_KEY;
+ }
+ *session_key = ntlmssp_state->session_key;
+
+ return NT_STATUS_OK;
+}
+
/**
* End an NTLMSSP state machine
*
* @param ntlmssp_state NTLMSSP State, free()ed by this function
*/
-void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state)
+void ntlmssp_end(struct ntlmssp_state **ntlmssp_state)
{
- TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;
-
(*ntlmssp_state)->ref_count--;
if ((*ntlmssp_state)->ref_count == 0) {
- talloc_destroy(mem_ctx);
+ talloc_free(*ntlmssp_state);
}
*ntlmssp_state = NULL;
*/
static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
- uint32 neg_flags, uint32 *chal_flags)
+ uint32_t neg_flags, uint32_t *chal_flags)
{
if (neg_flags & NTLMSSP_REQUEST_TARGET) {
*chal_flags |= NTLMSSP_CHAL_TARGET_INFO;
}
static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
- uint32 neg_flags, BOOL allow_lm) {
+ uint32_t neg_flags, BOOL allow_lm) {
if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
}
+ if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
+ }
+
+ if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
+ ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
+ }
+
if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
}
{
DATA_BLOB struct_blob;
fstring dnsname, dnsdomname;
- uint32 neg_flags = 0;
- uint32 ntlmssp_command, chal_flags;
+ uint32_t neg_flags = 0;
+ uint32_t ntlmssp_command, chal_flags;
char *cliname=NULL, *domname=NULL;
- const uint8 *cryptkey;
+ const uint8_t *cryptkey;
const char *target_name;
/* parse the NTLMSSP packet */
#endif
if (in.length) {
- if (!msrpc_parse(ntlmssp_state->mem_ctx,
+ if (!msrpc_parse(ntlmssp_state,
&in, "CddAA",
"NTLMSSP",
&ntlmssp_command,
&cliname,
&domname)) {
DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n"));
- dump_data(2, (const char *)in.data, in.length);
+ dump_data(2, in.data, in.length);
return NT_STATUS_INVALID_PARAMETER;
}
if (target_name == NULL)
return NT_STATUS_INVALID_PARAMETER;
- ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
- ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
+ ntlmssp_state->chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
+ ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state, cryptkey, 8);
/* This should be a 'netbios domain -> DNS domain' mapping */
dnsdomname[0] = '\0';
static NTSTATUS ntlmssp_server_preauth(struct ntlmssp_state *ntlmssp_state,
const DATA_BLOB request)
{
- uint32 ntlmssp_command, auth_flags;
+ uint32_t ntlmssp_command, auth_flags;
NTSTATUS nt_status;
- uchar session_nonce_hash[16];
+ uint8_t session_nonce_hash[16];
const char *parse_string;
char *domain = NULL;
ntlmssp_state->workstation = NULL;
/* now the NTLMSSP encoded auth hashes */
- if (!msrpc_parse(ntlmssp_state->mem_ctx,
+ if (!msrpc_parse(ntlmssp_state,
&request, parse_string,
"NTLMSSP",
&ntlmssp_command,
&ntlmssp_state->encrypted_session_key,
&auth_flags)) {
DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
- dump_data(10, (const char *)request.data, request.length);
+ dump_data(10, request.data, request.length);
/* zero this out */
data_blob_free(&ntlmssp_state->encrypted_session_key);
}
/* now the NTLMSSP encoded auth hashes */
- if (!msrpc_parse(ntlmssp_state->mem_ctx,
+ if (!msrpc_parse(ntlmssp_state,
&request, parse_string,
"NTLMSSP",
&ntlmssp_command,
&user,
&workstation)) {
DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
- dump_data(2, (const char *)request.data, request.length);
+ dump_data(2, request.data, request.length);
return NT_STATUS_INVALID_PARAMETER;
}
MD5Update(&md5_session_nonce_ctx, ntlmssp_state->session_nonce, 16);
MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
- ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx,
+ ntlmssp_state->chal = data_blob_talloc(ntlmssp_state,
session_nonce_hash, 8);
/* LM response is no longer useful, zero it out */
/* Handle the different session key derivation for NTLM2 */
if (ntlmssp_state->doing_ntlm2) {
if (user_session_key && user_session_key->data && user_session_key->length == 16) {
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
hmac_md5(user_session_key->data, ntlmssp_state->session_nonce,
sizeof(ntlmssp_state->session_nonce), session_key.data);
DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
SMBsesskeygen_lm_sess_key(lm_session_key->data, ntlmssp_state->lm_resp.data,
session_key.data);
DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
} else {
/* When there is no LM response, just use zeros */
- static const uchar zeros[24];
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ static const uint8_t zeros[24];
+ session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
SMBsesskeygen_lm_sess_key(zeros, zeros,
session_key.data);
DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
dump_data_pw("KEY_EXCH session key (enc):\n",
ntlmssp_state->encrypted_session_key.data,
ntlmssp_state->encrypted_session_key.length);
- SamOEMhash(ntlmssp_state->encrypted_session_key.data,
- session_key.data,
- ntlmssp_state->encrypted_session_key.length);
- ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx,
+ arcfour_crypt(ntlmssp_state->encrypted_session_key.data,
+ session_key.data,
+ ntlmssp_state->encrypted_session_key.length);
+ ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state,
ntlmssp_state->encrypted_session_key.data,
ntlmssp_state->encrypted_session_key.length);
dump_data_pw("KEY_EXCH session key:\n", ntlmssp_state->encrypted_session_key.data,
* @param ntlmssp_state NTLMSSP State, allocated by this function
*/
-NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state)
+NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("NTLMSSP context");
-
- *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
+ *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state);
if (!*ntlmssp_state) {
DEBUG(0,("ntlmssp_server_start: talloc failed!\n"));
- talloc_destroy(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
+ ZERO_STRUCTP(*ntlmssp_state);
(*ntlmssp_state)->role = NTLMSSP_SERVER;
- (*ntlmssp_state)->mem_ctx = mem_ctx;
(*ntlmssp_state)->get_challenge = get_challenge;
(*ntlmssp_state)->set_challenge = set_challenge;
(*ntlmssp_state)->may_set_challenge = may_set_challenge;
- (*ntlmssp_state)->get_global_myname = global_myname;
+ (*ntlmssp_state)->get_global_myname = lp_netbios_name;
(*ntlmssp_state)->get_domain = lp_workgroup;
(*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
(*ntlmssp_state)->ref_count = 1;
(*ntlmssp_state)->neg_flags =
- NTLMSSP_NEGOTIATE_128 |
- NTLMSSP_NEGOTIATE_NTLM |
-// NTLMSSP_NEGOTIATE_NTLM2 |
- NTLMSSP_NEGOTIATE_KEY_EXCH |
- NTLMSSP_NEGOTIATE_SIGN |
- NTLMSSP_NEGOTIATE_SEAL;
+ NTLMSSP_NEGOTIATE_NTLM;
+
+ if (lp_parm_bool(-1, "ntlmssp_server", "128bit", True)) {
+ (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
+ }
+
+ if (lp_parm_bool(-1, "ntlmssp_server", "keyexchange", True)) {
+ (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
+ }
+
+ if (lp_parm_bool(-1, "ntlmssp_server", "ntlm2", True)) {
+ (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+ }
return NT_STATUS_OK;
}
}
if (ntlmssp_state->use_ntlmv2) {
-// ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
}
/* generate the ntlmssp negotiate packet */
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out)
{
- uint32 chal_flags, ntlmssp_command, unkn1, unkn2;
+ uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
DATA_BLOB server_domain_blob;
DATA_BLOB challenge_blob;
DATA_BLOB struct_blob = data_blob(NULL, 0);
char *server_domain;
const char *chal_parse_string;
const char *auth_gen_string;
- uchar lm_hash[16];
+ uint8_t lm_hash[16];
DATA_BLOB lm_response = data_blob(NULL, 0);
DATA_BLOB nt_response = data_blob(NULL, 0);
DATA_BLOB session_key = data_blob(NULL, 0);
DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
NTSTATUS nt_status;
- if (!msrpc_parse(ntlmssp_state->mem_ctx,
+ if (!msrpc_parse(ntlmssp_state,
&in, "CdBd",
"NTLMSSP",
&ntlmssp_command,
&server_domain_blob,
&chal_flags)) {
DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n"));
- dump_data(2, (const char *)in.data, in.length);
+ dump_data(2, in.data, in.length);
return NT_STATUS_INVALID_PARAMETER;
}
DEBUG(3, ("NTLMSSP: Set final flags:\n"));
debug_ntlmssp_flags(ntlmssp_state->neg_flags);
- if (!msrpc_parse(ntlmssp_state->mem_ctx,
+ if (!msrpc_parse(ntlmssp_state,
&in, chal_parse_string,
"NTLMSSP",
&ntlmssp_command,
&unkn1, &unkn2,
&struct_blob)) {
DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n"));
- dump_data(2, (const char *)in.data, in.length);
+ dump_data(2, in.data, in.length);
return NT_STATUS_INVALID_PARAMETER;
}
}
if (!ntlmssp_state->password) {
- static const uchar zeros[16];
+ static const uint8_t zeros[16];
/* do nothing - blobs are zero length */
/* session key is all zeros */
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
- lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16);
+ session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
+ lm_session_key = data_blob_talloc(ntlmssp_state, zeros, 16);
/* not doing NLTM2 without a password */
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
ntlmssp_state->domain,
ntlmssp_state->password, &challenge_blob,
&struct_blob,
- &lm_response, &nt_response, &session_key)) {
+ &lm_response, &nt_response,
+ NULL, &session_key)) {
data_blob_free(&challenge_blob);
data_blob_free(&struct_blob);
return NT_STATUS_NO_MEMORY;
} else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
struct MD5Context md5_session_nonce_ctx;
- uchar nt_hash[16];
- uchar session_nonce[16];
- uchar session_nonce_hash[16];
- uchar user_session_key[16];
+ uint8_t nt_hash[16];
+ uint8_t session_nonce[16];
+ uint8_t session_nonce_hash[16];
+ uint8_t user_session_key[16];
E_md4hash(ntlmssp_state->password, nt_hash);
- lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
- generate_random_buffer(lm_response.data, 8, False);
+ lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
+ generate_random_buffer(lm_response.data, 8);
memset(lm_response.data+8, 0, 16);
memcpy(session_nonce, challenge_blob.data, 8);
DEBUG(5, ("NTLMSSP challenge set by NTLM2\n"));
DEBUG(5, ("challenge is: \n"));
- dump_data(5, (const char *)session_nonce_hash, 8);
+ dump_data(5, session_nonce_hash, 8);
- nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
+ nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
SMBNTencrypt(ntlmssp_state->password,
session_nonce_hash,
nt_response.data);
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
SMBsesskeygen_ntv1(nt_hash, user_session_key);
hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data);
/* LM Key is incompatible... */
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
} else {
- uchar nt_hash[16];
+ uint8_t nt_hash[16];
if (ntlmssp_state->use_nt_response) {
- nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
+ nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
nt_response.data);
E_md4hash(ntlmssp_state->password, nt_hash);
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
SMBsesskeygen_ntv1(nt_hash, session_key.data);
dump_data_pw("NT session key:\n", session_key.data, session_key.length);
}
/* lanman auth is insecure, it may be disabled */
if (lp_client_lanman_auth()) {
- lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24);
+ lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
lm_response.data)) {
/* If the LM password was too long (and therefore the LM hash being
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
} else {
E_deshash(ntlmssp_state->password, lm_hash);
- lm_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
memcpy(lm_session_key.data, lm_hash, 8);
memset(&lm_session_key.data[8], '\0', 8);
if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
&& lp_client_lanman_auth() && lm_session_key.length == 16) {
- DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ DATA_BLOB new_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
if (lm_response.length == 24) {
SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data,
new_session_key.data);
} else {
- static const uchar zeros[24];
+ static const uint8_t zeros[24];
SMBsesskeygen_lm_sess_key(lm_session_key.data, zeros,
new_session_key.data);
}
the password-derived key */
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
/* Make up a new session key */
- uint8 client_session_key[16];
- generate_random_buffer(client_session_key, sizeof(client_session_key), False);
+ uint8_t client_session_key[16];
+ generate_random_buffer(client_session_key, sizeof(client_session_key));
/* Encrypt the new session key with the old one */
- encrypted_session_key = data_blob_talloc(ntlmssp_state->mem_ctx,
+ encrypted_session_key = data_blob_talloc(ntlmssp_state,
client_session_key, sizeof(client_session_key));
dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
- SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
+ arcfour_crypt(encrypted_session_key.data, session_key.data, encrypted_session_key.length);
dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length);
/* Mark the new session key as the 'real' session key */
- session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key));
+ session_key = data_blob_talloc(ntlmssp_state, client_session_key, sizeof(client_session_key));
}
/* this generates the actual auth packet */
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
-NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state)
+NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmssp_state)
{
- TALLOC_CTX *mem_ctx;
-
- mem_ctx = talloc_init("NTLMSSP Client context");
-
- *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state));
+ *ntlmssp_state = talloc_p(mem_ctx, struct ntlmssp_state);
if (!*ntlmssp_state) {
DEBUG(0,("ntlmssp_client_start: talloc failed!\n"));
- talloc_destroy(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
+ ZERO_STRUCTP(*ntlmssp_state);
(*ntlmssp_state)->role = NTLMSSP_CLIENT;
- (*ntlmssp_state)->mem_ctx = mem_ctx;
-
- (*ntlmssp_state)->get_global_myname = global_myname;
+ (*ntlmssp_state)->get_global_myname = lp_netbios_name;
(*ntlmssp_state)->get_domain = lp_workgroup;
(*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
(*ntlmssp_state)->ref_count = 1;
(*ntlmssp_state)->neg_flags =
- NTLMSSP_NEGOTIATE_128 |
NTLMSSP_NEGOTIATE_NTLM |
-// NTLMSSP_NEGOTIATE_NTLM2 |
- NTLMSSP_NEGOTIATE_KEY_EXCH |
- /*
- * We need to set this to allow a later SetPassword
- * via the SAMR pipe to succeed. Strange.... We could
- * also add NTLMSSP_NEGOTIATE_SEAL here. JRA.
- *
- * Without this, Windows will not create the master key
- * that it thinks is only used for NTLMSSP signing and
- * sealing. (It is actually pulled out and used directly)
- */
- NTLMSSP_NEGOTIATE_SIGN |
NTLMSSP_REQUEST_TARGET;
+ if (lp_parm_bool(-1, "ntlmssp_client", "128bit", True)) {
+ (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_128;
+ }
+
+ if (lp_parm_bool(-1, "ntlmssp_client", "keyexchange", True)) {
+ (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
+ }
+
+ if (lp_parm_bool(-1, "ntlmssp_client", "ntlm2", True)) {
+ (*ntlmssp_state)->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+ } else {
+ /* apparently we can't do ntlmv2 if we don't do ntlm2 */
+ (*ntlmssp_state)->use_ntlmv2 = False;
+ }
+
return NT_STATUS_OK;
}