summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clientgen.c15
-rw-r--r--source3/libsmb/clierror.c12
-rw-r--r--source3/libsmb/clifile.c32
-rw-r--r--source3/libsmb/netlogon_unigrp.c37
-rw-r--r--source3/libsmb/ntlmssp.c2
-rw-r--r--source3/libsmb/ntlmssp_sign.c26
-rw-r--r--source3/libsmb/smb_signing.c17
-rw-r--r--source3/libsmb/trust_passwd.c116
8 files changed, 150 insertions, 107 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 81cb61d757..81b3bbcab5 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -118,10 +118,7 @@ BOOL cli_receive_smb(struct cli_state *cli)
}
if (!cli_check_sign_mac(cli)) {
- DEBUG(0, ("SMB Signature verification failed on incoming packet!\n"));
- cli->smb_rw_error = READ_BAD_SIG;
- close(cli->fd);
- cli->fd = -1;
+ DEBUG(0, ("SMB Signiture verification failed on incoming packet!\n"));
return False;
};
return True;
@@ -262,6 +259,9 @@ struct cli_state *cli_initialise(struct cli_state *cli)
if (getenv("CLI_FORCE_DOSERR"))
cli->force_dos_errors = True;
+ /* initialise signing */
+ cli_null_set_signing(cli);
+
if (lp_client_signing())
cli->sign_info.allow_smb_signing = True;
@@ -274,13 +274,6 @@ struct cli_state *cli_initialise(struct cli_state *cli)
memset(cli->outbuf, 0, cli->bufsize);
memset(cli->inbuf, 0, cli->bufsize);
- /* just becouse we over-allocate, doesn't mean it's right to use it */
- clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN);
- clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN);
-
- /* initialise signing */
- cli_null_set_signing(cli);
-
cli->nt_pipe_fnum = 0;
cli->saved_netlogon_pipe_fnum = 0;
diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c
index 9ee181a90f..cea736ef18 100644
--- a/source3/libsmb/clierror.c
+++ b/source3/libsmb/clierror.c
@@ -96,21 +96,17 @@ const char *cli_errstr(struct cli_state *cli)
break;
case READ_EOF:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Call returned zero bytes (EOF)" );
+ "Call returned zero bytes (EOF)\n" );
break;
case READ_ERROR:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Read error: %s", strerror(errno) );
+ "Read error: %s\n", strerror(errno) );
break;
case WRITE_ERROR:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Write error: %s", strerror(errno) );
+ "Write error: %s\n", strerror(errno) );
break;
- case READ_BAD_SIG:
- slprintf(cli_error_message, sizeof(cli_error_message) - 1,
- "Server packet had invalid SMB signiture!");
- break;
- default:
+ default:
slprintf(cli_error_message, sizeof(cli_error_message) - 1,
"Unknown error code %d\n", cli->smb_rw_error );
break;
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index b771e135f4..1163b752b1 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -945,6 +945,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t)
/****************************************************************************
Check for existance of a dir.
****************************************************************************/
+
BOOL cli_chkpath(struct cli_state *cli, const char *path)
{
pstring path2;
@@ -1051,34 +1052,3 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path)
return SVAL(cli->inbuf,smb_vwv0);
}
-
-
-/*
- send a raw ioctl - used by the torture code
-*/
-NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *blob)
-{
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
-
- set_message(cli->outbuf, 3, 0, True);
- SCVAL(cli->outbuf,smb_com,SMBioctl);
- cli_setup_packet(cli);
-
- SSVAL(cli->outbuf, smb_vwv0, fnum);
- SSVAL(cli->outbuf, smb_vwv1, code>>16);
- SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF));
-
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
- }
-
- if (cli_is_error(cli)) {
- return cli_nt_error(cli);
- }
-
- *blob = data_blob(NULL, 0);
-
- return NT_STATUS_OK;
-}
diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c
index 466410d800..fa2fe32f35 100644
--- a/source3/libsmb/netlogon_unigrp.c
+++ b/source3/libsmb/netlogon_unigrp.c
@@ -22,7 +22,6 @@
*/
#include "includes.h"
-#define UNIGROUP_PREFIX "UNIGROUP"
/*
Handle for netlogon_unigrp.tdb database. It is used internally
@@ -51,22 +50,17 @@ BOOL uni_group_cache_init(void)
BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user)
{
TDB_DATA key,data;
- fstring keystr, sid_string;
- DOM_SID user_sid;
- unsigned int i;
+ fstring keystr;
+ int i;
if (!uni_group_cache_init()) {
DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n"));
return False;
}
- sid_copy(&user_sid, &user->dom_sid.sid);
- sid_append_rid(&user_sid, user->user_rid);
-
- /* Prepare key as USER-SID string */
- slprintf(keystr, sizeof(keystr), "%s/%s",
- UNIGROUP_PREFIX,
- sid_to_string(sid_string, &user_sid));
+ /* Prepare key as DOMAIN-SID/USER-RID string */
+ slprintf(keystr, sizeof(keystr), "%s/%d",
+ sid_string_static(&user->dom_sid.sid), user->user_rid);
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
@@ -96,15 +90,14 @@ BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user)
and elements are array[0] ... array[num_elements-1]
*/
-DOM_SID **uni_group_cache_fetch(DOM_SID *domain, DOM_SID *user_sid,
+uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid,
TALLOC_CTX *mem_ctx, uint32 *num_groups)
{
TDB_DATA key,data;
fstring keystr;
- DOM_SID **groups;
+ uint32 *groups;
uint32 i;
uint32 group_count;
- fstring sid_string;
if (!domain) {
DEBUG(1,("uni_group_cache_fetch: expected non-null domain sid\n"));
@@ -130,9 +123,8 @@ DOM_SID **uni_group_cache_fetch(DOM_SID *domain, DOM_SID *user_sid,
*num_groups = 0;
/* Fetch universal groups */
- slprintf(keystr, sizeof(keystr), "%s/%s",
- UNIGROUP_PREFIX,
- sid_to_string(sid_string, user_sid));
+ slprintf(keystr, sizeof(keystr), "%s/%d",
+ sid_string_static(domain), user_rid);
key.dptr = keystr;
key.dsize = strlen(keystr) + 1;
data = tdb_fetch(netlogon_unigrp_tdb, key);
@@ -144,17 +136,12 @@ DOM_SID **uni_group_cache_fetch(DOM_SID *domain, DOM_SID *user_sid,
/* Transfer data to receiver's memory context */
group_count = IVAL(&((uint32*)data.dptr)[0],0);
- groups = talloc(mem_ctx, (group_count)*sizeof(*groups));
+ groups = talloc(mem_ctx, (group_count)*sizeof(uint32));
if (groups) {
for(i=0; i<group_count; i++) {
- groups[i] = talloc(mem_ctx, sizeof(**groups));
- if (!groups[i]) {
- DEBUG(1,("uni_group_cache_fetch: cannot allocate uni groups in receiver's memory context\n"));
- return NULL;
- }
- sid_copy(groups[i], domain);
- sid_append_rid(groups[i], IVAL(&((uint32*)data.dptr)[i+1],0));
+ groups[i] = IVAL(&((uint32*)data.dptr)[i+1],0);
}
+
} else {
DEBUG(1,("uni_group_cache_fetch: cannot allocate uni groups in receiver's memory context\n"));
}
diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
index d54655d17f..c179b98abf 100644
--- a/source3/libsmb/ntlmssp.c
+++ b/source3/libsmb/ntlmssp.c
@@ -385,7 +385,7 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state,
} else if (ntlmssp_command == NTLMSSP_AUTH) {
return ntlmssp_server_auth(ntlmssp_state, request, reply);
} else {
- DEBUG(1, ("unknown NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
+ DEBUG(1, ("unknown NTLMSSP command %u expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
return NT_STATUS_INVALID_PARAMETER;
}
}
diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c
index 5426263fb9..8f6bd0c691 100644
--- a/source3/libsmb/ntlmssp_sign.c
+++ b/source3/libsmb/ntlmssp_sign.c
@@ -92,14 +92,8 @@ static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16],
calc_hash(hash, digest, 16);
}
-enum ntlmssp_direction {
- NTLMSSP_SEND,
- NTLMSSP_RECEIVE
-};
-
static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state,
const uchar *data, size_t length,
- enum ntlmssp_direction direction,
DATA_BLOB *sig)
{
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
@@ -116,14 +110,8 @@ static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_stat
if (!msrpc_gen(sig, "Bd", digest, sizeof(digest), ntlmssp_state->ntlmssp_seq_num)) {
return NT_STATUS_NO_MEMORY;
}
- switch (direction) {
- case NTLMSSP_SEND:
- NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data, sig->length);
- break;
- case NTLMSSP_RECEIVE:
- NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data, sig->length);
- break;
- }
+
+ NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, sig->data, sig->length);
} else {
uint32 crc;
crc = crc32_calc_buffer(data, length);
@@ -141,7 +129,7 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
DATA_BLOB *sig)
{
ntlmssp_state->ntlmssp_seq_num++;
- return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig);
+ return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, sig);
}
/**
@@ -163,7 +151,7 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
}
nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data,
- length, NTLMSSP_RECEIVE, &local_sig);
+ length, &local_sig);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
@@ -173,12 +161,6 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state,
if (memcmp(sig->data, local_sig.data, MIN(sig->length, local_sig.length)) == 0) {
return NT_STATUS_OK;
} else {
- DEBUG(5, ("BAD SIG: wanted signature of\n"));
- dump_data(5, local_sig.data, local_sig.length);
-
- DEBUG(5, ("BAD SIG: got signature of\n"));
- dump_data(5, sig->data, sig->length);
-
DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n"));
return NT_STATUS_ACCESS_DENIED;
}
diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c
index 4e9b895a1b..9bbf7ef91c 100644
--- a/source3/libsmb/smb_signing.c
+++ b/source3/libsmb/smb_signing.c
@@ -160,6 +160,11 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli)
SIVAL(sequence_buf, 0, data->reply_seq_num);
SIVAL(sequence_buf, 4, 0);
+ if (smb_len(cli->inbuf) < (offset_end_of_sig - 4)) {
+ DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf)));
+ return False;
+ }
+
/* get a copy of the server-sent mac */
memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac));
@@ -270,7 +275,7 @@ static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli)
{
BOOL good;
NTSTATUS nt_status;
- DATA_BLOB sig = data_blob(&cli->inbuf[smb_ss_field], 8);
+ DATA_BLOB sig = data_blob(&cli->outbuf[smb_ss_field], 8);
NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context;
@@ -455,14 +460,8 @@ void cli_caclulate_sign_mac(struct cli_state *cli)
BOOL cli_check_sign_mac(struct cli_state *cli)
{
BOOL good;
-
- if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) {
- DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf)));
- good = False;
- } else {
- good = cli->sign_info.check_incoming_message(cli);
- }
-
+ good = cli->sign_info.check_incoming_message(cli);
+
if (!good) {
if (cli->sign_info.doing_signing) {
return False;
diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c
new file mode 100644
index 0000000000..cf9fd58b13
--- /dev/null
+++ b/source3/libsmb/trust_passwd.c
@@ -0,0 +1,116 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Routines to change trust account passwords.
+ * 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"
+
+/*********************************************************
+ Change the domain password on the PDC.
+
+ Just changes the password betwen the two values specified.
+
+ Caller must have the cli connected to the netlogon pipe
+ already.
+**********************************************************/
+static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ unsigned char orig_trust_passwd_hash[16],
+ unsigned char new_trust_passwd_hash[16])
+{
+ NTSTATUS result;
+ uint32 neg_flags = 0x000001ff;
+
+ result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n",
+ nt_errstr(result)));
+ return result;
+ }
+
+ result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash);
+
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(0,("just_change_the_password: unable to change password (%s)!\n",
+ nt_errstr(result)));
+ }
+ return result;
+}
+
+/*********************************************************
+ Change the domain password on the PDC.
+ Store the password ourselves, but use the supplied password
+ Caller must have already setup the connection to the NETLOGON pipe
+**********************************************************/
+
+NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ unsigned char orig_trust_passwd_hash[16])
+{
+ unsigned char new_trust_passwd_hash[16];
+ char *new_trust_passwd;
+ char *str;
+ NTSTATUS nt_status;
+
+ /* Create a random machine account password */
+ str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
+ new_trust_passwd = talloc_strdup(mem_ctx, str);
+
+ E_md4hash(new_trust_passwd, new_trust_passwd_hash);
+
+ nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash,
+ new_trust_passwd_hash);
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n",
+ timestring(False)));
+ /*
+ * Return the result of trying to write the new password
+ * back into the trust account file.
+ */
+ if (!secrets_store_machine_password(new_trust_passwd)) {
+ nt_status = NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+
+ return nt_status;
+}
+
+/*********************************************************
+ Change the domain password on the PDC.
+ Do most of the legwork ourselfs. Caller must have
+ already setup the connection to the NETLOGON pipe
+**********************************************************/
+
+NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx,
+ const char *domain)
+{
+ unsigned char old_trust_passwd_hash[16];
+ char *up_domain;
+
+ up_domain = talloc_strdup(mem_ctx, domain);
+
+ if (!secrets_fetch_trust_account_password(domain,
+ old_trust_passwd_hash,
+ NULL)) {
+ DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash);
+
+}