r13407: Change the credentials code to be more like the Samba4 structure,
authorJeremy Allison <jra@samba.org>
Thu, 9 Feb 2006 07:03:23 +0000 (07:03 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:09:59 +0000 (11:09 -0500)
makes fixes much easier to port. Fix the size of dc->sess_key to
be 16 bytes, not 8 bytes - only store 8 bytes in the inter-smbd
store in secrets.tdb though. Should fix some uses of the dc->sess_key
where we where assuming we could read 16 bytes.
Jeremy.

source/include/ntdomain.h
source/include/rpc_dce.h
source/libsmb/credentials.c
source/libsmb/smbdes.c
source/passdb/secrets.c
source/rpc_parse/parse_rpc.c
source/rpc_server/srv_netlog_nt.c

index a30b7243727b924ca37285d77b07b9cc3b891d39..82e212c0ca0a966abcf8b31f9afc594a7688be62 100644 (file)
@@ -140,7 +140,7 @@ struct dcinfo {
        DOM_CHAL clnt_chal; /* Client credential */
        DOM_CHAL srv_chal;  /* Server credential */
  
-       uchar  sess_key[8]; /* Session key */
+       uchar  sess_key[16]; /* Session key - 8 bytes followed by 8 zero bytes */
        uchar  mach_pw[16];   /* md4(machine password) */
 
        fstring mach_acct;  /* Machine name we've authenticated. */
index e718d92271c70042208d1384053a24f097b829e6..218cad336de4eface4e2536bd2dc28b71e636a1d 100644 (file)
@@ -90,12 +90,19 @@ enum RPC_PKT_TYPE {
 #define RPC_AUTH_SCHANNEL_SIGN_ONLY_CHK_LEN    0x18
 
 
+#define NETLOGON_EXTRA_SIDS                        0x0020
+#define NETLOGON_RESOURCE_GROUPS                   0x0200
+#define NETLOGON_NEG_ARCFOUR                   0x00000004
+#define NETLOGON_NEG_128BIT                    0x00004000
+#define NETLOGON_NEG_SCHANNEL                  0x40000000
+
 /* The 7 here seems to be required to get Win2k not to downgrade us
    to NT4.  Actually, anything other than 1ff would seem to do... */
 #define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
-#define NETLOGON_NEG_SCHANNEL                  0x40000000
 #define NETLOGON_NEG_DOMAIN_TRUST_ACCOUNT      0x2010b000
+/* these are the flags that ADS clients use */
+#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL)
 
 enum schannel_direction {
        SENDER_IS_INITIATOR,
index ad06cd9015f33e9e49f73374b66885943b237d6b..795c30d12d69433c2417f5189a28508cf07c8be3 100644 (file)
@@ -36,38 +36,52 @@ char *credstr(const uchar *cred)
 
 
 /****************************************************************************
- Setup the session key. 
- Input: 8 byte challenge block
-       8 byte server challenge block
-      16 byte md4 encrypted password
- Output:
-      16 byte session key (last 8 bytes zero).
+ Setup the session key and the client and server creds in dc.
+ Used by both client and server creds setup.
 ****************************************************************************/
 
-static void cred_create_session_key(const DOM_CHAL *clnt_chal_in,
+static void creds_init_64(struct dcinfo *dc,
+                       const DOM_CHAL *clnt_chal_in,
                        const DOM_CHAL *srv_chal_in,
-                       const uchar *pass_in, 
-                       uchar session_key_out[16])
+                       const char mach_pw[16])
 {
        uint32 sum[2];
        unsigned char sum2[8];
 
+       /* Just in case this isn't already there */
+       memcpy(dc->mach_pw, mach_pw, 16);
+
        sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0);
        sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4);
 
        SIVAL(sum2,0,sum[0]);
        SIVAL(sum2,4,sum[1]);
 
-       cred_hash1(session_key_out, sum2, pass_in);
-       memset(&session_key_out[8], '\0', 8);
+       ZERO_STRUCT(dc->sess_key);
 
-       /* debug output */
-       DEBUG(4,("cred_create_session_key\n"));
+       des_crypt128(dc->sess_key, sum2, dc->mach_pw);
 
+       /* debug output */
+       DEBUG(5,("creds_init_64\n"));
        DEBUG(5,("      clnt_chal_in: %s\n", credstr(clnt_chal_in->data)));
        DEBUG(5,("      srv_chal_in : %s\n", credstr(srv_chal_in->data)));
        DEBUG(5,("      clnt+srv : %s\n", credstr(sum2)));
-       DEBUG(5,("      sess_key_out : %s\n", credstr(session_key_out)));
+       DEBUG(5,("      sess_key_out : %s\n", credstr(dc->sess_key)));
+
+       /* Generate the next client and server creds. */
+       
+       des_crypt112(dc->clnt_chal.data,                /* output */
+                       clnt_chal_in->data,             /* input */
+                       dc->sess_key,                   /* input */
+                       1);
+
+       des_crypt112(dc->srv_chal.data,                 /* output */
+                       srv_chal_in->data,              /* input */
+                       dc->sess_key,                   /* input */
+                       1);
+
+       /* Seed is the client chal. */
+       memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
 }
 
 /****************************************************************************
@@ -88,7 +102,7 @@ static void creds_step(struct dcinfo *dc)
                                                                                                    
        DEBUG(5,("\tseed+seq   %s\n", credstr(time_chal.data) ));
 
-       cred_hash2(dc->clnt_chal.data, time_chal.data, dc->sess_key);
+       des_crypt112(dc->clnt_chal.data, time_chal.data, dc->sess_key, 1);
 
        DEBUG(5,("\tCLIENT      %s\n", credstr(dc->clnt_chal.data) ));
 
@@ -97,12 +111,11 @@ static void creds_step(struct dcinfo *dc)
 
        DEBUG(5,("\tseed+seq+1   %s\n", credstr(time_chal.data) ));
 
-       cred_hash2(dc->srv_chal.data, time_chal.data, dc->sess_key);
+       des_crypt112(dc->srv_chal.data, time_chal.data, dc->sess_key, 1);
 
        DEBUG(5,("\tSERVER      %s\n", credstr(dc->srv_chal.data) ));
 }
 
-
 /****************************************************************************
  Create a server credential struct.
 ****************************************************************************/
@@ -117,29 +130,14 @@ void creds_server_init(struct dcinfo *dc,
        DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) ));
        dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16);
 
