Rev 5295: merge from upstream in http://samba.sernet.de/ma/bzr/SAMBA_3_0-registry.bzr/

Michael Adam ma at sernet.de
Wed Mar 21 11:15:45 GMT 2007


At http://samba.sernet.de/ma/bzr/SAMBA_3_0-registry.bzr/

------------------------------------------------------------
revno: 5295
revision-id: ma at sernet.de-20070321111540-96c903c02ca88d77
parent: ma at sernet.de-20070320162624-8e43ac647ee3993b
parent: jra at samba.org-20070321050334-barxfl0kcqqewl34
committer: Michael Adam <ma at sernet.de>
branch nick: SAMBA_3_0-registry.bzr
timestamp: Wed 2007-03-21 12:15:40 +0100
message:
  merge from upstream
modified:
  REVISION                       REVISION-20060530022625-68239662668b41c3
  source/Makefile.in             Makefile.in-20060530022626-b16dac2328ebe703
  source/client/client.c         client.c-20060530022627-a5e98bdfdd1ca9d9
  source/lib/dummysmbd.c         dummysmbd.c-20060530022627-0881298f6c26bb01
  source/libsmb/cliconnect.c     cliconnect.c-20060530022627-fb16a3a9bd86c44d
  source/libsmb/clifsinfo.c      clifsinfo.c-20060530022627-9360212d14f20006
  source/libsmb/clitrans.c       clitrans.c-20060530022627-8d4f01dc98138adf
  source/libsmb/smb_seal.c       smb_seal.c-20070317050048-jthijp4m79ic4h3q-1
  source/libsmb/smb_signing.c    smb_signing.c-20060530022627-1e3c4643957ae652
  source/libsmb/trustdom_cache.c trustdom_cache.c-20060530022627-3b3f57f5b89e82f8
  source/nsswitch/winbindd_pam.c winbindd_pam.c-20060530022627-6b827f2f7ba30f85
  source/smbd/seal.c             seal.c-20070320050326-brtwj05flzzelvyk-1
  source/smbd/trans2.c           trans2.c-20060530022627-7ce34cd85c3f02f5
    ------------------------------------------------------------
    merged: jra at samba.org-20070321050334-barxfl0kcqqewl34
    parent: jra at samba.org-20070321050303-t94g2gwo94kbaqty
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:03:34 -0500
    message:
      jra at samba.org (r21903)  2007-03-20 21:02:09 -0500 (Tue, 20 Mar 2007)
          
          Get the length calculations right (I always forget
          the 4 byte length isn't included in the length :-).
          We now have working NTLMSSP transport encryption
          with sign+seal. W00t! 
          Jeremy.
          
    ------------------------------------------------------------
    merged: jra at samba.org-20070321050303-t94g2gwo94kbaqty
    parent: jra at samba.org-20070321050234-8og7yqh98qb1zbe5
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:03:03 -0500
    message:
      jra at samba.org (r21902)  2007-03-20 20:32:01 -0500 (Tue, 20 Mar 2007)
          
          Don't free the thing you're trying to set in the cli state.
          Jeremy.
          
    ------------------------------------------------------------
    merged: jra at samba.org-20070321050234-8og7yqh98qb1zbe5
    parent: jra at samba.org-20070321050207-u594s3kqi736nuxe
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:02:34 -0500
    message:
      jra at samba.org (r21901)  2007-03-20 20:21:16 -0500 (Tue, 20 Mar 2007)
          
          Don't use fstrcat when you mean fstrcpy. Doh !
          Jeremy.
          
    ------------------------------------------------------------
    merged: jra at samba.org-20070321050207-u594s3kqi736nuxe
    parent: jra at samba.org-20070321050140-567t3d0zqbzg9ux2
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:02:07 -0500
    message:
      jra at samba.org (r21900)  2007-03-20 20:04:56 -0500 (Tue, 20 Mar 2007)
          
          Token exchange now seems to work, now why does the
          client encrypt fail ?
          Jeremy.
          
    ------------------------------------------------------------
    merged: jra at samba.org-20070321050140-567t3d0zqbzg9ux2
    parent: jra at samba.org-20070321050114-0evkm0j71f464mlf
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:01:40 -0500
    message:
      jra at samba.org (r21899)  2007-03-20 19:56:40 -0500 (Tue, 20 Mar 2007)
          
          At least we're getting to stage 2 of the blob
          exchange. Still not working but closer.
          Jeremy.
          
    ------------------------------------------------------------
    merged: jra at samba.org-20070321050114-0evkm0j71f464mlf
    parent: jra at samba.org-20070321050042-ku13b1ai0qpy4b20
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:01:14 -0500
    message:
      jra at samba.org (r21898)  2007-03-20 19:44:15 -0500 (Tue, 20 Mar 2007)
          
          Added test command, fixed first valgrind bugs.
          Now to investigate why it doesn't work :-).
          Jeremy.
          
    ------------------------------------------------------------
    merged: jra at samba.org-20070321050042-ku13b1ai0qpy4b20
    parent: jra at samba.org-20070320230143-xoygjt96di3vnod9
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:00:42 -0500
    message:
      jra at samba.org (r21897)  2007-03-20 19:25:08 -0500 (Tue, 20 Mar 2007)
          
          Add in a basic raw NTLM encrypt request. Now
          for testing.
          Jeremy.
          
    ------------------------------------------------------------
    merged: jra at samba.org-20070320230143-xoygjt96di3vnod9
    parent: mimir at samba.org-20070320230124-67y3u9e9915pz2wi
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 18:01:43 -0500
    message:
      jra at samba.org (r21894)  2007-03-20 17:01:02 -0500 (Tue, 20 Mar 2007)
          
          Some refactoring of server side encryption context. Support
          "raw" NTLM auth (no spnego).
          Jeremy.
          
    ------------------------------------------------------------
    merged: mimir at samba.org-20070320230124-67y3u9e9915pz2wi
    parent: vlendec at samba.org-20070320230054-doog7u02pa5wot0h
    committer: mimir at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 18:01:24 -0500
    message:
      mimir at samba.org (r21893)  2007-03-20 16:21:04 -0500 (Tue, 20 Mar 2007)
          
          Update comments so they actually reflect reality...
          
          
          rafal
          
          
    ------------------------------------------------------------
    merged: vlendec at samba.org-20070320230054-doog7u02pa5wot0h
    parent: jra at samba.org-20070320230028-xa3pbiggj70jfv0x
    committer: vlendec at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 18:00:54 -0500
    message:
      vlendec at samba.org (r21892)  2007-03-20 15:47:17 -0500 (Tue, 20 Mar 2007)
          
          Mini-Patch from Michael
    ------------------------------------------------------------
    merged: jra at samba.org-20070320230028-xa3pbiggj70jfv0x
    parent: jerry at samba.org-20070320170810-7jzv9777fqmg8zg8
    committer: jra at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 18:00:28 -0500
    message:
      jra at samba.org (r21891)  2007-03-20 13:11:48 -0500 (Tue, 20 Mar 2007)
          
          Finish server-side NTLM-SPNEGO negotiation support.
          Now for the client part, and testing.
          Jeremy.
          
    ------------------------------------------------------------
    merged: jerry at samba.org-20070320170810-7jzv9777fqmg8zg8
    parent: gd at samba.org-20070320152320-t1aapy0vl9h9o0tk
    committer: jerry at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 12:08:10 -0500
    message:
      jerry at samba.org (r21888)  2007-03-20 10:29:33 -0500 (Tue, 20 Mar 2007)
          
          Add the osname and osver options to 'net ads join' as discussed 
          on the samba-technical ml.  
          
          I'll add a 'net ads set attribute=value' utility later
          rather than the original 'net ads setmachineupn' patch that
          was also posted to the tech ml.
          
          
    ------------------------------------------------------------
    merged: gd at samba.org-20070320152320-t1aapy0vl9h9o0tk
    parent: ab at samba.org-20070320110156-vu2wo42qnbkak37f
    committer: gd at samba.org
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 10:23:20 -0500
    message:
      gd at samba.org (r21887)  2007-03-20 07:44:40 -0500 (Tue, 20 Mar 2007)
          
          Fix annoying bug where in a pam_close_session (or a pam_setcred with the
          PAM_DELETE_CREDS flag set) any user could delete krb5 credential caches.
          Make sure that only root can do this.
          
          Jerry, Jeremy, please check.
          
          Guenther
          
          
=== modified file 'REVISION'
--- a/REVISION	2007-03-20 11:01:56 +0000
+++ b/REVISION	2007-03-21 05:03:34 +0000
@@ -2,9 +2,9 @@
 URL: svn+ssh://svn.samba.org/home/svn/samba/branches/SAMBA_3_0
 Repository Root: svn+ssh://svn.samba.org/home/svn/samba
 Repository UUID: 0c0555d6-39d7-0310-84fc-f1cc0bd64818
-Revision: 21885
+Revision: 21903
 Node Kind: directory
-Last Changed Author: ab
-Last Changed Rev: 21885
-Last Changed Date: 2007-03-20 03:17:27 -0500 (Tue, 20 Mar 2007)
+Last Changed Author: jra
+Last Changed Rev: 21903
+Last Changed Date: 2007-03-20 21:02:09 -0500 (Tue, 20 Mar 2007)
 

=== modified file 'source/Makefile.in'
--- a/source/Makefile.in	2007-03-20 15:27:04 +0000
+++ b/source/Makefile.in	2007-03-21 11:15:40 +0000
@@ -256,9 +256,9 @@
 	  lib/substitute.o lib/fsusage.o \
 	  lib/ms_fnmatch.o lib/select.o lib/messages.o \
 	  lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \
-	  libsmb/smb_seal.o lib/md5.o lib/hmacmd5.o lib/arc4.o lib/iconv.o \
+	  lib/md5.o lib/hmacmd5.o lib/arc4.o lib/iconv.o \
 	  nsswitch/wb_client.o $(WBCOMMON_OBJ) \
-	  lib/pam_errors.o intl/lang_tdb.o \
+	  lib/pam_errors.o intl/lang_tdb.o libsmb/smb_seal.o \
 	  lib/adt_tree.o lib/gencache.o $(TDB_OBJ) \
 	  lib/module.o lib/events.o lib/ldap_escape.o @CHARSET_STATIC@ \
 	  lib/secdesc.o lib/util_seaccess.o lib/secace.o lib/secacl.o \

=== modified file 'source/client/client.c'
--- a/source/client/client.c	2007-03-09 00:15:08 +0000
+++ b/source/client/client.c	2007-03-21 05:02:34 +0000
@@ -1787,6 +1787,49 @@
 /****************************************************************************
 ****************************************************************************/
 
+static int cmd_posix_encrypt(void)
+{
+	fstring buf;
+	fstring domain;
+	fstring user;
+	fstring password;
+	NTSTATUS status;
+
+	if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+		d_printf("posix_encrypt domain user password\n");
+		return 1;
+	}
+	fstrcpy(domain,buf);
+
+	if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+		d_printf("posix_encrypt domain user password\n");
+		return 1;
+	}
+	fstrcpy(user,buf);
+
+	if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
+		d_printf("posix_encrypt domain user password\n");
+		return 1;
+	}
+	fstrcpy(password,buf);
+
+	status = cli_raw_ntlm_smb_encryption_start(cli,
+						user,
+						password,
+						domain);
+	
+	if (!NT_STATUS_IS_OK(status)) {
+		d_printf("posix_encrypt failed with error %s\n", nt_errstr(status));
+	} else {
+		d_printf("encryption on\n");
+	}
+
+	return 0;
+}
+
+/****************************************************************************
+****************************************************************************/
+
 static int cmd_posix_open(void)
 {
 	pstring mask;
@@ -3227,6 +3270,7 @@
   {"newer",cmd_newer,"<file> only mget files newer than the specified local file",{COMPL_LOCAL,COMPL_NONE}},
   {"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
   {"posix", cmd_posix, "turn on all POSIX capabilities", {COMPL_REMOTE,COMPL_NONE}},
+  {"posix_encrypt",cmd_posix_encrypt,"<domain> <user> <password> start up transport encryption",{COMPL_REMOTE,COMPL_NONE}},
   {"posix_open",cmd_posix_open,"<name> 0<mode> open_flags mode open a file using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
   {"posix_mkdir",cmd_posix_mkdir,"<name> 0<mode> creates a directory using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},
   {"posix_rmdir",cmd_posix_rmdir,"<name> removes a directory using POSIX interface",{COMPL_REMOTE,COMPL_NONE}},

=== modified file 'source/lib/dummysmbd.c'
--- a/source/lib/dummysmbd.c	2007-03-20 05:03:29 +0000
+++ b/source/lib/dummysmbd.c	2007-03-21 05:00:42 +0000
@@ -63,3 +63,8 @@
 {
 	;
 }
+
+BOOL srv_encryption_on(void)
+{
+	return False;
+}

=== modified file 'source/libsmb/cliconnect.c'
--- a/source/libsmb/cliconnect.c	2007-03-08 00:13:01 +0000
+++ b/source/libsmb/cliconnect.c	2007-03-20 23:01:43 +0000
@@ -763,7 +763,7 @@
 		}
 	}
 
-	/* we have a reference conter on ntlmssp_state, if we are signing
+	/* we have a reference counter on ntlmssp_state, if we are signing
 	   then the state will be kept by the signing engine */
 
 	ntlmssp_end(&ntlmssp_state);
@@ -973,7 +973,6 @@
 	}
 
 	return NT_STATUS_OK;
-
 }
 
 /****************************************************************************

=== modified file 'source/libsmb/clifsinfo.c'
--- a/source/libsmb/clifsinfo.c	2006-08-29 16:18:48 +0000
+++ b/source/libsmb/clifsinfo.c	2007-03-21 05:03:03 +0000
@@ -302,3 +302,118 @@
 
 	return ret;	
 }
+
+/******************************************************************************
+ Send/receive the request encryption blob.
+******************************************************************************/
+
+static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out)
+{
+	uint16 setup;
+	char param[4];
+	char *rparam=NULL, *rdata=NULL;
+	unsigned int rparam_count=0, rdata_count=0;
+	NTSTATUS status = NT_STATUS_OK;
+
+	setup = TRANSACT2_SETFSINFO;
+
+	SSVAL(param,0,0);
+	SSVAL(param,2,SMB_REQUEST_TRANSPORT_ENCRYPTION);
+
+	if (!cli_send_trans(cli, SMBtrans2,
+				NULL,
+				0, 0,
+				&setup, 1, 0,
+				param, 4, 0,
+				(char *)in->data, in->length, CLI_BUFFER_SIZE)) {
+		status = cli_nt_error(cli);
+		goto out;
+	}
+
+	if (!cli_receive_trans(cli, SMBtrans2,
+				&rparam, &rparam_count,
+				&rdata, &rdata_count)) {
+		status = cli_nt_error(cli);
+		goto out;
+	}
+
+	if (cli_is_error(cli)) {
+		status = cli_nt_error(cli);
+		if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+			goto out;
+		}
+	}
+
+	*out = data_blob(rdata, rdata_count);
+
+  out:
+
+	SAFE_FREE(rparam);
+	SAFE_FREE(rdata);
+	return status;
+}
+
+/******************************************************************************
+ Start a raw ntlmssp encryption.
+******************************************************************************/
+
+NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, 
+				const char *user,
+				const char *pass,
+				const char *domain)
+{
+	DATA_BLOB blob_in = data_blob(NULL, 0);
+	DATA_BLOB blob_out = data_blob(NULL, 0);
+	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+	struct smb_trans_enc_state *es = NULL;
+
+	es = SMB_MALLOC_P(struct smb_trans_enc_state);
+	if (!es) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	ZERO_STRUCTP(es);
+	es->smb_enc_type = SMB_TRANS_ENC_NTLM;
+	status = ntlmssp_client_start(&es->ntlmssp_state);
+	if (!NT_STATUS_IS_OK(status)) {
+		goto fail;
+	}
+
+	ntlmssp_want_feature(es->ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+	es->ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
+
+	if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->ntlmssp_state, user))) {
+		goto fail;
+	}
+	if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->ntlmssp_state, domain))) {
+		goto fail;
+	}
+	if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->ntlmssp_state, pass))) {
+		goto fail;
+	}
+
+	do {
+		status = ntlmssp_update(es->ntlmssp_state, blob_in, &blob_out);
+		data_blob_free(&blob_in);
+		if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) {
+			status = enc_blob_send_receive(cli, &blob_out, &blob_in);
+		}
+		data_blob_free(&blob_out);
+	} while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
+
+	data_blob_free(&blob_in);
+
+	if (NT_STATUS_IS_OK(status)) {
+		/* Replace the old state, if any. */
+		if (cli->trans_enc_state) {
+			common_free_encryption_state(&cli->trans_enc_state);
+		}
+		cli->trans_enc_state = es;
+		cli->trans_enc_state->enc_on = True;
+		es = NULL;
+	}
+
+  fail:
+
+	common_free_encryption_state(&es);
+	return status;
+}

