[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-1075-g16224e8

Jeremy Allison jra at samba.org
Fri Jan 4 21:00:06 GMT 2008


The branch, v3-2-test has been updated
       via  16224e8f4f22a8db0ed278d741a7706967f55335 (commit)
       via  c4e5a505043965eec77b5bb9bc60957e8f3b97c8 (commit)
      from  18360b852c662d933ceff9854725f878a5de9a7d (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 16224e8f4f22a8db0ed278d741a7706967f55335
Merge: c4e5a505043965eec77b5bb9bc60957e8f3b97c8 18360b852c662d933ceff9854725f878a5de9a7d
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Jan 4 12:59:36 2008 -0800

    Merge branch 'v3-2-test' of ssh://jra@git.samba.org/data/git/samba into v3-2-test

commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Jan 4 12:56:23 2008 -0800

    Refactor the crypto code after a very helpful conversation
    with Volker. Mostly making sure we have data on the incoming
    packet type, not stored in the smb header.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source/client/client.c        |   10 ++-
 source/include/smb.h          |    4 +
 source/include/smb_macros.h   |   11 ++-
 source/lib/dummysmbd.c        |   21 -----
 source/lib/util_sock.c        |   74 -----------------
 source/libsmb/smb_seal.c      |   25 +++---
 source/libsmb/smb_signing.c   |    8 +-
 source/param/loadparm.c       |    5 +-
 source/printing/nt_printing.c |    2 +-
 source/smbd/aio.c             |   27 ++++---
 source/smbd/blocking.c        |   34 +++++---
 source/smbd/error.c           |    4 +-
 source/smbd/ipc.c             |   53 +++++++------
 source/smbd/lanman.c          |    2 +-
 source/smbd/notify.c          |   46 ++++++-----
 source/smbd/nttrans.c         |   39 +++++----
 source/smbd/open.c            |    4 +-
 source/smbd/oplock.c          |   26 +++---
 source/smbd/pipes.c           |    3 +-
 source/smbd/process.c         |  173 +++++++++++++++++++++++++++--------------
 source/smbd/reply.c           |   55 +++++++------
 source/smbd/seal.c            |   44 +++++++----
 source/smbd/sesssetup.c       |    2 +-
 source/smbd/trans2.c          |   69 ++++++++++-------
 source/utils/smbfilter.c      |   28 ++++++-
 25 files changed, 410 insertions(+), 359 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/client/client.c b/source/client/client.c
index 2a86035..fbcfa53 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -4328,16 +4328,22 @@ static void readline_callback(void)
 	timeout.tv_usec = 0;
 	sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout);
 
-	/* We deliberately use receive_smb instead of
+	/* We deliberately use receive_smb_raw instead of
 	   client_receive_smb as we want to receive
 	   session keepalives and then drop them here.
 	*/
 	if (FD_ISSET(cli->fd,&fds)) {
-		if (!receive_smb(cli->fd,cli->inbuf,0,&cli->smb_rw_error)) {
+		if (!receive_smb_raw(cli->fd,cli->inbuf,0,0,&cli->smb_rw_error)) {
 			DEBUG(0, ("Read from server failed, maybe it closed the "
 				"connection\n"));
 			return;
 		}
+		if(CVAL(cli->inbuf,0) != SMBkeepalive) {
+			DEBUG(0, ("Read from server "
+				"returned unexpected packet!\n"));
+			return;
+		}
+
 		goto again;
 	}
 
diff --git a/source/include/smb.h b/source/include/smb.h
index 75fe31e..49245ea 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -659,6 +659,7 @@ typedef struct connection_struct {
 	int num_files_open;
 	unsigned int num_smb_operations; /* Count of smb operations on this tree. */
 	int encrypt_level;
+	bool encrypted_tid;
 
 	/* Semantics requested by the client or forced by the server config. */
 	bool case_sensitive;
@@ -694,6 +695,8 @@ struct smb_request {
 	const uint8 *inbuf;
 	uint8 *outbuf;
 	size_t unread_bytes;
+	bool encrypted;
+	connection_struct *conn;
 };
 
 /* Defines for the sent_oplock_break field above. */
@@ -757,6 +760,7 @@ struct pending_message_list {
 	struct pending_message_list *next, *prev;
 	struct timeval request_time; /* When was this first issued? */
 	struct timeval end_time; /* When does this time out? */
+	bool encrypted;
 	DATA_BLOB buf;
 	DATA_BLOB private_data;
 };
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index 9bacdce..3324f3f 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -158,10 +158,10 @@
 #define SMB_LARGE_LKLEN_OFFSET_HIGH(indx) (12 + (20 * (indx)))
 #define SMB_LARGE_LKLEN_OFFSET_LOW(indx) (16 + (20 * (indx)))
 
-#define ERROR_DOS(class,code) error_packet(inbuf,outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
-#define ERROR_NT(status) error_packet(inbuf,outbuf,0,0,status,__LINE__,__FILE__)
-#define ERROR_FORCE_NT(status) error_packet(inbuf,outbuf,-1,-1,status,__LINE__,__FILE__)
-#define ERROR_BOTH(status,class,code) error_packet(inbuf,outbuf,class,code,status,__LINE__,__FILE__)
+#define ERROR_DOS(class,code) error_packet(outbuf,class,code,NT_STATUS_OK,__LINE__,__FILE__)
+#define ERROR_NT(status) error_packet(outbuf,0,0,status,__LINE__,__FILE__)
+#define ERROR_FORCE_NT(status) error_packet(outbuf,-1,-1,status,__LINE__,__FILE__)
+#define ERROR_BOTH(status,class,code) error_packet(outbuf,class,code,status,__LINE__,__FILE__)
 
 #define reply_nterror(req,status) reply_nt_error(req,status,__LINE__,__FILE__)
 #define reply_force_nterror(req,status) reply_force_nt_error(req,status,__LINE__,__FILE__)
@@ -192,6 +192,9 @@
 #define _smb_setlen_large(buf,len) do { buf[0] = 0; buf[1] = ((len)&0xFF0000)>>16; \
         buf[2] = ((len)&0xFF00)>>8; buf[3] = (len)&0xFF; } while (0)
 
+#define ENCRYPTION_REQUIRED(conn) ((conn) ? ((conn)->encrypt_level == Required) : false)
+#define IS_CONN_ENCRYPTED(conn) ((conn) ? (conn)->encrypted_tid : false)
+
 /*******************************************************************
 find the difference in milliseconds between two struct timeval
 values
diff --git a/source/lib/dummysmbd.c b/source/lib/dummysmbd.c
index 464ba92..dbe886e 100644
--- a/source/lib/dummysmbd.c
+++ b/source/lib/dummysmbd.c
@@ -51,24 +51,3 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
 {
 	return NT_STATUS_OK;
 }
-
-NTSTATUS srv_decrypt_buffer(char *buf)
-{
-        return NT_STATUS_OK;
-}
-
-NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out)
-{
-        *buf_out = buffer;
-        return NT_STATUS_OK;
-}
-
-void srv_free_enc_buffer(char *buf)
-{
-        ;
-}
-
-bool srv_encryption_on(void)
-{
-        return false;
-}
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index b92cd3d..945506e 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -1277,80 +1277,6 @@ ssize_t receive_smb_raw(int fd,
 }
 
 /****************************************************************************
- Wrapper for receive_smb_raw().
- Checks the MAC on signed packets.
-****************************************************************************/
-
-bool receive_smb(int fd, char *buffer, unsigned int timeout, enum smb_read_errors *pre)
-{
-	if (receive_smb_raw(fd, buffer, timeout, 0, pre) < 0) {
-		return false;
-	}
-
-	if (srv_encryption_on()) {
-		NTSTATUS status = srv_decrypt_buffer(buffer);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("receive_smb: SMB decryption failed "
-				"on incoming packet! Error %s\n",
-				nt_errstr(status) ));
-			cond_set_smb_read_error(pre, SMB_READ_BAD_DECRYPT);
-			return false;
-		}
-	}
-
-	/* Check the incoming SMB signature. */
-	if (!srv_check_sign_mac(buffer, true)) {
-		DEBUG(0, ("receive_smb: SMB Signature verification "
-			"failed on incoming packet!\n"));
-		cond_set_smb_read_error(pre,SMB_READ_BAD_SIG);
-		return false;
-	}
-
-	return true;
-}
-
-/****************************************************************************
- Send an smb to a fd.
-****************************************************************************/
-
-bool send_smb(int fd, char *buffer)
-{
-	size_t len;
-	size_t nwritten=0;
-	ssize_t ret;
-	char *buf_out = buffer;
-
-	/* Sign the outgoing packet if required. */
-	srv_calculate_sign_mac(buf_out);
-
-	if (srv_encryption_on()) {
-		NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
-		if (!NT_STATUS_IS_OK(status)) {
-			DEBUG(0, ("send_smb: SMB encryption failed "
-				"on outgoing packet! Error %s\n",
-				nt_errstr(status) ));
-			return false;
-		}
-	}
-
-	len = smb_len(buf_out) + 4;
-
-	while (nwritten < len) {
-		ret = write_data(fd,buf_out+nwritten,len - nwritten);
-		if (ret <= 0) {
-			DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
-				(int)len,(int)ret, strerror(errno) ));
-			srv_free_enc_buffer(buf_out);
-			return false;
-		}
-		nwritten += ret;
-	}
-
-	srv_free_enc_buffer(buf_out);
-	return true;
-}
-
-/****************************************************************************
  Open a socket of the specified type, port, and address for incoming data.
 ****************************************************************************/
 