-       /* Just in case this isn't already there */
-       memcpy(dc->mach_pw, mach_pw, 16);
-
-       /* Generate the session key. */
-       cred_create_session_key(clnt_chal,              /* Stored client challenge. */
-                               srv_chal,               /* Stored server challenge. */
-                               dc->mach_pw,              /* input machine password. */
-                               dc->sess_key);            /* output session key. */
+       /* Generate the session key and the next client and server creds. */
+       creds_init_64(dc,
+                       clnt_chal,
+                       srv_chal,
+                       mach_pw);
 
        dump_data_pw("creds_server_init: session key", dc->sess_key, 16);
 
-       /* Generate the next client and server creds. */
-       cred_hash2(dc->clnt_chal.data,                  /* output */
-                       clnt_chal->data,                /* input */
-                       dc->sess_key);                  /* input */
-
-       cred_hash2(dc->srv_chal.data,                   /* output */
-                       srv_chal->data,                 /* input */
-                       dc->sess_key);                  /* input */
-
-       /* Seed is the client chal. */
-       memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
-
        DEBUG(10,("creds_server_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
        DEBUG(10,("creds_server_init: server : %s\n", credstr(dc->srv_chal.data) ));
        DEBUG(10,("creds_server_init: seed : %s\n", credstr(dc->seed_chal.data) ));
@@ -214,29 +212,14 @@ void creds_client_init(struct dcinfo *dc,
        DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) ));
        dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16);
 
-       /* Just in case this isn't already there */
-       memcpy(dc->mach_pw, mach_pw, 16);
-
-       /* Generate the session key. */
-       cred_create_session_key(clnt_chal,              /* Stored client challenge. */
-                               srv_chal,               /* Stored server challenge. */
-                               dc->mach_pw,              /* input machine password. */
-                               dc->sess_key);            /* output session key. */
+       /* Generate the session key and the next client and server creds. */
+       creds_init_64(dc,
+                       clnt_chal,
+                       srv_chal,
+                       mach_pw);
 
        dump_data_pw("creds_client_init: session key", dc->sess_key, 16);
 
-       /* Generate the next client and server creds. */
-       cred_hash2(dc->clnt_chal.data,  /* output */
-                       clnt_chal->data,                /* input */
-                       dc->sess_key);                  /* input */
-
-       cred_hash2(dc->srv_chal.data,           /* output */
-                       srv_chal->data,                 /* input */
-                       dc->sess_key);                  /* input */
-
-       /* Seed is the client cred. */
-       memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8);
-
        DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) ));
        DEBUG(10,("creds_client_init: server : %s\n", credstr(dc->srv_chal.data) ));
        DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) ));
index 4378385f3fd0cf9b4f99d5a410e79466dad1e4f4..ee43f4beee5981d0324df4f1e237033bc94c62b8 100644 (file)
@@ -258,7 +258,8 @@ static void dohash(char *out, char *in, char *key, int forw)
        permute(out, rl, perm6, 64);
 }
 
