X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fmodules%2Fvfs_smb_traffic_analyzer.c;h=f5c39ad6d7ce096346cba9410f3241605f902999;hb=2d6dca8797afb02083c86ec7d8d220fa6a60d333;hp=57d483fa46bd4491be3fa13850a133d979bee54c;hpb=c136b84f0d28d1a88c5918b06f81766a271a3780;p=samba.git diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c index 57d483fa46b..f5c39ad6d7c 100644 --- a/source3/modules/vfs_smb_traffic_analyzer.c +++ b/source3/modules/vfs_smb_traffic_analyzer.c @@ -20,10 +20,16 @@ */ #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/dom_sid.h" +#include "../libcli/security/security.h" #include "secrets.h" +#include "../librpc/gen_ndr/ndr_netlogon.h" +#include "auth.h" +#include "../lib/tsocket/tsocket.h" +#include "lib/util/sys_rw_data.h" /* abstraction for the send_over_network function */ enum sock_type {INTERNET_SOCKET = 0, UNIX_DOMAIN_SOCKET}; @@ -164,28 +170,27 @@ struct refcounted_sock { static char *smb_traffic_analyzer_encrypt( TALLOC_CTX *ctx, const char *akey, const char *str, size_t *len) { - int s1,s2,h,d; + int s1,s2,h; AES_KEY key; unsigned char filler[17]= "................"; char *output; - unsigned char crypted[18]; if (akey == NULL) return NULL; - samba_AES_set_encrypt_key((unsigned char *) akey, 128, &key); + 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); + memcpy(filler, str + (s1*16), s2); DEBUG(10, ("smb_traffic_analyzer_send_data_socket: created %s" " as filling block.\n", filler)); - output = talloc_array(ctx, char, (s1*16)+17 ); - d=0; + + *len = ((s1 + 1)*16); + output = talloc_array(ctx, char, *len); for (h = 0; h < s1; h++) { - samba_AES_encrypt((unsigned char *) str+(16*h), crypted, &key); - for (d = 0; d<16; d++) output[d+(16*h)]=crypted[d]; + AES_encrypt((const unsigned char *) str+(16*h), (unsigned char *)output+16*h, + &key); } - samba_AES_encrypt( (unsigned char *) str+(16*h), filler, &key ); - for (d = 0;d < 16; d++) output[d+(16*h)]=*(filler+d); + AES_encrypt(filler, (unsigned char *)(output+(16*h)), &key); *len = (s1*16)+16; - return output; + return output; } /** @@ -298,6 +303,7 @@ 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); @@ -312,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 */ /* @@ -329,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", \ @@ -347,10 +360,9 @@ static char *smb_traffic_analyzer_create_string( TALLOC_CTX *ctx, tm->tm_sec, \ (int)seconds); 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, @@ -361,10 +373,12 @@ static char *smb_traffic_analyzer_create_string( TALLOC_CTX *ctx, (unsigned int) strlen(service_name), service_name, (unsigned int) - strlen(handle->conn->server_info->info3->base.domain.string), - handle->conn->server_info->info3->base.domain.string, + 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); @@ -411,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) { @@ -420,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; @@ -434,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) { @@ -446,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; @@ -465,9 +490,9 @@ 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, - handle->conn->server_info->info3->base.domain.string, + handle->conn->session_info->info->domain_name, Write ? 'W' : 'R', - handle->conn->connectpath, + handle->conn->cwd, s_data->filename, tm->tm_year+1900, tm->tm_mon+1, @@ -483,7 +508,10 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, return; } - } else if ( strcmp( protocol_version, "V2") == 0) { + } else { + /** + * Protocol 2 is used by default. + */ switch( vfs_operation ) { case vfs_id_open: ; @@ -491,7 +519,7 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, tm, seconds, handle, username, vfs_id_open, 3, ((struct open_data *) data)->filename, talloc_asprintf( talloc_tos(), "%u", - ((struct open_data *) data)->mode), + (unsigned int)((struct open_data *) data)->mode), talloc_asprintf( talloc_tos(), "%u", ((struct open_data *) data)->result)); break; @@ -507,7 +535,7 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, tm, seconds, handle, username, vfs_id_mkdir, \ 3, ((struct mkdir_data *) data)->path, \ talloc_asprintf( talloc_tos(), "%u", \ - ((struct mkdir_data *) data)->mode), \ + (unsigned int)((struct mkdir_data *) data)->mode), \ talloc_asprintf( talloc_tos(), "%u", \ ((struct mkdir_data *) data)->result )); break; @@ -551,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) { @@ -577,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); @@ -649,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; @@ -741,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, + 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, + 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) { @@ -758,7 +821,7 @@ static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \ static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, \ - files_struct *fsp, void *data, size_t n, SMB_OFF_T offset) + files_struct *fsp, void *data, size_t n, off_t offset) { struct rw_data s_data; @@ -791,7 +854,7 @@ static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, \ } static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, \ - files_struct *fsp, const void *data, size_t n, SMB_OFF_T offset) + files_struct *fsp, const void *data, size_t n, off_t offset) { struct rw_data s_data; @@ -840,20 +903,23 @@ static int smb_traffic_analyzer_close(vfs_handle_struct *handle, \ static struct vfs_fn_pointers vfs_smb_traffic_analyzer_fns = { - .connect_fn = smb_traffic_analyzer_connect, - .vfs_read = smb_traffic_analyzer_read, - .pread = smb_traffic_analyzer_pread, - .write = smb_traffic_analyzer_write, - .pwrite = smb_traffic_analyzer_pwrite, - .mkdir = smb_traffic_analyzer_mkdir, - .rename = smb_traffic_analyzer_rename, - .chdir = smb_traffic_analyzer_chdir, - .open = smb_traffic_analyzer_open, - .rmdir = smb_traffic_analyzer_rmdir, - .close_fn = smb_traffic_analyzer_close + .connect_fn = smb_traffic_analyzer_connect, + .read_fn = smb_traffic_analyzer_read, + .pread_fn = smb_traffic_analyzer_pread, + .write_fn = smb_traffic_analyzer_write, + .pwrite_fn = smb_traffic_analyzer_pwrite, + .mkdir_fn = smb_traffic_analyzer_mkdir, + .rename_fn = smb_traffic_analyzer_rename, + .chdir_fn = smb_traffic_analyzer_chdir, + .open_fn = smb_traffic_analyzer_open, + .rmdir_fn = smb_traffic_analyzer_rmdir, + .close_fn = smb_traffic_analyzer_close, + .sendfile_fn = smb_traffic_analyzer_sendfile, + .recvfile_fn = smb_traffic_analyzer_recvfile }; /* Module initialization */ +static_decl_vfs; NTSTATUS vfs_smb_traffic_analyzer_init(void) { NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION,