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

------------------------------------------------------------
revno: 5295
revision-id: [EMAIL PROTECTED]
parent: [EMAIL PROTECTED]
parent: [EMAIL PROTECTED]
committer: Michael Adam <[EMAIL PROTECTED]>
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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:03:34 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:03:03 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:02:34 -0500
    message:
      [EMAIL PROTECTED] (r21901)  2007-03-20 20:21:16 -0500 (Tue, 20 Mar 2007)
          
          Don't use fstrcat when you mean fstrcpy. Doh !
          Jeremy.
          
    ------------------------------------------------------------
    merged: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:02:07 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:01:40 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:01:14 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Wed 2007-03-21 00:00:42 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 18:01:43 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 18:01:24 -0500
    message:
      [EMAIL PROTECTED] (r21893)  2007-03-20 16:21:04 -0500 (Tue, 20 Mar 2007)
          
          Update comments so they actually reflect reality...
          
          
          rafal
          
          
    ------------------------------------------------------------
    merged: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 18:00:54 -0500
    message:
      [EMAIL PROTECTED] (r21892)  2007-03-20 15:47:17 -0500 (Tue, 20 Mar 2007)
          
          Mini-Patch from Michael
    ------------------------------------------------------------
    merged: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 18:00:28 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 12:08:10 -0500
    message:
      [EMAIL PROTECTED] (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: [EMAIL PROTECTED]
    parent: [EMAIL PROTECTED]
    committer: [EMAIL PROTECTED]
    branch nick: SAMBA_3_0.bzr
    timestamp: Tue 2007-03-20 10:23:20 -0500
    message:
      [EMAIL PROTECTED] (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;
                        }

Reply via email to