-static void str_to_key(const unsigned char *str,unsigned char *key)
+/* Convert a 7 byte string to an 8 byte key. */
+static void str_to_key(const unsigned char str[7], unsigned char key[8])
 {
        int i;
 
@@ -330,7 +331,8 @@ void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *
         des_crypt56(out+8, in+8, p14+7, 1);
 }
 
-void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char *key)
+/* forward des encryption with a 128 bit key */
+void des_crypt128(unsigned char out[8], const unsigned char in[8], const unsigned char key[16])
 {
        unsigned char buf[8];
 
@@ -338,25 +340,49 @@ void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char
        des_crypt56(out, buf, key+9, 1);
 }
 
-void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key)
+/* forward des encryption with a 64 bit key */
+void des_crypt64(unsigned char out[8], const unsigned char in[8], const unsigned char key[8])
 {
        unsigned char buf[8];
-       static unsigned char key2[8];
+       unsigned char key2[8];
 
+       memset(key2,'\0',8);
        des_crypt56(buf, in, key, 1);
        key2[0] = key[7];
        des_crypt56(out, buf, key2, 1);
 }
 
+/* des encryption with a 112 bit (14 byte) key */
+/* Note that if the forw is 1, and key is actually 8 bytes of key, followed by 6 bytes of zeros,
+   this is identical to des_crypt64(). JRA. */
+
+void des_crypt112(unsigned char out[8], const unsigned char in[8], const unsigned char key[14], int forw)
+{
+       unsigned char buf[8];
+       des_crypt56(buf, in, key, forw);
+       des_crypt56(out, buf, key+7, forw);
+}
+
 void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw)
 {
-        static unsigned char key2[8];
+        unsigned char key2[8];
 
+       memset(key2,'\0',8);
         des_crypt56(out, in, key, forw);
         key2[0] = key[7];
         des_crypt56(out + 8, in + 8, key2, forw);
 }
 
+/* des encryption of a 16 byte lump of data with a 112 bit key */
+/* Note that if the key is actually 8 bytes of key, followed by 6 bytes of zeros,
+   this is identical to cred_hash3(). JRA. */
+
+void des_crypt112_16(unsigned char out[16], unsigned char in[16], const unsigned char key[14], int forw)
+{
+       des_crypt56(out, in, key, forw);
+       des_crypt56(out + 8, in + 8, key+7, forw);
+}
+
 /*****************************************************************
  arc4 crypt/decrypt with a 16 byte key.
 *****************************************************************/
index 69bafc7ce5707c60180cea5fa468ce22ad5013de..8f93bec9bc760f6b6612763b2ced8119b8a67a1f 100644 (file)
@@ -1063,6 +1063,7 @@ BOOL secrets_restore_schannel_session_info(TALLOC_CTX *mem_ctx,
        memcpy(pdc->clnt_chal.data, pclnt_chal, 8);
        memcpy(pdc->srv_chal.data, psrv_chal, 8);
        memcpy(pdc->sess_key, psess_key, 8);
+       memset(&pdc->sess_key[8], '\0', 8); /* key followed by 8 bytes of zero. */
        memcpy(pdc->mach_pw, pmach_pw, 16);
 
        /* We know these are true so didn't bother to store them. */
index 544d139acb363bc06a3ee13a69651960d2497467..79dfc05e43cbd87aa6c0ae62572adff93a710e85 100644 (file)
@@ -848,4 +848,3 @@ BOOL smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len,
 
        return True;
 }
-
index d6ec31a9857fa6d80a0142ab410ee165f11284b5..784f7336172716e4d01665990c8d4b45a524ccd2 100644 (file)
@@ -817,7 +817,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                fstring group_sid_string;
                uchar user_session_key[16];
                uchar lm_session_key[16];
-               uchar netlogon_sess_key[16];
 
                sampw = server_info->sam_account;
 
@@ -859,23 +858,20 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                        return status;
                }
 
-               ZERO_STRUCT(netlogon_sess_key);
-               memcpy(netlogon_sess_key, p->dc->sess_key, 8);
                if (server_info->user_session_key.length) {
                        memcpy(user_session_key,
                               server_info->user_session_key.data, 
                               MIN(sizeof(user_session_key),
                                   server_info->user_session_key.length));
-                       SamOEMhash(user_session_key, netlogon_sess_key, 16);
+                       SamOEMhash(user_session_key, p->dc->sess_key, 16);
                }
                if (server_info->lm_session_key.length) {
                        memcpy(lm_session_key,
                               server_info->lm_session_key.data, 
                               MIN(sizeof(lm_session_key),
                                   server_info->lm_session_key.length));
-                       SamOEMhash(lm_session_key, netlogon_sess_key, 16);
+                       SamOEMhash(lm_session_key, p->dc->sess_key, 16);
                }
-               ZERO_STRUCT(netlogon_sess_key);
                
                init_net_user_info3(p->mem_ctx, usr_info, 
                                    user_rid,