s3-auth use auth_user_info not netr_SamInfo3 in auth3_session_info
[ira/wip.git] / source3 / modules / vfs_smb_traffic_analyzer.c
index dcb01994c32e3c3732e2ba9054e465df6990b069..5f05fa68d1ee30bd61a75359c29bec696987d9ff 100644 (file)
  */
 
 #include "includes.h"
+#include "smbd/smbd.h"
+#include "../smbd/globals.h"
 #include "../lib/crypto/crypto.h"
 #include "vfs_smb_traffic_analyzer.h"
+#include "../libcli/security/security.h"
+#include "secrets.h"
+#include "../librpc/gen_ndr/ndr_netlogon.h"
+#include "auth.h"
+#include "../lib/tsocket/tsocket.h"
 
 /* abstraction for the send_over_network function */
 enum sock_type {INTERNET_SOCKET = 0, UNIX_DOMAIN_SOCKET};
@@ -168,7 +175,7 @@ static char *smb_traffic_analyzer_encrypt( TALLOC_CTX *ctx,
        char *output;
        unsigned char crypted[18];
        if (akey == NULL) return NULL;
-       samba_AES_set_encrypt_key((unsigned char *) akey, 128, &key);
+       samba_AES_set_encrypt_key((const unsigned char *) akey, 128, &key);
        s1 = strlen(str) / 16;
        s2 = strlen(str) % 16;
        for (h = 0; h < s2; h++) *(filler+h)=*(str+(s1*16)+h);
@@ -177,10 +184,10 @@ static char *smb_traffic_analyzer_encrypt( TALLOC_CTX *ctx,
        output = talloc_array(ctx, char, (s1*16)+17 );
        d=0;
        for (h = 0; h < s1; h++) {
-               samba_AES_encrypt((unsigned char *) str+(16*h), crypted, &key);
+               samba_AES_encrypt((const unsigned char *) str+(16*h), crypted, &key);
                for (d = 0; d<16; d++) output[d+(16*h)]=crypted[d];
        }
-       samba_AES_encrypt( (unsigned char *) str+(16*h), filler, &key );
+       samba_AES_encrypt( (const unsigned char *) str+(16*h), filler, &key );
        for (d = 0;d < 16; d++) output[d+(16*h)]=*(filler+d);
        *len = (s1*16)+16;
        return output;  
@@ -296,8 +303,11 @@ static char *smb_traffic_analyzer_create_string( TALLOC_CTX *ctx,
        char *timestr = NULL;
        char *sidstr = NULL;
        char *usersid = NULL;
+       char *raddr = NULL;
        char *buf = NULL;
        char *vfs_operation_str = NULL;
+       const char *service_name = lp_const_servicename(handle->conn->params->service);
+
        /*
         * first create the data that is transfered with any VFS op
         * These are, in the following order:
@@ -308,6 +318,7 @@ static char *smb_traffic_analyzer_create_string( TALLOC_CTX *ctx,
         * 4.affected share
         * 5.domain
         * 6.timestamp
+        * 7.IP Addresss of client
         */
 
        /*
@@ -325,13 +336,19 @@ static char *smb_traffic_analyzer_create_string( TALLOC_CTX *ctx,
         * anonymized if needed, by the calling function.
         */
        usersid = dom_sid_string( common_data_count_str,
-               &handle->conn->server_info->ptok->user_sids[0]);
+               &handle->conn->session_info->security_token->sids[0]);
 
        sidstr = smb_traffic_analyzer_anonymize(
                common_data_count_str,
                usersid,
                handle);
-       
+
+       raddr = tsocket_address_inet_addr_string(handle->conn->sconn->remote_address,
+                                                ctx);
+       if (raddr == NULL) {
+               return NULL;
+       }
+
        /* time stamp */
        timestr = talloc_asprintf( common_data_count_str, \
                "%04d-%02d-%02d %02d:%02d:%02d.%03d", \
@@ -345,7 +362,7 @@ static char *smb_traffic_analyzer_create_string( TALLOC_CTX *ctx,
        len = strlen( timestr );
        /* create the string of common data */
        buf = talloc_asprintf(ctx,
-               "%s%04u%s%04u%s%04u%s%04u%s%04u%s%04u%s",
+               "%s%04u%s%04u%s%04u%s%04u%s%04u%s%04u%s%04u%s",
                common_data_count_str,
                (unsigned int) strlen(vfs_operation_str),
                vfs_operation_str,
@@ -353,13 +370,15 @@ static char *smb_traffic_analyzer_create_string( TALLOC_CTX *ctx,
                username,
                (unsigned int) strlen(sidstr),
                sidstr,
-               (unsigned int) strlen(handle->conn->connectpath),
-               handle->conn->connectpath,
+               (unsigned int) strlen(service_name),
+               service_name,
                (unsigned int)
-               strlen(pdb_get_domain(handle->conn->server_info->sam_account)),
-               pdb_get_domain(handle->conn->server_info->sam_account),
+               strlen(handle->conn->session_info->info->domain_name),
+               handle->conn->session_info->info->domain_name,
                (unsigned int) strlen(timestr),
-               timestr);
+               timestr,
+               (unsigned int) strlen(raddr),
+               raddr);
 
        talloc_free(common_data_count_str);
 
@@ -406,6 +425,17 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
         */
        char state_flags[9] = "000000\0";
 
+       /**
+        * The first byte of the state flag string represents
+        * the modules protocol subversion number, defined
+        * in smb_traffic_analyzer.h. smbtatools/smbtad are designed
+        * to handle not yet implemented protocol enhancements
+        * by ignoring them. By recognizing the SMBTA_SUBRELEASE
+        * smbtatools can tell the user to update the client
+        * software.
+        */
+       state_flags[0] = SMBTA_SUBRELEASE;
+
        SMB_VFS_HANDLE_GET_DATA(handle, rf_sock, struct refcounted_sock, return);
 
        if (rf_sock == NULL || rf_sock->sock == -1) {
@@ -415,7 +445,7 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
        }
 
        GetTimeOfDay(&tv);
-       tv_sec = convert_timespec_to_time_t(convert_timeval_to_timespec(tv));
+       tv_sec = tv.tv_sec;
        tm = localtime(&tv_sec);
        if (!tm) {
                return;
@@ -429,7 +459,7 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
         * function.
         */
        username = smb_traffic_analyzer_anonymize( talloc_tos(),
-                       handle->conn->server_info->sanitized_username,
+                       handle->conn->session_info->unix_info->sanitized_username,
                        handle);
 
        if (!username) {
@@ -441,7 +471,7 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
                                        "protocol_version", NULL );
 
 
-       if ( protocol_version == NULL || strcmp( protocol_version,"V1") == 0) {
+       if (protocol_version != NULL && strcmp(protocol_version,"V1") == 0) {
 
                struct rw_data *s_data = (struct rw_data *) data;
 
@@ -460,7 +490,7 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
                        "\"%04d-%02d-%02d %02d:%02d:%02d.%03d\"\n",
                        (unsigned int) s_data->len,
                        username,
-                       pdb_get_domain(handle->conn->server_info->sam_account),
+                       handle->conn->session_info->info->domain_name,
                        Write ? 'W' : 'R',
                        handle->conn->connectpath,
                        s_data->filename,
@@ -471,13 +501,17 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
                        tm->tm_min,
                        tm->tm_sec,
                        (int)seconds);
+               len = strlen(str);
                if (write_data(rf_sock->sock, str, len) != len) {
                        DEBUG(1, ("smb_traffic_analyzer_send_data_socket: "
                        "error sending V1 protocol data to socket!\n"));
                return;
                }
 
-       } else if ( strcmp( protocol_version, "V2") == 0) {
+       } else {
+               /**
+                * Protocol 2 is used by default.
+                */
 
                switch( vfs_operation ) {
                case vfs_id_open: ;
@@ -545,10 +579,6 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
                        return;
                }
 
-       } else {
-               DEBUG(1, ("smb_traffic_analyzer_send_data_socket: "
-                       "error, unkown protocol given!\n"));
-               return;
        }
 
        if (!str) {
@@ -571,6 +601,7 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle,
                        " found, encrypting data!\n"));
                output = smb_traffic_analyzer_encrypt( talloc_tos(),
                                                akey, str, &len);
+               SAFE_FREE(akey);
                header = smb_traffic_analyzer_create_header( talloc_tos(),
                                                state_flags, len);
 
@@ -643,7 +674,7 @@ static int smb_traffic_analyzer_connect(struct vfs_handle_struct *handle,
                rf_sock->ref_count++;
        } else {
                /* New connection. */
-               rf_sock = TALLOC_ZERO_P(NULL, struct refcounted_sock);
+               rf_sock = talloc_zero(NULL, struct refcounted_sock);
                if (rf_sock == NULL) {
                        SMB_VFS_NEXT_DISCONNECT(handle);
                        errno = ENOMEM;
@@ -735,6 +766,44 @@ static int smb_traffic_analyzer_mkdir(vfs_handle_struct *handle, \
        return s_data.result;
 }
 
+static ssize_t smb_traffic_analyzer_sendfile(vfs_handle_struct *handle,
+                               int tofd,
+                               files_struct *fromfsp,
+                               const DATA_BLOB *hdr,
+                               SMB_OFF_T offset,
+                               size_t n)
+{
+       struct rw_data s_data;
+       s_data.len = SMB_VFS_NEXT_SENDFILE(handle,
+                       tofd, fromfsp, hdr, offset, n);
+       s_data.filename = fromfsp->fsp_name->base_name;
+       DEBUG(10, ("smb_traffic_analyzer_sendfile: sendfile(r): %s\n",
+               fsp_str_dbg(fromfsp)));
+       smb_traffic_analyzer_send_data(handle,
+               &s_data,
+               vfs_id_read);
+       return s_data.len;
+}
+
+static ssize_t smb_traffic_analyzer_recvfile(vfs_handle_struct *handle,
+                               int fromfd,
+                               files_struct *tofsp,
+                               SMB_OFF_T offset,
+                               size_t n)
+{
+       struct rw_data s_data;
+       s_data.len = SMB_VFS_NEXT_RECVFILE(handle,
+                       fromfd, tofsp, offset, n);
+       s_data.filename = tofsp->fsp_name->base_name;
+       DEBUG(10, ("smb_traffic_analyzer_recvfile: recvfile(w): %s\n",
+               fsp_str_dbg(tofsp)));
+       smb_traffic_analyzer_send_data(handle,
+               &s_data,
+               vfs_id_write);
+       return s_data.len;
+}
+
+
 static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \
                                files_struct *fsp, void *data, size_t n)
 {
@@ -842,9 +911,11 @@ static struct vfs_fn_pointers vfs_smb_traffic_analyzer_fns = {
        .mkdir = smb_traffic_analyzer_mkdir,
        .rename = smb_traffic_analyzer_rename,
        .chdir = smb_traffic_analyzer_chdir,
-       .open = smb_traffic_analyzer_open,
+       .open_fn = smb_traffic_analyzer_open,
        .rmdir = smb_traffic_analyzer_rmdir,
-       .close_fn = smb_traffic_analyzer_close
+       .close_fn = smb_traffic_analyzer_close,
+       .sendfile = smb_traffic_analyzer_sendfile,
+       .recvfile = smb_traffic_analyzer_recvfile
 };
 
 /* Module initialization */