=== modified file 'source/libsmb/clitrans.c'
--- a/source/libsmb/clitrans.c	2006-08-01 08:42:07 +0000
+++ b/source/libsmb/clitrans.c	2007-03-21 05:01:40 +0000
@@ -194,11 +194,15 @@
 	 * to a trans call. This is not an error and should not
 	 * be treated as such. Note that STATUS_NO_MORE_FILES is
 	 * returned when a trans2 findfirst/next finishes.
+	 * When setting up an encrypted transport we can also
+	 * see NT_STATUS_MORE_PROCESSING_REQUIRED here.
 	 */
 	status = cli_nt_error(cli);
 	
-	if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) {
-		goto out;
+	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+		if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) {
+			goto out;
+		}
 	}
 
 	/* parse out the lengths */
@@ -303,8 +307,10 @@
 				 CVAL(cli->inbuf,smb_com)));
 			goto out;
 		}
-		if (NT_STATUS_IS_ERR(cli_nt_error(cli))) {
-			goto out;
+		if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+			if (NT_STATUS_IS_ERR(cli_nt_error(cli))) {
+				goto out;
+			}
 		}
 
 		/* parse out the total lengths again - they can shrink! */

=== modified file 'source/libsmb/smb_seal.c'
--- a/source/libsmb/smb_seal.c	2007-03-20 05:05:07 +0000
+++ b/source/libsmb/smb_seal.c	2007-03-21 05:03:34 +0000
@@ -38,30 +38,33 @@
 NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
 {
 	NTSTATUS status;
-	size_t orig_len = smb_len(buf);
-	size_t new_len = orig_len - NTLMSSP_SIG_SIZE;
+	size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
 	DATA_BLOB sig;
 
-	if (orig_len < 8 + NTLMSSP_SIG_SIZE) {
+	if (buf_len < 8 + NTLMSSP_SIG_SIZE) {
 		return NT_STATUS_BUFFER_TOO_SMALL;
 	}
 
+	/* Adjust for the signature. */
+	buf_len -= NTLMSSP_SIG_SIZE;
+
 	/* Save off the signature. */
-	sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE);
+	sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE);
 
 	status = ntlmssp_unseal_packet(ntlmssp_state,
 		(unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
-		new_len - 8,
+		buf_len - 8,
 		(unsigned char *)buf,
-		new_len,
+		buf_len,
 		&sig);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		data_blob_free(&sig);
 		return status;
 	}
+
 	/* Reset the length. */
-	smb_setlen(buf, new_len);
+	smb_setlen(buf, smb_len(buf) - NTLMSSP_SIG_SIZE);
 	return NT_STATUS_OK;
 }
 
@@ -74,13 +77,12 @@
 {
 	NTSTATUS status;
 	char *buf_out;
-	size_t orig_len = smb_len(buf);
-	size_t new_len = orig_len + NTLMSSP_SIG_SIZE;
+	size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
 	DATA_BLOB sig;
 
 	*ppbuf_out = NULL;
 
-	if (orig_len < 8) {
+	if (buf_len < 8) {
 		return NT_STATUS_BUFFER_TOO_SMALL;
 	}
 
@@ -91,19 +93,19 @@
 
 	/* Copy the original buffer. */
 
-	buf_out = SMB_XMALLOC_ARRAY(char, new_len);
-	memcpy(buf_out, buf, orig_len);
+	buf_out = SMB_XMALLOC_ARRAY(char, buf_len + NTLMSSP_SIG_SIZE);
+	memcpy(buf_out, buf, buf_len);
 	/* Last 16 bytes undefined here... */
 
-	smb_setlen(buf_out, new_len);
+	smb_setlen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE);
 
 	sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
 
 	status = ntlmssp_seal_packet(ntlmssp_state,
 		(unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
-		orig_len - 8,
+		buf_len - 8,
 		(unsigned char *)buf_out,
-		orig_len,
+		buf_len,
 		&sig);
 
 	if (!NT_STATUS_IS_OK(status)) {
@@ -112,7 +114,7 @@
 		return status;
 	}
 
-	memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE);
+	memcpy(buf_out+buf_len, sig.data, NTLMSSP_SIG_SIZE);
 	*ppbuf_out = buf_out;
 	return NT_STATUS_OK;
 }