diff --git a/source/libsmb/smb_seal.c b/source/libsmb/smb_seal.c
index 055a27d..b5befbf 100644
--- a/source/libsmb/smb_seal.c
+++ b/source/libsmb/smb_seal.c
@@ -23,13 +23,13 @@
  Pull out the encryption context for this packet. 0 means global context.
 ******************************************************************************/
 
-NTSTATUS get_enc_ctx_num(const char *buf, uint16 *p_enc_ctx_num)
+NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16 *p_enc_ctx_num)
 {
 	if (smb_len(buf) < 8) {
 		return NT_STATUS_INVALID_BUFFER_SIZE;
 	}
 
-	if (buf[4] == (char)0xFF) {
+	if (buf[4] == 0xFF) {
 		if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') {
 			/* Not an encrypted buffer. */
 			return NT_STATUS_NOT_FOUND;
@@ -93,8 +93,8 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
 
 	memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len);
 
-	/* Reset the length. */
-	_smb_setlen(buf,data_len + 4);
+	/* Reset the length and overwrite the header. */
+	smb_setlen(buf,data_len + 4);
 
 	SAFE_FREE(inbuf);
 	return NT_STATUS_OK;
@@ -203,7 +203,8 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta
 	}
 
 	memcpy(buf + 8, out_buf.value, out_buf.length);
-	_smb_setlen(buf, out_buf.length + 4);
+	/* Reset the length and overwrite the header. */
+	smb_setlen(buf, out_buf.length + 4);
 
 	gss_release_buffer(&minor, &out_buf);
 	return NT_STATUS_OK;
@@ -440,9 +441,9 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf)
 {
 	/* We know this is an smb buffer, and we
 	 * didn't malloc, only copy, for a keepalive,
-	 * so ignore session keepalives. */
+	 * so ignore non-session messages. */
 
-	if(CVAL(buf,0) == SMBkeepalive) {
+	if(CVAL(buf,0)) {
 		return;
 	}
 
@@ -461,12 +462,12 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli)
 	NTSTATUS status;
 	uint16 enc_ctx_num;
 
-	/* Ignore session keepalives. */
-	if(CVAL(cli->inbuf,0) == SMBkeepalive) {
+	/* Ignore non-session messages. */
+	if(CVAL(cli->inbuf,0)) {
 		return NT_STATUS_OK;
 	}
 
-	status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num);
+	status = get_enc_ctx_num((const uint8_t *)cli->inbuf, &enc_ctx_num);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
@@ -484,8 +485,8 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli)
 
 NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out)
 {
-	/* Ignore session keepalives. */
-	if(CVAL(cli->outbuf,0) == SMBkeepalive) {
+	/* Ignore non-session messages. */
+	if(CVAL(cli->outbuf,0)) {
 		return NT_STATUS_OK;
 	}
 
diff --git a/source/libsmb/smb_signing.c b/source/libsmb/smb_signing.c
index d5cbe3b..f03c21b 100644
--- a/source/libsmb/smb_signing.c
+++ b/source/libsmb/smb_signing.c
@@ -745,8 +745,8 @@ bool srv_oplock_set_signing(bool onoff)
 
 bool srv_check_sign_mac(const char *inbuf, bool must_be_ok)
 {
-	/* Check if it's a session keepalive. */
-	if(CVAL(inbuf,0) == SMBkeepalive) {
+	/* Check if it's a non-session message. */
+	if(CVAL(inbuf,0)) {
 		return True;
 	}
 
@@ -759,8 +759,8 @@ bool srv_check_sign_mac(const char *inbuf, bool must_be_ok)
 
 void srv_calculate_sign_mac(char *outbuf)
 {
-	/* Check if it's a session keepalive. */
-	if(CVAL(outbuf,0) == SMBkeepalive) {
+	/* Check if it's a non-session message. */
+	if(CVAL(outbuf,0)) {
 		return;
 	}
 
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 16e9372..29166cf 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -6213,7 +6213,7 @@ uint32 lp_get_spoolss_state( void )
 }
 
 /*******************************************************************
- Ensure we don't use sendfile if server smb signing or selaing is active.
+ Ensure we don't use sendfile if server smb signing is active.
 ********************************************************************/
 
 bool lp_use_sendfile(int snum)
@@ -6224,8 +6224,7 @@ bool lp_use_sendfile(int snum)
 	}
 	return (_lp_use_sendfile(snum) &&
 			(get_remote_arch() != RA_WIN95) &&
-			!srv_is_signing_active() &&
-			!srv_encryption_on());
+			!srv_is_signing_active());
 }
 
 /*******************************************************************
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index f115fba..bae32e8 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -1867,7 +1867,7 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
 		goto err_exit;
 	}
 
-	create_directory(conn, new_dir);
+	create_directory(conn, NULL, new_dir);
 
 	/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
 	 * listed for this driver which has already been moved, skip it (note:
diff --git a/source/smbd/aio.c b/source/smbd/aio.c
index a439c3a..bc1761b 100644
--- a/source/smbd/aio.c
+++ b/source/smbd/aio.c
@@ -236,7 +236,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
 	}
 
 	construct_reply_common((char *)req->inbuf, aio_ex->outbuf);
-	srv_set_message((const char *)req->inbuf, aio_ex->outbuf, 12, 0, True);
+	srv_set_message(aio_ex->outbuf, 12, 0, True);
 	SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */
 
 	a = &aio_ex->acb;
@@ -356,8 +356,9 @@ bool schedule_aio_write_and_X(connection_struct *conn,
 	        SSVAL(aio_ex->outbuf,smb_vwv2,numtowrite);
                 SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1);
 		show_msg(aio_ex->outbuf);
-		if (!send_smb(smbd_server_fd(),aio_ex->outbuf)) {
-			exit_server_cleanly("handle_aio_write: send_smb "
+		if (!srv_send_smb(smbd_server_fd(),aio_ex->outbuf,
+				IS_CONN_ENCRYPTED(fsp->conn))) {
+			exit_server_cleanly("handle_aio_write: srv_send_smb "
 					    "failed.");
 		}
 		DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
@@ -387,7 +388,6 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
 	int ret = 0;
 	int outsize;
 	char *outbuf = aio_ex->outbuf;
-	const char *inbuf = aio_ex->inbuf;
 	char *data = smb_buf(outbuf);
 	ssize_t nread = SMB_VFS_AIO_RETURN(aio_ex->fsp,&aio_ex->acb);
 
@@ -410,9 +410,9 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
 
 		ret = errno;
 		ERROR_NT(map_nt_error_from_unix(ret));
-		outsize = srv_set_message(inbuf,outbuf,0,0,true);
+		outsize = srv_set_message(outbuf,0,0,true);
 	} else {
-		outsize = srv_set_message(inbuf, outbuf,12,nread,False);
+		outsize = srv_set_message(outbuf,12,nread,False);
 		SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be * -1. */
 		SSVAL(outbuf,smb_vwv5,nread);
 		SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
@@ -425,10 +425,11 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
 			    (int)aio_ex->acb.aio_nbytes, (int)nread ) );
 
 	}
-	_smb_setlen(outbuf,outsize - 4);
+	smb_setlen(outbuf,outsize - 4);
 	show_msg(outbuf);
-	if (!send_smb(smbd_server_fd(),outbuf)) {
-		exit_server_cleanly("handle_aio_read_complete: send_smb "
+	if (!srv_send_smb(smbd_server_fd(),outbuf,
+			IS_CONN_ENCRYPTED(aio_ex->fsp->conn))) {
+		exit_server_cleanly("handle_aio_read_complete: srv_send_smb "
 				    "failed.");
 	}
 
@@ -497,7 +498,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
 
 		ret = errno;
 		ERROR_BOTH(map_nt_error_from_unix(ret), ERRHRD, ERRdiskfull);
-		srv_set_message(inbuf,outbuf,0,0,true);
+		srv_set_message(outbuf,0,0,true);
         } else {
 		bool write_through = BITSETW(aio_ex->inbuf+smb_vwv7,0);
 		NTSTATUS status;
@@ -516,15 +517,15 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
 			ret = errno;
 			ERROR_BOTH(map_nt_error_from_unix(ret),
 				   ERRHRD, ERRdiskfull);
-			srv_set_message(inbuf,outbuf,0,0,true);
+			srv_set_message(outbuf,0,0,true);
                 	DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
 				fsp->fsp_name, nt_errstr(status) ));
 		}
 	}
 
 	show_msg(outbuf);
-	if (!send_smb(smbd_server_fd(),outbuf)) {
-		exit_server_cleanly("handle_aio_write: send_smb failed.");
+	if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn))) {
+		exit_server_cleanly("handle_aio_write: srv_send_smb failed.");
 	}
 
 	DEBUG(10,("handle_aio_write_complete: scheduled aio_write completed "
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index 0078bb7..c56f635 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -41,6 +41,7 @@ typedef struct _blocking_lock_record {
 	enum brl_type lock_type;
 	char *inbuf;
 	int length;
+	bool encrypted;
 } blocking_lock_record;
 
 /* dlink list we store pending lock records on. */
@@ -149,7 +150,7 @@ static bool recalc_brl_timeout(void)
 ****************************************************************************/
 
 bool push_blocking_lock_request( struct byte_range_lock *br_lck,
-		const char *inbuf, int length,
+		const struct smb_request *req,
 		files_struct *fsp,
 		int lock_timeout,
 		int lock_num,
@@ -161,6 +162,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
 		uint32 blocking_pid)
 {
 	static bool set_lock_msg;
+	size_t length = smb_len(req->inbuf)+4;
 	blocking_lock_record *blr;
 	NTSTATUS status;
 
@@ -188,7 +190,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
 		return False;
 	}
 
-	blr->com_type = CVAL(inbuf,smb_com);
+	blr->com_type = CVAL(req->inbuf,smb_com);
 	blr->fsp = fsp;
 	if (lock_timeout == -1) {
 		blr->expire_time.tv_sec = 0;
@@ -204,8 +206,9 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
 	blr->lock_type = lock_type;
 	blr->offset = offset;
 	blr->count = count;
-	memcpy(blr->inbuf, inbuf, length);
+	memcpy(blr->inbuf, req->inbuf, length);
 	blr->length = length;
+	blr->encrypted = req->encrypted;
 
 	/* Add a pending lock record for this. */
 	status = brl_lock(smbd_messaging_context(), br_lck,
@@ -242,7 +245,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
 		blr->fsp->fnum, blr->fsp->fsp_name ));
 
 	/* Push the MID of this packet on the signing queue. */
-	srv_defer_sign_response(SVAL(inbuf,smb_mid));
+	srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
 
 	return True;
 }
@@ -259,7 +262,7 @@ static void reply_lockingX_success(blocking_lock_record *blr)
 		smb_panic("Could not allocate smb_request");
 	}
 
-	init_smb_request(req, (uint8 *)blr->inbuf, 0);
+	init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
 	reply_outbuf(req, 2, 0);
 
 	/*
@@ -272,8 +275,10 @@ static void reply_lockingX_success(blocking_lock_record *blr)
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list