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