summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-02-09 07:03:23 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:09:59 -0500
commitad8b47a2ba4e81420bc2272e8438a727cc2223ee (patch)
treeb6f23560649f3b54aa3458d3c8667f145805ec5b
parentcf7c47aac990f67e1829a7e4b9d3550b7e93739b (diff)
downloadsamba-ad8b47a2ba4e81420bc2272e8438a727cc2223ee.tar.gz
samba-ad8b47a2ba4e81420bc2272e8438a727cc2223ee.tar.bz2
samba-ad8b47a2ba4e81420bc2272e8438a727cc2223ee.zip
r13407: Change the credentials code to be more like the Samba4 structure,
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. (This used to be commit 5b3c2e63c73fee8949108abe19ac7a448a033a7f)
-rw-r--r--source3/include/ntdomain.h2
-rw-r--r--source3/include/rpc_dce.h11
-rw-r--r--source3/libsmb/credentials.c97
-rw-r--r--source3/libsmb/smbdes.c36
-rw-r--r--source3/passdb/secrets.c1
-rw-r--r--source3/rpc_parse/parse_rpc.c1
-rw-r--r--source3/rpc_server/srv_netlog_nt.c8
7 files changed, 84 insertions, 72 deletions
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index a30b724372..82e212c0ca 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -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. */
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h
index e718d92271..218cad336d 100644
--- a/source3/include/rpc_dce.h
+++ b/source3/include/rpc_dce.h
@@ -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,
diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c
index ad06cd9015..795c30d12d 100644
--- a/source3/libsmb/credentials.c
+++ b/source3/libsmb/credentials.c
@@ -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) ));
diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c
index 4378385f3f..ee43f4beee 100644
--- a/source3/libsmb/smbdes.c
+++ b/source3/libsmb/smbdes.c
@@ -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.
*****************************************************************/
diff --git a/source3/passdb/secrets.c b/source3/passdb/secrets.c
index 69bafc7ce5..8f93bec9bc 100644
--- a/source3/passdb/secrets.c
+++ b/source3/passdb/secrets.c
@@ -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. */
diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c
index 544d139acb..79dfc05e43 100644
--- a/source3/rpc_parse/parse_rpc.c
+++ b/source3/rpc_parse/parse_rpc.c
@@ -848,4 +848,3 @@ BOOL smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len,
return True;
}
-
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index d6ec31a985..784f733617 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -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,