@@ -154,6 +156,12 @@
 		return NT_STATUS_OK;
 	}
 
+	/* Ignore session keepalives. */
+	if(CVAL(buffer,0) == SMBkeepalive) {
+		*buf_out = buffer;
+		return NT_STATUS_OK;
+	}
+
 	if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
 		return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out);
 	} else {
@@ -177,6 +185,12 @@
 		/* Not decrypting. */
 		return NT_STATUS_OK;
 	}
+
+	/* Ignore session keepalives. */
+	if(CVAL(buf,0) == SMBkeepalive) {
+		return NT_STATUS_OK;
+	}
+
 	if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
 		return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf);
 	} else {

=== modified file 'source/libsmb/smb_signing.c'
--- a/source/libsmb/smb_signing.c	2006-11-12 05:08:21 +0000
+++ b/source/libsmb/smb_signing.c	2007-03-21 05:00:42 +0000
@@ -585,7 +585,9 @@
  
 void cli_calculate_sign_mac(struct cli_state *cli)
 {
-	cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
+	if (!cli_encryption_on(cli)) {
+		cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info);
+	}
 }
 
 /**
@@ -596,6 +598,9 @@
  
 BOOL cli_check_sign_mac(struct cli_state *cli) 
 {
+	if (cli_encryption_on(cli)) {
+		return True;
+	}
 	if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) {
 		free_signing_context(&cli->sign_info);	
 		return False;
@@ -612,6 +617,9 @@
 	struct smb_sign_info *si = &cli->sign_info;
 	struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
 
+	if (cli_encryption_on(cli)) {
+		return True;
+	}
 	if (!si->doing_signing) {
 		return True;
 	}
@@ -637,6 +645,9 @@
 	struct smb_sign_info *si = &cli->sign_info;
 	struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context;
 
+	if (cli_encryption_on(cli)) {
+		return True;
+	}
 	if (!si->doing_signing) {
 		return True;
 	}
@@ -798,8 +809,18 @@
 BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok)
 {
 	/* Check if it's a session keepalive. */
