Add the capability to set "smb encrypt = required"
authorJeremy Allison <jra@samba.org>
Fri, 28 Dec 2007 07:51:03 +0000 (23:51 -0800)
committerJeremy Allison <jra@samba.org>
Fri, 28 Dec 2007 07:51:03 +0000 (23:51 -0800)
on a share (or global) and have the server reply with
ACCESS_DENIED for all non-encrypted traffic (except
that used to query encryption requirements and set
encryption state).
Jeremy.
(This used to be commit d241bfa57729bb934ada6beabf842a2ca7b4f8a2)

source3/client/client.c
source3/include/smb.h
source3/smbd/process.c
source3/smbd/service.c
source3/smbd/trans2.c

index 665a051190cba35abe7ee7fb83cc1d4978a8c997..53669bc8d093f74c59a1047daba3b59d343b8029 100644 (file)
@@ -2466,17 +2466,30 @@ static int cmd_posix(void)
                        return 1;
                }
        }
+       if (caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP) {
+               caps = talloc_asprintf_append(caps, "posix_encrypt ");
+               if (!caps) {
+                       return 1;
+               }
+       }
+       if (caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) {
+               caps = talloc_asprintf_append(caps, "mandatory_posix_encrypt ");
+               if (!caps) {
+                       return 1;
+               }
+       }
 
        if (*caps && caps[strlen(caps)-1] == ' ') {
                caps[strlen(caps)-1] = '\0';
        }
+
+       d_printf("Server supports CIFS capabilities %s\n", caps);
+
        if (!cli_set_unix_extensions_capabilities(cli, major, minor, caplow, caphigh)) {
                d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n", cli_errstr(cli));
                return 1;
        }
 
-       d_printf("Selecting server supported CIFS capabilities %s\n", caps);
-
        if (caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
                CLI_DIRSEP_CHAR = '/';
                *CLI_DIRSEP_STR = '/';
index 2ffd530fb06e85a9d02c16b09159346022b7f09c..aca0009688671f760d742b068dd82ad6d5cf9acf 100644 (file)
@@ -658,6 +658,7 @@ typedef struct connection_struct {
        bool used;
        int num_files_open;
        unsigned int num_smb_operations; /* Count of smb operations on this tree. */
+       int encrypt_level;
 
        /* Semantics requested by the client or forced by the server config. */
        bool case_sensitive;
index 1260d52c7717a5ca761557926f70563bf8965854..48a6d18bc92c6432c909079536b8b8e1824c5699 100644 (file)
@@ -1457,6 +1457,16 @@ static void switch_message(uint8 type, struct smb_request *req, int size)
                        reply_doserror(req, ERRSRV, ERRaccess);
                        return;
                }
+
+               if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
+                       /* An encrypted packet has 0xFF 'E' at offset 4
+                        * which is little endian 0x45FF */
+                       uint8 com = CVAL(req->inbuf,smb_com);
+                       if (com != SMBtrans2 && com != SMBtranss2) {
+                               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+                               return;
+                       }
+               }
                conn->num_smb_operations++;
        }
 
index 8e69a3b3817482bda2c88921049ef6ea7270fc20..65fc8181446aecd2b54559fca492008249fac0c3 100644 (file)
@@ -795,6 +795,8 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,
        conn->case_preserve = lp_preservecase(snum);
        conn->short_case_preserve = lp_shortpreservecase(snum);
 
+       conn->encrypt_level = lp_smb_encrypt(snum);
+
        conn->veto_list = NULL;
        conn->hide_list = NULL;
        conn->veto_oplock_list = NULL;
index ee4787199e5f0baa9caaf49e5b5dc2257aff871d..7625eaed7df40ae0a755b869801d294f4205d903 100644 (file)
@@ -2430,6 +2430,16 @@ static void call_trans2qfsinfo(connection_struct *conn,
 
        info_level = SVAL(params,0);
 
+       if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
+               if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
+                       DEBUG(0,("call_trans2qfsinfo: encryption required "
+                               "and info level 0x%x sent.\n",
+                               (unsigned int)info_level));
+                       reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+                       return;
+               }
+       }
+
        DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
 
        if(SMB_VFS_STAT(conn,".",&st)!=0) {
@@ -2736,7 +2746,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
                                return;
                        }
 
-                       switch (lp_smb_encrypt(SNUM(conn))) {
+                       switch (conn->encrypt_level) {
                        case 0:
                                encrypt_caps = 0;
                                break;
@@ -2968,6 +2978,16 @@ static void call_trans2setfsinfo(connection_struct *conn,
 
        info_level = SVAL(params,2);
 
+       if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
+               if (info_level != SMB_REQUEST_TRANSPORT_ENCRYPTION) {
+                       DEBUG(0,("call_trans2setfsinfo: encryption required "
+                               "and info level 0x%x sent.\n",
+                               (unsigned int)info_level));
+                       reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+                       return;
+               }
+       }
+
        switch(info_level) {
                case SMB_SET_CIFS_UNIX_INFO:
                        {
@@ -7060,6 +7080,17 @@ static void handle_trans2(connection_struct *conn, struct smb_request *req,
                SSVAL(req->inbuf,smb_flg2,req->flags2);
        }
 
+       if (conn->encrypt_level == Required && SVAL(req->inbuf,4) != 0x45FF ) {
+               if (state->call != TRANSACT2_QFSINFO &&
+                               state->call != TRANSACT2_SETFSINFO) {
+                       DEBUG(0,("handle_trans2: encryption required "
+                               "with call 0x%x\n",
+                               (unsigned int)state->call));
+                       reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+                       return;
+               }
+       }
+
        /* Now we must call the relevant TRANS2 function */
        switch(state->call)  {
        case TRANSACT2_OPEN: