diff options
author | Jeremy Allison <jra@samba.org> | 2008-09-30 15:13:19 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2008-09-30 15:13:19 -0700 |
commit | 321191d5e2ec1eaf22728dcee944e0a250a7725d (patch) | |
tree | 4d4b2cefcdc85c584bff834ce12c161c39f66776 /source3/modules | |
parent | 97d57d03640664416500efb1f1cf8e5a4a9522d8 (diff) | |
download | samba-321191d5e2ec1eaf22728dcee944e0a250a7725d.tar.gz samba-321191d5e2ec1eaf22728dcee944e0a250a7725d.tar.bz2 samba-321191d5e2ec1eaf22728dcee944e0a250a7725d.zip |
Restructure the module so it connects to the remote data sink
on connect, and closes the socket on client disconnect. This should
make it much more efficient. Store the remote fd in a private data
pointer off the handle. Finally we need to remove the fstrings and
convert to allocated buffer storage.
Jeremy.
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/vfs_smb_traffic_analyzer.c | 306 |
1 files changed, 156 insertions, 150 deletions
diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c index 9e4cf81638..cd843e6ad4 100644 --- a/source3/modules/vfs_smb_traffic_analyzer.c +++ b/source3/modules/vfs_smb_traffic_analyzer.c @@ -31,67 +31,8 @@ extern userdom_struct current_user_info; static int vfs_smb_traffic_analyzer_debug_level = DBGC_VFS; -NTSTATUS vfs_smb_traffic_analyzer_init(void); - -static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, - files_struct *fsp, const void *data, size_t n); - -static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, - files_struct *fsp, void *data, size_t n); - -static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, - files_struct *fsp, const void *data, size_t n, - SMB_OFF_T offset); - -static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, - files_struct *fsp, void *data, size_t n, SMB_OFF_T offset); - - -/* VFS operations we use */ - -static vfs_op_tuple smb_traffic_analyzer_tuples[] = { - - {SMB_VFS_OP(smb_traffic_analyzer_read), SMB_VFS_OP_READ, - SMB_VFS_LAYER_LOGGER}, - {SMB_VFS_OP(smb_traffic_analyzer_pread), SMB_VFS_OP_PREAD, - SMB_VFS_LAYER_LOGGER}, - {SMB_VFS_OP(smb_traffic_analyzer_write), SMB_VFS_OP_WRITE, - SMB_VFS_LAYER_LOGGER}, - {SMB_VFS_OP(smb_traffic_analyzer_pwrite), SMB_VFS_OP_PWRITE, - SMB_VFS_LAYER_LOGGER}, - {SMB_VFS_OP(NULL),SMB_VFS_OP_NOOP,SMB_VFS_LAYER_NOOP} - - }; - - -/* Module initialization */ - -NTSTATUS vfs_smb_traffic_analyzer_init(void) -{ - NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, \ - "smb_traffic_analyzer", smb_traffic_analyzer_tuples); - - if (!NT_STATUS_IS_OK(ret)) - return ret; - - vfs_smb_traffic_analyzer_debug_level = - debug_add_class("smb_traffic_analyzer"); - - if (vfs_smb_traffic_analyzer_debug_level == -1) { - vfs_smb_traffic_analyzer_debug_level = DBGC_VFS; - DEBUG(1, ("smb_traffic_analyzer: Couldn't register custom" - "debugging class!\n")); - } else { - DEBUG(3, ("smb_traffic_analyzer: Debug class number of" - "'smb_traffic_analyzer': %d\n", \ - vfs_smb_traffic_analyzer_debug_level)); - } - - return ret; -} - /* create the timestamp in sqlite compatible format */ -static void get_timestamp( char *String ) +static void get_timestamp(fstring str) { struct timeval tv; struct timezone tz; @@ -102,13 +43,13 @@ static void get_timestamp( char *String ) tm=localtime(&tv.tv_sec); seconds=(float) (tv.tv_usec / 1000); - fstr_sprintf(String,"%04d-%02d-%02d %02d:%02d:%02d.%03d", \ + fstr_sprintf(str,"%04d-%02d-%02d %02d:%02d:%02d.%03d", \ tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, \ tm->tm_hour, tm->tm_min, tm->tm_sec, (int)seconds); } -static int smb_traffic_analyzer_connMode( vfs_handle_struct *handle) +static int smb_traffic_analyzer_connMode(vfs_handle_struct *handle) { connection_struct *conn = handle->conn; const char *Mode; @@ -122,10 +63,9 @@ static int smb_traffic_analyzer_connMode( vfs_handle_struct *handle) } -/* Send data over a internet socket */ -static void smb_traffic_analyzer_send_data_inet_socket( char *String, - vfs_handle_struct *handle, const char *file_name, - bool Write) +/* Connect to an internet socket */ + +static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle) { /* Create a streaming Socket */ const char *Hostname; @@ -134,13 +74,11 @@ static void smb_traffic_analyzer_send_data_inet_socket( char *String, struct addrinfo hints; struct addrinfo *ailist = NULL; struct addrinfo *res = NULL; - char Sender[200]; - char TimeStamp[200]; connection_struct *conn = handle->conn; int ret; /* get port number, target system from the config parameters */ - Hostname=lp_parm_const_string(SNUM(conn), "smb_traffic_analyzer", + Hostname=lp_parm_const_string(SNUM(conn), "smb_traffic_analyzer", "host", "localhost"); ZERO_STRUCT(hints); @@ -154,14 +92,14 @@ static void smb_traffic_analyzer_send_data_inet_socket( char *String, &ailist); if (ret) { - DEBUG(3,("smb_traffic_analyzer_send_data_inet_socket: " + DEBUG(3,("smb_traffic_analyzer_connect_inet_socket: " "getaddrinfo failed for name %s [%s]\n", Hostname, gai_strerror(ret) )); - return; + return -1; } - port = atoi( lp_parm_const_string(SNUM(conn), + port = atoi( lp_parm_const_string(SNUM(conn), "smb_traffic_analyzer", "port", "9430")); DEBUG(3,("smb_traffic_analyzer: Internet socket mode. Hostname: %s," @@ -188,116 +126,129 @@ static void smb_traffic_analyzer_send_data_inet_socket( char *String, } if (sockfd == -1) { - DEBUG(1, ("smb_traffic_analyzer: unable to create socket, error is %s", + DEBUG(1, ("smb_traffic_analyzer: unable to create " + "socket, error is %s", strerror(errno))); - return; + return -1; } - strlcpy(Sender, String, sizeof(Sender)); - strlcat(Sender, ",\"", sizeof(Sender)); - strlcat(Sender, get_current_username(), sizeof(Sender)); - strlcat(Sender, "\",\"", sizeof(Sender)); - strlcat(Sender, current_user_info.domain, sizeof(Sender)); - strlcat(Sender, "\",\"", sizeof(Sender)); - if (Write) - strlcat(Sender, "W", sizeof(Sender)); - else - strlcat(Sender, "R", sizeof(Sender)); - strlcat(Sender, "\",\"", sizeof(Sender)); - strlcat(Sender, handle->conn->connectpath, sizeof(Sender)); - strlcat(Sender, "\",\"", sizeof(Sender) - 1); - strlcat(Sender, file_name, sizeof(Sender) - 1); - strlcat(Sender, "\",\"", sizeof(Sender) - 1); - get_timestamp(TimeStamp); - strlcat(Sender, TimeStamp, sizeof(Sender) - 1); - strlcat(Sender, "\");", sizeof(Sender) - 1); - DEBUG(10, ("smb_traffic_analyzer: sending %s\n", Sender)); - if ( send(sockfd, Sender, strlen(Sender), 0) == -1 ) { - DEBUG(1, ("smb_traffic_analyzer: error sending data to socket!\n")); - close(sockfd); - return ; - } - - /* one operation, close the socket */ - close(sockfd); + return sockfd; } +/* Connect to a unix domain socket */ - -/* Send data over a unix domain socket */ -static void smb_traffic_analyzer_send_data_unix_socket( char *String , - vfs_handle_struct *handle, const char *file_name, - bool Write) +static int smb_traffic_analyzer_connect_unix_socket(vfs_handle_struct *handle) { /* Create the socket to stad */ int len, sock; struct sockaddr_un remote; - char Sender[200]; - char TimeStamp[200]; - DEBUG(7, ("smb_traffic_analyzer: Unix domain socket mode. Using " + DEBUG(7, ("smb_traffic_analyzer_connect_unix_socket: " + "Unix domain socket mode. Using " "/var/tmp/stadsocket\n")); if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { - DEBUG(1, ("smb_traffic_analyzer: Couldn create socket," + DEBUG(1, ("smb_traffic_analyzer_connect_unix_socket: " + "Couldn't create socket, " "make sure stad is running!\n")); } remote.sun_family = AF_UNIX; - strlcpy(remote.sun_path, "/var/tmp/stadsocket", + strlcpy(remote.sun_path, "/var/tmp/stadsocket", sizeof(remote.sun_path)); len=strlen(remote.sun_path) + sizeof(remote.sun_family); if (connect(sock, (struct sockaddr *)&remote, len) == -1 ) { - DEBUG(1, ("smb_traffic_analyzer: Could not connect to" + DEBUG(1, ("smb_traffic_analyzer_connect_unix_socket: " + "Could not connect to " "socket, make sure\nstad is running!\n")); close(sock); + return -1; + } + return sock; +} + +/* Send data over a socket */ + +static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, + char *str, + const char *file_name, + bool Write) +{ + int *psockfd = NULL; + char Sender[200]; + char TimeStamp[200]; + + SMB_VFS_HANDLE_GET_DATA(handle, psockfd, int, return); + + if (psockfd == NULL || *psockfd == -1) { + DEBUG(1, ("smb_traffic_analyzer_send_data: socket is " + "closed\n")); return; } - strlcpy(Sender, String, sizeof(Sender)); + + strlcpy(Sender, str, sizeof(Sender)); strlcat(Sender, ",\"", sizeof(Sender)); strlcat(Sender, get_current_username(), sizeof(Sender)); - strlcat(Sender,"\",\"",sizeof(Sender)); + strlcat(Sender, "\",\"", sizeof(Sender)); strlcat(Sender, current_user_info.domain, sizeof(Sender)); strlcat(Sender, "\",\"", sizeof(Sender)); - if (Write) + if (Write) strlcat(Sender, "W", sizeof(Sender)); else strlcat(Sender, "R", sizeof(Sender)); strlcat(Sender, "\",\"", sizeof(Sender)); strlcat(Sender, handle->conn->connectpath, sizeof(Sender)); - strlcat(Sender, "\",\"", sizeof(Sender)); - strlcat(Sender, file_name, sizeof(Sender)); - strlcat(Sender, "\",\"", sizeof(Sender)); - get_timestamp(TimeStamp); - strlcat(Sender, TimeStamp, sizeof(Sender)); - strlcat(Sender, "\");", sizeof(Sender)); - - DEBUG(10, ("smb_traffic_analyzer: sending %s\n", Sender)); - if ( send(sock, Sender, strlen(Sender), 0) == -1 ) { - DEBUG(1, ("smb_traffic_analyzer: error sending data to" - "socket!\n")); - close(sock); - return; + strlcat(Sender, "\",\"", sizeof(Sender) - 1); + strlcat(Sender, file_name, sizeof(Sender) - 1); + strlcat(Sender, "\",\"", sizeof(Sender) - 1); + get_timestamp(TimeStamp); + strlcat(Sender, TimeStamp, sizeof(Sender) - 1); + strlcat(Sender, "\");", sizeof(Sender) - 1); + DEBUG(10, ("smb_traffic_analyzer_send_data_socket: sending %s\n", + Sender)); + if (send(*psockfd, Sender, strlen(Sender), 0) == -1 ) { + DEBUG(1, ("smb_traffic_analyzer_send_data_socket: " + "error sending data to socket!\n")); + return ; } +} - /* one operation, close the socket */ - close(sock); - return; +static void smb_traffic_analyzer_free_data(void **pptr) +{ + int *pfd = *(int **)pptr; + if(!pfd) { + return; + } + if (*pfd != -1) { + close(*pfd); + } + TALLOC_FREE(pfd); } -static void smb_traffic_analyzer_send_data( char *Buffer , vfs_handle_struct \ - *handle, char *file_name, bool Write, files_struct *fsp) +static int smb_traffic_analyzer_connect(struct vfs_handle_struct *handle, + const char *service, + const char *user) { + int *pfd = TALLOC_P(handle, int); - if (smb_traffic_analyzer_connMode(handle) == UNIX_DOMAIN_SOCKET) { - smb_traffic_analyzer_send_data_unix_socket(Buffer, handle, \ - fsp->fsp_name, Write); - } else { - smb_traffic_analyzer_send_data_inet_socket(Buffer, handle, \ - fsp->fsp_name, Write); - } -} + if (!pfd) { + errno = ENOMEM; + return -1; + } + if (smb_traffic_analyzer_connMode(handle) == UNIX_DOMAIN_SOCKET) { + *pfd = smb_traffic_analyzer_connect_unix_socket(handle); + } else { + *pfd = smb_traffic_analyzer_connect_inet_socket(handle); + } + if (*pfd == -1) { + return -1; + } + /* Store the private data. */ + SMB_VFS_HANDLE_SET_DATA(handle, pfd, smb_traffic_analyzer_free_data, + int, return -1); + return SMB_VFS_NEXT_CONNECT(handle, service, user); +} /* VFS Functions: write, read, pread, pwrite for now */ @@ -308,11 +259,14 @@ static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \ fstring Buffer; result = SMB_VFS_NEXT_READ(handle, fsp, data, n); - DEBUG(10, ("smb_traffic_analyzer: READ: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp->fsp_name )); fstr_sprintf(Buffer, "%u", (uint) result); - smb_traffic_analyzer_send_data(Buffer, handle, fsp->fsp_name, false, fsp); + smb_traffic_analyzer_send_data(handle, + Buffer, + fsp->fsp_name, + false); return result; } @@ -325,10 +279,13 @@ static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); - DEBUG(10, ("smb_traffic_analyzer: READ: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", fsp->fsp_name )); fstr_sprintf(Buffer,"%u", (uint) result); - smb_traffic_analyzer_send_data(Buffer, handle, fsp->fsp_name, false, fsp); + smb_traffic_analyzer_send_data(handle, + Buffer, + fsp->fsp_name, + false); return result; } @@ -341,11 +298,13 @@ static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n); - DEBUG(10, ("smb_traffic_analyzer: WRITE: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", fsp->fsp_name )); fstr_sprintf(Buffer, "%u", (uint) result); - smb_traffic_analyzer_send_data(Buffer, handle, fsp->fsp_name, \ - true, fsp ); + smb_traffic_analyzer_send_data(handle, + Buffer, + fsp->fsp_name, + true); return result; } @@ -357,9 +316,56 @@ static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, \ result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); - DEBUG(10, ("smb_traffic_analyzer: PWRITE: %s\n", fsp->fsp_name )); + DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp->fsp_name )); fstr_sprintf(Buffer, "%u", (uint) result); - smb_traffic_analyzer_send_data(Buffer, handle, fsp->fsp_name, true, fsp); + smb_traffic_analyzer_send_data(handle, + Buffer, + fsp->fsp_name, + true); return result; } + +/* VFS operations we use */ + +static vfs_op_tuple smb_traffic_analyzer_tuples[] = { + + {SMB_VFS_OP(smb_traffic_analyzer_connect), SMB_VFS_OP_CONNECT, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_traffic_analyzer_read), SMB_VFS_OP_READ, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_traffic_analyzer_pread), SMB_VFS_OP_PREAD, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_traffic_analyzer_write), SMB_VFS_OP_WRITE, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_traffic_analyzer_pwrite), SMB_VFS_OP_PWRITE, + SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(NULL),SMB_VFS_OP_NOOP,SMB_VFS_LAYER_NOOP} +}; + +/* Module initialization */ + +NTSTATUS vfs_smb_traffic_analyzer_init(void) +{ + NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION, \ + "smb_traffic_analyzer", smb_traffic_analyzer_tuples); + + if (!NT_STATUS_IS_OK(ret)) { + return ret; + } + + vfs_smb_traffic_analyzer_debug_level = + debug_add_class("smb_traffic_analyzer"); + + if (vfs_smb_traffic_analyzer_debug_level == -1) { + vfs_smb_traffic_analyzer_debug_level = DBGC_VFS; + DEBUG(1, ("smb_traffic_analyzer_init: Couldn't register custom" + "debugging class!\n")); + } else { + DEBUG(3, ("smb_traffic_analyzer_init: Debug class number of" + "'smb_traffic_analyzer': %d\n", \ + vfs_smb_traffic_analyzer_debug_level)); + } + + return ret; +} |