-	if(CVAL(inbuf,0) == SMBkeepalive)
-		return True;
+	if(CVAL(inbuf,0) == SMBkeepalive) {
+		return True;
+	}
+
+	/* 
+	 * If we have an encrypted transport
+	 * don't sign - we're already doing that.
+	 */
+
+	if (srv_encryption_on()) {
+		return True;
+	}
 
 	return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok);
 }
@@ -811,9 +832,18 @@
 void srv_calculate_sign_mac(char *outbuf)
 {
 	/* Check if it's a session keepalive. */
-	/* JRA Paranioa test - do we ever generate these in the server ? */
-	if(CVAL(outbuf,0) == SMBkeepalive)
-		return;
+	if(CVAL(outbuf,0) == SMBkeepalive) {
+		return;
+	}
+
+	/* 
+	 * If we have an encrypted transport
+	 * don't check sign - we're already doing that.
+	 */
+
+	if (srv_encryption_on()) {
+		return;
+	}
 
 	srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info);
 }

=== modified file 'source/libsmb/trustdom_cache.c'
--- a/source/libsmb/trustdom_cache.c	2007-01-12 14:00:26 +0000
+++ b/source/libsmb/trustdom_cache.c	2007-03-20 23:01:24 +0000
@@ -99,7 +99,7 @@
 
 /**
  * Store trusted domain in gencache as the domain name (key)
- * and ip address of domain controller (value)
+ * and trusted domain's SID (value)
  *
  * @param name trusted domain name
  * @param alt_name alternative trusted domain name (used in ADS domains)
@@ -152,7 +152,7 @@
 
 
 /**
- * Fetch trusted domain's dc from the gencache.
+ * Fetch trusted domain's SID from the gencache.
  * This routine can also be used to check whether given
  * domain is currently trusted one.
  *
@@ -189,7 +189,7 @@
 		DEBUG(5, ("trusted domain %s found (%s)\n", name, value));
 	}
 
-	/* convert ip string representation into in_addr structure */
+	/* convert sid string representation into DOM_SID structure */
 	if(! string_to_sid(sid, value)) {
 		sid = NULL;
 		SAFE_FREE(value);

=== modified file 'source/nsswitch/winbindd_pam.c'
--- a/source/nsswitch/winbindd_pam.c	2007-03-19 17:03:07 +0000
+++ b/source/nsswitch/winbindd_pam.c	2007-03-20 15:23:20 +0000
@@ -2092,7 +2092,9 @@
 {
 	struct winbindd_domain *domain;
 	fstring name_domain, user;
-	
+	uid_t caller_uid = (uid_t)-1;
+	uid_t request_uid = state->request.data.logoff.uid;
+
 	DEBUG(3, ("[%5lu]: pam logoff %s\n", (unsigned long)state->pid,
 		state->request.data.logoff.user));
 
@@ -2103,6 +2105,10 @@
 	state->request.data.logoff.krb5ccname
 		[sizeof(state->request.data.logoff.krb5ccname)-1]='\0';
 
+	if (request_uid == (gid_t)-1) {
+		goto failed;
+	}
+
 	if (!canonicalize_username(state->request.data.logoff.user, name_domain, user)) {
 		goto failed;
 	}
@@ -2111,6 +2117,28 @@
 		goto failed;
 	}
 
+	if ((sys_getpeereid(state->sock, &caller_uid)) != 0) {
+		DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n", 
+			strerror(errno)));
+		goto failed;
+	}
+
+	switch (caller_uid) {
+		case -1:
+			goto failed;
+		case 0:
+			/* root must be able to logoff any user - gd */
+			state->request.data.logoff.uid = request_uid;
+			break;
+		default:
+			if (caller_uid != request_uid) {
+				DEBUG(1,("winbindd_pam_logoff: caller requested invalid uid\n"));
+				goto failed;
+			}
+			state->request.data.logoff.uid = caller_uid;
+			break;
+	}
+
 	sendto_domain(state, domain);
 	return;
 

=== modified file 'source/smbd/seal.c'
--- a/source/smbd/seal.c	2007-03-20 05:03:29 +0000
+++ b/source/smbd/seal.c	2007-03-21 05:02:07 +0000
@@ -49,7 +49,44 @@
 }
 
 /******************************************************************************
- Shutdown a server encryption state.
+ Create an auth_ntlmssp_state and ensure pointer copy is correct.
+******************************************************************************/
+
+static NTSTATUS make_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
+{
+	NTSTATUS status = auth_ntlmssp_start(&ec->auth_ntlmssp_state);
+	if (!NT_STATUS_IS_OK(status)) {
+		return nt_status_squash(status);
+	}
+
+	/*
+	 * We must remember to update the pointer copy for the common
+	 * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
+	 */
+	ec->es->ntlmssp_state = ec->auth_ntlmssp_state->ntlmssp_state;
+	return status;
+}
+
+/******************************************************************************
+ Destroy an auth_ntlmssp_state and ensure pointer copy is correct.
+******************************************************************************/
+
+static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
+{
+	/*
+	 * We must remember to update the pointer copy for the common
+	 * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
+	 */
+
+	if (ec->auth_ntlmssp_state) {
+		auth_ntlmssp_end(&ec->auth_ntlmssp_state);
+		/* The auth_ntlmssp_end killed this already. */
+		ec->es->ntlmssp_state = NULL;
+	}
+}
+
+/******************************************************************************
+ Shutdown a server encryption context.
 ******************************************************************************/
 
 static void srv_free_encryption_context(struct smb_srv_trans_enc_ctx **pp_ec)
@@ -61,12 +98,8 @@
 	}
 
 	if (ec->es) {
-		struct smb_trans_enc_state *es = ec->es;
-		if (es->smb_enc_type == SMB_TRANS_ENC_NTLM &&
-				ec->auth_ntlmssp_state) {
-			auth_ntlmssp_end(&ec->auth_ntlmssp_state);
-			/* The auth_ntlmssp_end killed this already. */
-			es->ntlmssp_state = NULL;
+		if (ec->es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+			destroy_auth_ntlmssp(ec);
 		}
 		common_free_encryption_state(&ec->es);
 	}
@@ -76,6 +109,36 @@
 }
 
 /******************************************************************************
+ Create a server encryption context.
+******************************************************************************/
+
+static struct smb_srv_trans_enc_ctx *make_srv_encryption_context(enum smb_trans_enc_type smb_enc_type)
+{
+	struct smb_srv_trans_enc_ctx *ec;
+
+	ec = SMB_MALLOC_P(struct smb_srv_trans_enc_ctx);
+	if (!ec) {
+		return NULL;
+	}
+	ZERO_STRUCTP(partial_srv_trans_enc_ctx);
+	ec->es = SMB_MALLOC_P(struct smb_trans_enc_state);
+	if (!ec->es) {
+		SAFE_FREE(ec);
+		return NULL;
+	}
+	ZERO_STRUCTP(ec->es);
+	ec->es->smb_enc_type = smb_enc_type;
+	if (smb_enc_type == SMB_TRANS_ENC_NTLM) {
+		NTSTATUS status = make_auth_ntlmssp(ec);
+		if (!NT_STATUS_IS_OK(status)) {
+			srv_free_encryption_context(&ec);
+			return NULL;
+		}
+	}
+	return ec;
+}
+
+/******************************************************************************
  Free an encryption-allocated buffer.
 ******************************************************************************/
 
@@ -118,15 +181,50 @@
 ******************************************************************************/
 
 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
-static NTSTATUS srv_enc_spnego_gss_negotiate(char **ppdata, size_t *p_data_size, DATA_BLOB *psecblob)
+static NTSTATUS srv_enc_spnego_gss_negotiate(char **ppdata, size_t *p_data_size, DATA_BLOB secblob)
 {
 	return NT_STATUS_NOT_SUPPORTED;
 }
 #endif
 
 /******************************************************************************
+ Do the NTLM SPNEGO (or raw) encryption negotiation. Parameters are in/out.
+ Until success we do everything on the partial enc ctx.
+******************************************************************************/
+
+static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob, BOOL spnego_wrap)
+{
+	NTSTATUS status;
+	DATA_BLOB chal = data_blob(NULL, 0);
+	DATA_BLOB response = data_blob(NULL, 0);
+
+	partial_srv_trans_enc_ctx = make_srv_encryption_context(SMB_TRANS_ENC_NTLM);
+	if (!partial_srv_trans_enc_ctx) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, secblob, &chal);
+
+	/* status here should be NT_STATUS_MORE_PROCESSING_REQUIRED
+	 * for success ... */
+
+	if (spnego_wrap) {
+		response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
+		data_blob_free(&chal);
+	} else {
+		/* Return the raw blob. */
+		response = chal;
+	}
+
+	SAFE_FREE(*ppdata);
+	*ppdata = response.data;
+	*p_data_size = response.length;
+	return status;
+}
+
+/******************************************************************************
  Do the SPNEGO encryption negotiation. Parameters are in/out.
- Covers the NTLM case. Based off code in smbd/sesssionsetup.c
+ Based off code in smbd/sesssionsetup.c
  Until success we do everything on the partial enc ctx.
 ******************************************************************************/
 
@@ -135,10 +233,7 @@
 	NTSTATUS status;
 	DATA_BLOB blob = data_blob(NULL,0);
 	DATA_BLOB secblob = data_blob(NULL, 0);
-	DATA_BLOB chal = data_blob(NULL, 0);
-	DATA_BLOB response = data_blob(NULL, 0);
 	BOOL got_kerberos_mechanism = False;
-	struct smb_srv_trans_enc_ctx *ec = NULL;
 
 	blob = data_blob_const(*ppdata, *p_data_size);
 
@@ -151,59 +246,102 @@
 
 	srv_free_encryption_context(&partial_srv_trans_enc_ctx);
 
-	partial_srv_trans_enc_ctx = SMB_MALLOC_P(struct smb_srv_trans_enc_ctx);
-	if (!partial_srv_trans_enc_ctx) {
-		data_blob_free(&secblob);
-		return NT_STATUS_NO_MEMORY;
-	}
-	ZERO_STRUCTP(partial_srv_trans_enc_ctx);
-
 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
 	if (got_kerberos_mechanism && lp_use_kerberos_keytab()) ) {
-		status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, &secblob);
-		if (!NT_STATUS_IS_OK(status)) {
-			data_blob_free(&secblob);
+		status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob);
+	} else 
+#endif
+	{
+		status = srv_enc_ntlm_negotiate(ppdata, p_data_size, secblob, True);
+	}
+
+	data_blob_free(&secblob);
+
+	if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
+		srv_free_encryption_context(&partial_srv_trans_enc_ctx);
+	}
+
+	return status;
+}
+
+/******************************************************************************
+ Complete a SPNEGO encryption negotiation. Parameters are in/out.
+ We only get this for a NTLM auth second stage.
+******************************************************************************/
+
+static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_size)
+{
+	NTSTATUS status;
+	DATA_BLOB blob = data_blob(NULL,0);
+	DATA_BLOB auth = data_blob(NULL,0);
+	DATA_BLOB auth_reply = data_blob(NULL,0);
+	DATA_BLOB response = data_blob(NULL,0);
+	struct smb_srv_trans_enc_ctx *ec = partial_srv_trans_enc_ctx;
+
+	/* We must have a partial context here. */
+
+	if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
+		srv_free_encryption_context(&partial_srv_trans_enc_ctx);
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	blob = data_blob_const(*ppdata, *p_data_size);
+	if (!spnego_parse_auth(blob, &auth)) {
+		srv_free_encryption_context(&partial_srv_trans_enc_ctx);
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	status = auth_ntlmssp_update(ec->auth_ntlmssp_state, auth, &auth_reply);
+	data_blob_free(&auth);
+
+	response = spnego_gen_auth_response(&auth_reply, status, OID_NTLMSSP);
+	data_blob_free(&auth_reply);
+
+	SAFE_FREE(*ppdata);
+	*ppdata = response.data;
+	*p_data_size = response.length;
+	return status;
+}
+
+/******************************************************************************
+ Raw NTLM encryption negotiation. Parameters are in/out.
+ This function does both steps.
+******************************************************************************/
+
+static NTSTATUS srv_enc_raw_ntlm_auth(unsigned char **ppdata, size_t *p_data_size)
+{
+	NTSTATUS status;
+	DATA_BLOB blob = data_blob_const(*ppdata, *p_data_size);
+	DATA_BLOB response = data_blob(NULL,0);
+	struct smb_srv_trans_enc_ctx *ec;
+
+	if (!partial_srv_trans_enc_ctx) {
+		/* This is the initial step. */
+		status = srv_enc_ntlm_negotiate(ppdata, p_data_size, blob, False);
+		if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
 			srv_free_encryption_context(&partial_srv_trans_enc_ctx);
+			return nt_status_squash(status);
 		}
 		return status;
 	}
-#endif
 
-	/* Deal with an NTLM enc. setup. */
 	ec = partial_srv_trans_enc_ctx;
-
-	status = auth_ntlmssp_start(&ec->auth_ntlmssp_state);
-	if (!NT_STATUS_IS_OK(status)) {
+	if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
 		srv_free_encryption_context(&partial_srv_trans_enc_ctx);
-		return nt_status_squash(status);
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	status = auth_ntlmssp_update(ec->auth_ntlmssp_state, secblob, &chal);
-	data_blob_free(&secblob);
-
-	/* status here should be NT_STATUS_MORE_PROCESSING_REQUIRED
-	 * for success ... */
-
-	response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
-	data_blob_free(&chal);
-
+	/* Second step. */
+	status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, blob, &response);
+
+	/* Return the raw blob. */
 	SAFE_FREE(*ppdata);
 	*ppdata = response.data;
 	*p_data_size = response.length;
-
 	return status;
 }
 
 /******************************************************************************
- Complete a SPNEGO encryption negotiation. Parameters are in/out.
-******************************************************************************/
-
-static NTSTATUS srv_enc_spnego_auth(unsigned char **ppdata, size_t *p_data_size)
-{
-	return NT_STATUS_NOT_SUPPORTED;
-}
-
-/******************************************************************************
  Do the SPNEGO encryption negotiation. Parameters are in/out.
 ******************************************************************************/
 
@@ -225,25 +363,67 @@
 	}
 
 	if (pdata[0] == ASN1_CONTEXT(1)) {
-		/* Its a auth packet */
-		return srv_enc_spnego_auth(ppdata, p_data_size);
-	}
-
-	return NT_STATUS_INVALID_PARAMETER;
-}
-
-/******************************************************************************
- Negotiation was successful - turn on server-side encryption.
-******************************************************************************/
-
-void srv_encryption_start(void)
-{
+		/* It's an auth packet */
+		return srv_enc_spnego_ntlm_auth(ppdata, p_data_size);
+	}
+
+	/* Maybe it's a raw unwrapped auth ? */
+	if (*p_data_size < 7) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (strncmp((char *)pdata, "NTLMSSP", 7) == 0) {
+		return srv_enc_raw_ntlm_auth(ppdata, p_data_size);
+	}
+
+	DEBUG(1,("srv_request_encryption_setup: Unknown packet\n"));
+
+	return NT_STATUS_LOGON_FAILURE;
+}
+
+/******************************************************************************
+ Negotiation was successful - turn on server-side encryption.
+******************************************************************************/
+
+static NTSTATUS check_enc_good(struct smb_srv_trans_enc_ctx *ec)
+{
+	if (!ec || !ec->es) {
+		return NT_STATUS_LOGON_FAILURE;
+	}
+
+	if (ec->es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+		if ((ec->es->ntlmssp_state->neg_flags & (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL)) !=
+				(NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL)) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+	}
+	/* Todo - check gssapi case. */
+
+	return NT_STATUS_OK;
+}
+
+/******************************************************************************
+ Negotiation was successful - turn on server-side encryption.
+******************************************************************************/
+
+NTSTATUS srv_encryption_start(void)
+{
+	NTSTATUS status;
+
+	/* Check that we are really doing sign+seal. */
+	status = check_enc_good(partial_srv_trans_enc_ctx);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+	/* Throw away the context we're using currently (if any). */
 	srv_free_encryption_context(&srv_trans_enc_ctx);
+
 	/* Steal the partial pointer. Deliberate shallow copy. */
 	srv_trans_enc_ctx = partial_srv_trans_enc_ctx;
 	srv_trans_enc_ctx->es->enc_on = True;
 
 	partial_srv_trans_enc_ctx = NULL;
+	return NT_STATUS_OK;
 }
 
 /******************************************************************************

=== modified file 'source/smbd/trans2.c'
--- a/source/smbd/trans2.c	2007-03-20 05:03:29 +0000
+++ b/source/smbd/trans2.c	2007-03-21 05:01:14 +0000
@@ -2769,7 +2769,7 @@
 
 				DEBUG( 4,("call_trans2setfsinfo: request transport encrption.\n"));
 
-				status = srv_request_encryption_setup((unsigned char **)&pdata, &data_len);
+				status = srv_request_encryption_setup((unsigned char **)ppdata, &data_len);
 
 				if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
 					error_packet_set(outbuf, 0, 0, status, __LINE__,__FILE__);
@@ -2777,11 +2777,14 @@
 					return ERROR_NT(status);
 				}
 
-				send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes);
+				send_trans2_replies( outbuf, bufsize, params, 0, *ppdata, data_len, max_data_bytes);
 
 				if (NT_STATUS_IS_OK(status)) {
 					/* Server-side transport encryption is now *on*. */
-					srv_encryption_start();
+					status = srv_encryption_start();
+					if (!NT_STATUS_IS_OK(status)) {
+						exit_server_cleanly("Failure in setting up encrypted transport");
+					}
 				}
 				return -1;
 			}



More information about the samba-cvs mailing list