From 97d57d03640664416500efb1f1cf8e5a4a9522d8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 2008 13:26:41 -0700 Subject: Fix the make test problem Karolin reported. Now rename_open_files actually works correctly we must emit the change notify before we change the name, not before. Jeremy. --- source3/smbd/reply.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 6933533672..8bfa28faea 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -5583,10 +5583,10 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n", fsp->fsp_name,newname)); - rename_open_files(conn, lck, newname); - notify_rename(conn, fsp->is_directory, fsp->fsp_name, newname); + rename_open_files(conn, lck, newname); + /* * A rename acts as a new file create w.r.t. allowing an initial delete * on close, probably because in Windows there is a new handle to the -- cgit From 321191d5e2ec1eaf22728dcee944e0a250a7725d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 2008 15:13:19 -0700 Subject: 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. --- source3/modules/vfs_smb_traffic_analyzer.c | 306 +++++++++++++++-------------- 1 file changed, 156 insertions(+), 150 deletions(-) (limited to 'source3') 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; +} -- cgit From 4e6445a0720d7265f0bddff71cd2e17d6b2ac057 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 2008 15:21:58 -0700 Subject: Remove current_user_info - not needed. Jeremy. --- source3/modules/vfs_expand_msdfs.c | 2 +- source3/modules/vfs_smb_traffic_analyzer.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_expand_msdfs.c b/source3/modules/vfs_expand_msdfs.c index 0d09d213e1..c22ab66e14 100644 --- a/source3/modules/vfs_expand_msdfs.c +++ b/source3/modules/vfs_expand_msdfs.c @@ -147,7 +147,7 @@ static char *expand_msdfs_target(TALLOC_CTX *ctx, conn->connectpath, conn->server_info->utok.gid, conn->server_info->sanitized_username, - pdb_get_domain(conn->server_info->sam_account), + pdb_get_domain(handle->conn->server_info->sam_account), targethost); DEBUG(10, ("Expanded targethost to %s\n", targethost)); diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c index cd843e6ad4..12c893fae7 100644 --- a/source3/modules/vfs_smb_traffic_analyzer.c +++ b/source3/modules/vfs_smb_traffic_analyzer.c @@ -27,8 +27,6 @@ /* Prototypes */ -extern userdom_struct current_user_info; - static int vfs_smb_traffic_analyzer_debug_level = DBGC_VFS; /* create the timestamp in sqlite compatible format */ @@ -187,9 +185,9 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, strlcpy(Sender, str, sizeof(Sender)); strlcat(Sender, ",\"", sizeof(Sender)); - strlcat(Sender, get_current_username(), sizeof(Sender)); + strlcat(Sender, handle->conn->server_info->sanitized_username, sizeof(Sender)); strlcat(Sender, "\",\"", sizeof(Sender)); - strlcat(Sender, current_user_info.domain, sizeof(Sender)); + strlcat(Sender, pdb_get_domain(handle->conn->server_info->sam_account), sizeof(Sender)); strlcat(Sender, "\",\"", sizeof(Sender)); if (Write) strlcat(Sender, "W", sizeof(Sender)); -- cgit From 5d7d18b7e827930018ab30fc5e738b5a5cd90789 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 2008 15:26:26 -0700 Subject: Revert erroneous commit. Jeremy. --- source3/modules/vfs_expand_msdfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/modules/vfs_expand_msdfs.c b/source3/modules/vfs_expand_msdfs.c index c22ab66e14..0d09d213e1 100644 --- a/source3/modules/vfs_expand_msdfs.c +++ b/source3/modules/vfs_expand_msdfs.c @@ -147,7 +147,7 @@ static char *expand_msdfs_target(TALLOC_CTX *ctx, conn->connectpath, conn->server_info->utok.gid, conn->server_info->sanitized_username, - pdb_get_domain(handle->conn->server_info->sam_account), + pdb_get_domain(conn->server_info->sam_account), targethost); DEBUG(10, ("Expanded targethost to %s\n", targethost)); -- cgit From c164ff2be5f9af7cc83e43d8c54b54186444fac0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 2008 16:19:37 -0700 Subject: Convert to allocated strings. Use write_data(), not send as this doesn't correctly deal with EINTR. Jim and Holger please check this still works. Jeremy. --- source3/modules/vfs_smb_traffic_analyzer.c | 100 ++++++++++++----------------- 1 file changed, 42 insertions(+), 58 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c index 12c893fae7..3925424214 100644 --- a/source3/modules/vfs_smb_traffic_analyzer.c +++ b/source3/modules/vfs_smb_traffic_analyzer.c @@ -24,29 +24,8 @@ #define UNIX_DOMAIN_SOCKET 1 #define INTERNET_SOCKET 0 - -/* Prototypes */ - static int vfs_smb_traffic_analyzer_debug_level = DBGC_VFS; -/* create the timestamp in sqlite compatible format */ -static void get_timestamp(fstring str) -{ - struct timeval tv; - struct timezone tz; - struct tm *tm; - int seconds; - - gettimeofday(&tv, &tz); - tm=localtime(&tv.tv_sec); - seconds=(float) (tv.tv_usec / 1000); - - 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) { connection_struct *conn = handle->conn; @@ -58,7 +37,6 @@ static int smb_traffic_analyzer_connMode(vfs_handle_struct *handle) } else { return INTERNET_SOCKET; } - } /* Connect to an internet socket */ @@ -167,13 +145,16 @@ static int smb_traffic_analyzer_connect_unix_socket(vfs_handle_struct *handle) /* Send data over a socket */ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, - char *str, + ssize_t result, const char *file_name, bool Write) { int *psockfd = NULL; - char Sender[200]; - char TimeStamp[200]; + struct timeval tv; + struct tm *tm = NULL; + int seconds; + char *str = NULL; + size_t len; SMB_VFS_HANDLE_GET_DATA(handle, psockfd, int, return); @@ -183,27 +164,39 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, return; } - strlcpy(Sender, str, sizeof(Sender)); - strlcat(Sender, ",\"", sizeof(Sender)); - strlcat(Sender, handle->conn->server_info->sanitized_username, sizeof(Sender)); - strlcat(Sender, "\",\"", sizeof(Sender)); - strlcat(Sender, pdb_get_domain(handle->conn->server_info->sam_account), 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); + GetTimeOfDay(&tv); + tm=localtime(&tv.tv_sec); + if (!tm) { + return; + } + seconds=(float) (tv.tv_usec / 1000); + + str = talloc_asprintf(talloc_tos(), + "%u,\"%s\",\"%s\",\"%c\",\"%s\",\"%s\"," + "\"%04d-%02d-%02d %02d:%02d:%02d.%03d\");", + (unsigned int)result, + handle->conn->server_info->sanitized_username, + pdb_get_domain(handle->conn->server_info->sam_account), + Write ? 'W' : 'R', + handle->conn->connectpath, + file_name, + tm->tm_year+1900, + tm->tm_mon+1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + (int)seconds); + + if (!str) { + return; + } + + len = strlen(str); + DEBUG(10, ("smb_traffic_analyzer_send_data_socket: sending %s\n", - Sender)); - if (send(*psockfd, Sender, strlen(Sender), 0) == -1 ) { + str)); + if (write_data(*psockfd, str, len) != len) { DEBUG(1, ("smb_traffic_analyzer_send_data_socket: " "error sending data to socket!\n")); return ; @@ -254,15 +247,12 @@ static ssize_t smb_traffic_analyzer_read(vfs_handle_struct *handle, \ files_struct *fsp, void *data, size_t n) { ssize_t result; - fstring Buffer; result = SMB_VFS_NEXT_READ(handle, fsp, data, n); DEBUG(10, ("smb_traffic_analyzer_read: READ: %s\n", fsp->fsp_name )); - fstr_sprintf(Buffer, "%u", (uint) result); - smb_traffic_analyzer_send_data(handle, - Buffer, + result, fsp->fsp_name, false); return result; @@ -273,15 +263,13 @@ static ssize_t smb_traffic_analyzer_pread(vfs_handle_struct *handle, \ files_struct *fsp, void *data, size_t n, SMB_OFF_T offset) { ssize_t result; - fstring Buffer; result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset); DEBUG(10, ("smb_traffic_analyzer_pread: PREAD: %s\n", fsp->fsp_name )); - fstr_sprintf(Buffer,"%u", (uint) result); smb_traffic_analyzer_send_data(handle, - Buffer, + result, fsp->fsp_name, false); @@ -292,15 +280,13 @@ static ssize_t smb_traffic_analyzer_write(vfs_handle_struct *handle, \ files_struct *fsp, const void *data, size_t n) { ssize_t result; - fstring Buffer; result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n); DEBUG(10, ("smb_traffic_analyzer_write: WRITE: %s\n", fsp->fsp_name )); - fstr_sprintf(Buffer, "%u", (uint) result); smb_traffic_analyzer_send_data(handle, - Buffer, + result, fsp->fsp_name, true); return result; @@ -310,15 +296,13 @@ static ssize_t smb_traffic_analyzer_pwrite(vfs_handle_struct *handle, \ files_struct *fsp, const void *data, size_t n, SMB_OFF_T offset) { ssize_t result; - fstring Buffer; result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset); DEBUG(10, ("smb_traffic_analyzer_pwrite: PWRITE: %s\n", fsp->fsp_name )); - fstr_sprintf(Buffer, "%u", (uint) result); smb_traffic_analyzer_send_data(handle, - Buffer, + result, fsp->fsp_name, true); return result; -- cgit From 370cbe0060cb2670c7f65100954dac6c63030ca0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Oct 2008 12:50:29 -0700 Subject: Turn the socket connections into a refcounted list - in the common case there'll now only be one socket per smbd. Changed the format of the wire data to (a) include a version number (V1) as the first element. (b) removed the ";)" at the end an replaced it with a "\n". Receiver can change back if needed, and now receiver can just log "as-is" to a text file (making testing easier). Added my (C). Sorry Holger, but I've changed quite a bit now. Jeremy. --- source3/modules/vfs_smb_traffic_analyzer.c | 139 ++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 44 deletions(-) (limited to 'source3') diff --git a/source3/modules/vfs_smb_traffic_analyzer.c b/source3/modules/vfs_smb_traffic_analyzer.c index 3925424214..ff61768495 100644 --- a/source3/modules/vfs_smb_traffic_analyzer.c +++ b/source3/modules/vfs_smb_traffic_analyzer.c @@ -3,6 +3,7 @@ * on the net. * * Copyright (C) Holger Hetterich, 2008 + * Copyright (C) Jeremy Allison, 2008 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,12 +22,14 @@ #include "includes.h" /* abstraction for the send_over_network function */ -#define UNIX_DOMAIN_SOCKET 1 -#define INTERNET_SOCKET 0 + +enum sock_type {INTERNET_SOCKET = 0, UNIX_DOMAIN_SOCKET}; + +#define LOCAL_PATHNAME "/var/tmp/stadsocket" static int vfs_smb_traffic_analyzer_debug_level = DBGC_VFS; -static int smb_traffic_analyzer_connMode(vfs_handle_struct *handle) +static enum sock_type smb_traffic_analyzer_connMode(vfs_handle_struct *handle) { connection_struct *conn = handle->conn; const char *Mode; @@ -41,28 +44,22 @@ static int smb_traffic_analyzer_connMode(vfs_handle_struct *handle) /* Connect to an internet socket */ -static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle) +static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle, + const char *name, uint16_t port) { /* Create a streaming Socket */ - const char *Hostname; int sockfd = -1; - uint16_t port; struct addrinfo hints; struct addrinfo *ailist = NULL; struct addrinfo *res = NULL; - 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", - "host", "localhost"); - ZERO_STRUCT(hints); /* By default make sure it supports TCP. */ hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; - ret = getaddrinfo(Hostname, + ret = getaddrinfo(name, NULL, &hints, &ailist); @@ -70,16 +67,13 @@ static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle) if (ret) { DEBUG(3,("smb_traffic_analyzer_connect_inet_socket: " "getaddrinfo failed for name %s [%s]\n", - Hostname, + name, gai_strerror(ret) )); return -1; } - port = atoi( lp_parm_const_string(SNUM(conn), - "smb_traffic_analyzer", "port", "9430")); - DEBUG(3,("smb_traffic_analyzer: Internet socket mode. Hostname: %s," - "Port: %i\n", Hostname, port)); + "Port: %i\n", name, port)); for (res = ailist; res; res = res->ai_next) { struct sockaddr_storage ss; @@ -113,15 +107,16 @@ static int smb_traffic_analyzer_connect_inet_socket(vfs_handle_struct *handle) /* Connect to a unix domain socket */ -static int smb_traffic_analyzer_connect_unix_socket(vfs_handle_struct *handle) +static int smb_traffic_analyzer_connect_unix_socket(vfs_handle_struct *handle, + const char *name) { /* Create the socket to stad */ int len, sock; struct sockaddr_un remote; DEBUG(7, ("smb_traffic_analyzer_connect_unix_socket: " - "Unix domain socket mode. Using " - "/var/tmp/stadsocket\n")); + "Unix domain socket mode. Using %s\n", + name )); if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { DEBUG(1, ("smb_traffic_analyzer_connect_unix_socket: " @@ -129,7 +124,7 @@ static int smb_traffic_analyzer_connect_unix_socket(vfs_handle_struct *handle) "make sure stad is running!\n")); } remote.sun_family = AF_UNIX; - strlcpy(remote.sun_path, "/var/tmp/stadsocket", + strlcpy(remote.sun_path, name, sizeof(remote.sun_path)); len=strlen(remote.sun_path) + sizeof(remote.sun_family); if (connect(sock, (struct sockaddr *)&remote, len) == -1 ) { @@ -142,6 +137,16 @@ static int smb_traffic_analyzer_connect_unix_socket(vfs_handle_struct *handle) return sock; } +/* Private data allowing shared connection sockets. */ + +struct refcounted_sock { + struct refcounted_sock *next, *prev; + char *name; + uint16_t port; + int sock; + unsigned int ref_count; +}; + /* Send data over a socket */ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, @@ -149,16 +154,16 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, const char *file_name, bool Write) { - int *psockfd = NULL; + struct refcounted_sock *rf_sock = NULL; struct timeval tv; struct tm *tm = NULL; int seconds; char *str = NULL; size_t len; - SMB_VFS_HANDLE_GET_DATA(handle, psockfd, int, return); + SMB_VFS_HANDLE_GET_DATA(handle, rf_sock, struct refcounted_sock, return); - if (psockfd == NULL || *psockfd == -1) { + if (rf_sock == NULL || rf_sock->sock == -1) { DEBUG(1, ("smb_traffic_analyzer_send_data: socket is " "closed\n")); return; @@ -172,8 +177,8 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, seconds=(float) (tv.tv_usec / 1000); str = talloc_asprintf(talloc_tos(), - "%u,\"%s\",\"%s\",\"%c\",\"%s\",\"%s\"," - "\"%04d-%02d-%02d %02d:%02d:%02d.%03d\");", + "V1,%u,\"%s\",\"%s\",\"%c\",\"%s\",\"%s\"," + "\"%04d-%02d-%02d %02d:%02d:%02d.%03d\"\n", (unsigned int)result, handle->conn->server_info->sanitized_username, pdb_get_domain(handle->conn->server_info->sam_account), @@ -196,48 +201,94 @@ static void smb_traffic_analyzer_send_data(vfs_handle_struct *handle, DEBUG(10, ("smb_traffic_analyzer_send_data_socket: sending %s\n", str)); - if (write_data(*psockfd, str, len) != len) { + if (write_data(rf_sock->sock, str, len) != len) { DEBUG(1, ("smb_traffic_analyzer_send_data_socket: " "error sending data to socket!\n")); return ; } } +static struct refcounted_sock *sock_list; + static void smb_traffic_analyzer_free_data(void **pptr) { - int *pfd = *(int **)pptr; - if(!pfd) { + struct refcounted_sock *rf_sock = *(struct refcounted_sock **)pptr; + if (rf_sock == NULL) { return; } - if (*pfd != -1) { - close(*pfd); + rf_sock->ref_count--; + if (rf_sock->ref_count != 0) { + return; + } + if (rf_sock->sock != -1) { + close(rf_sock->sock); } - TALLOC_FREE(pfd); + DLIST_REMOVE(sock_list, rf_sock); + TALLOC_FREE(rf_sock); } static int smb_traffic_analyzer_connect(struct vfs_handle_struct *handle, const char *service, const char *user) { - int *pfd = TALLOC_P(handle, int); + connection_struct *conn = handle->conn; + enum sock_type st = smb_traffic_analyzer_connMode(handle); + struct refcounted_sock *rf_sock = NULL; + const char *name = (st == UNIX_DOMAIN_SOCKET) ? LOCAL_PATHNAME : + lp_parm_const_string(SNUM(conn), + "smb_traffic_analyzer", + "host", "localhost"); + uint16_t port = (st == UNIX_DOMAIN_SOCKET) ? 0 : + atoi( lp_parm_const_string(SNUM(conn), + "smb_traffic_analyzer", "port", "9430")); - if (!pfd) { - errno = ENOMEM; - return -1; + /* Are we already connected ? */ + for (rf_sock = sock_list; rf_sock; rf_sock = rf_sock->next) { + if (port == rf_sock->port && + (strcmp(name, rf_sock->name) == 0)) { + break; + } } - if (smb_traffic_analyzer_connMode(handle) == UNIX_DOMAIN_SOCKET) { - *pfd = smb_traffic_analyzer_connect_unix_socket(handle); + /* If we're connected already, just increase the + * reference count. */ + if (rf_sock) { + rf_sock->ref_count++; } else { - *pfd = smb_traffic_analyzer_connect_inet_socket(handle); - } - if (*pfd == -1) { - return -1; + /* New connection. */ + rf_sock = TALLOC_ZERO_P(NULL, struct refcounted_sock); + if (rf_sock == NULL) { + errno = ENOMEM; + return -1; + } + rf_sock->name = talloc_strdup(rf_sock, name); + if (rf_sock->name == NULL) { + TALLOC_FREE(rf_sock); + errno = ENOMEM; + return -1; + } + rf_sock->port = port; + rf_sock->ref_count = 1; + + if (st == UNIX_DOMAIN_SOCKET) { + rf_sock->sock = smb_traffic_analyzer_connect_unix_socket(handle, + name); + } else { + + rf_sock->sock = smb_traffic_analyzer_connect_inet_socket(handle, + name, + port); + } + if (rf_sock->sock == -1) { + TALLOC_FREE(rf_sock); + return -1; + } + DLIST_ADD(sock_list, rf_sock); } /* Store the private data. */ - SMB_VFS_HANDLE_SET_DATA(handle, pfd, smb_traffic_analyzer_free_data, - int, return -1); + SMB_VFS_HANDLE_SET_DATA(handle, rf_sock, smb_traffic_analyzer_free_data, + struct refcounted_sock, return -1); return SMB_VFS_NEXT_CONNECT(handle, service, user); } -- cgit From e4f5bfb34b7a515e2cf107eb94489260594b8733 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Oct 2008 13:15:54 -0700 Subject: Fix use of DLIST_REMOVE as spotted by Constantine Vetoshev . This API is unusual in that if used to remove a non-list head it nulls out the next and prev pointers. This is what you want for debugging (don't want an entry removed from the list to be still virtually linked into it) but means there is no consistent idiom for use as the next and prev pointers get trashed on removal from the list, meaning you must save them yourself. You can use it one way when deleting everything via the head pointer, as this preserves the next pointer, but you *must* use it another way when not deleting everything via the head pointer. Fix all known uses of this (the main one is in conn_free_internal() and would not free all the private data entries for vfs modules. The other changes in web/statuspage.c and winbindd_util.c are not strictly neccessary, as the head pointer is being used, but I've done them for consistency. Long term we must revisit this as this API is too hard to use correctly. Jeremy. --- source3/smbd/conn.c | 2 +- source3/web/statuspage.c | 5 +++-- source3/winbindd/winbindd_util.c | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3') diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index b9433bb965..7f34d2b8e2 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -252,8 +252,8 @@ void conn_free_internal(connection_struct *conn) /* Free vfs_connection_struct */ handle = conn->vfs_handles; while(handle) { - DLIST_REMOVE(conn->vfs_handles, handle); thandle = handle->next; + DLIST_REMOVE(conn->vfs_handles, handle); if (handle->free_data) handle->free_data(&handle->data); handle = thandle; diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c index ce24c7cddd..e684a075c2 100644 --- a/source3/web/statuspage.c +++ b/source3/web/statuspage.c @@ -43,9 +43,10 @@ static void initPid2Machine (void) { /* show machine name rather PID on table "Open Files"? */ if (PID_or_Machine) { - PIDMAP *p; + PIDMAP *p, *next; - for (p = pidmap; p != NULL; ) { + for (p = pidmap; p != NULL; p = next) { + next = p->next; DLIST_REMOVE(pidmap, p); SAFE_FREE(p->machine); SAFE_FREE(p); diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index b8cb27c797..fdfc8ed9d1 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -1075,13 +1075,12 @@ void free_getent_state(struct getent_state *state) temp = state; while(temp != NULL) { - struct getent_state *next; + struct getent_state *next = temp->next; /* Free sam entries then list entry */ SAFE_FREE(state->sam_entries); DLIST_REMOVE(state, state); - next = temp->next; SAFE_FREE(temp); temp = next; -- cgit From ea85ceefa945f1fee2bb10441a3cc8e35216733b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Oct 2008 15:01:05 -0700 Subject: Whitespace cleanup. Jeremy. --- source3/printing/print_cups.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'source3') diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index f9568f0a54..97584cbe05 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -7,12 +7,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ @@ -109,7 +109,7 @@ bool cups_cache_reload(void) { "printer-name", "printer-info" - }; + }; bool ret = False; DEBUG(5, ("reloading cups printcap cache\n")); @@ -657,8 +657,8 @@ static int cups_job_submit(int snum, struct printjob *pjob) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, new_jobname); - /* - * add any options defined in smb.conf + /* + * add any options defined in smb.conf */ num_options = 0; @@ -666,7 +666,7 @@ static int cups_job_submit(int snum, struct printjob *pjob) num_options = cupsParseOptions(lp_cups_options(snum), num_options, &options); if ( num_options ) - cupsEncodeOptions(request, num_options, options); + cupsEncodeOptions(request, num_options, options); /* * Do the request and get back a response... @@ -712,7 +712,7 @@ static int cups_job_submit(int snum, struct printjob *pjob) static int cups_queue_get(const char *sharename, enum printing_types printing_type, char *lpq_command, - print_queue_struct **q, + print_queue_struct **q, print_status_struct *status) { fstring printername; @@ -751,10 +751,10 @@ static int cups_queue_get(const char *sharename, *q = NULL; - /* HACK ALERT!!! The problem with support the 'printer name' - option is that we key the tdb off the sharename. So we will - overload the lpq_command string to pass in the printername - (which is basically what we do for non-cups printers ... using + /* HACK ALERT!!! The problem with support the 'printer name' + option is that we key the tdb off the sharename. So we will + overload the lpq_command string to pass in the printername + (which is basically what we do for non-cups printers ... using the lpq_command to get the queue listing). */ fstrcpy( printername, lpq_command ); @@ -1316,22 +1316,22 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer) /* Grab the comment if we don't have one */ if ( (strcmp(attr->name, "printer-info") == 0) && (attr->value_tag == IPP_TAG_TEXT) - && !strlen(printer->comment) ) + && !strlen(printer->comment) ) { DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n", - attr->values[0].string.text)); + attr->values[0].string.text)); strlcpy(printer->comment, attr->values[0].string.text, sizeof(printer->comment)); } - /* Grab the location if we don't have one */ + /* Grab the location if we don't have one */ if ( (strcmp(attr->name, "printer-location") == 0) - && (attr->value_tag == IPP_TAG_TEXT) + && (attr->value_tag == IPP_TAG_TEXT) && !strlen(printer->location) ) { DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n", - attr->values[0].string.text)); + attr->values[0].string.text)); fstrcpy(printer->location,attr->values[0].string.text); } -- cgit From 3bfb53caa86ece1d7ff1bf3c7759f003203d4247 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Oct 2008 16:40:41 -0700 Subject: Fix bug #5080. Access to cups-printers via samba broken with cups 1.3.4, Unsupported character set. Cups 1.3.4 expects utf8 to be used in all messages to/from the server. We may be using a different character set so we need to use talloc utf8 push/pull functions in all communication. Needs more testing. Don't release until I've done a thorough test. I also have a version for 3.2.x. Jeremy. --- source3/printing/print_cups.c | 341 +++++++++++++++++++++++++++++++----------- 1 file changed, 251 insertions(+), 90 deletions(-) (limited to 'source3') diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 97584cbe05..b46d83bb01 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -2,6 +2,7 @@ * Support code for the Common UNIX Printing System ("CUPS") * * Copyright 1999-2003 by Michael R Sweet. + * Copyright 2008 Jeremy Allison. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +18,10 @@ * along with this program; if not, see . */ +/* + * JRA. Converted to utf8 pull/push. + */ + #include "includes.h" #include "printing.h" @@ -51,24 +56,23 @@ cups_passwd_cb(const char *prompt) /* I - Prompt */ return (NULL); } -static http_t *cups_connect(void) +static http_t *cups_connect(TALLOC_CTX *frame) { - http_t *http; - char *server, *p; + http_t *http = NULL; + char *server = NULL, *p = NULL; int port; int timeout = lp_cups_connection_timeout(); - - gotalarm = 0; - - if (timeout) { - CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); - alarm(timeout); - } + size_t size; if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) { - server = smb_xstrdup(lp_cups_server()); + if (!push_utf8_talloc(frame, &server, lp_cups_server(), &size)) { + return NULL; + } } else { - server = smb_xstrdup(cupsServer()); + server = talloc_strdup(frame,cupsServer()); + } + if (server) { + return NULL; } p = strchr(server, ':'); @@ -82,6 +86,13 @@ static http_t *cups_connect(void) DEBUG(10, ("connecting to cups server %s:%d\n", server, port)); + gotalarm = 0; + + if (timeout) { + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(timeout); + } + http = httpConnect(server, port); CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); @@ -92,12 +103,12 @@ static http_t *cups_connect(void) server, port, strerror(errno))); } - SAFE_FREE(server); return http; } bool cups_cache_reload(void) { + TALLOC_CTX *frame = talloc_stackframe(); http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ @@ -111,6 +122,7 @@ bool cups_cache_reload(void) "printer-info" }; bool ret = False; + size_t size; DEBUG(5, ("reloading cups printcap cache\n")); @@ -124,7 +136,7 @@ bool cups_cache_reload(void) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -145,7 +157,7 @@ bool cups_cache_reload(void) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -185,12 +197,24 @@ bool cups_cache_reload(void) while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && - attr->value_tag == IPP_TAG_NAME) - name = attr->values[0].string.text; + attr->value_tag == IPP_TAG_NAME) { + if (!pull_utf8_talloc(frame, + &name, + attr->values[0].string.text, + &size)) { + goto out; + } + } if (strcmp(attr->name, "printer-info") == 0 && - attr->value_tag == IPP_TAG_TEXT) - info = attr->values[0].string.text; + attr->value_tag == IPP_TAG_TEXT) { + if (!pull_utf8_talloc(frame, + &info, + attr->values[0].string.text, + &size)) { + goto out; + } + } attr = attr->next; } @@ -225,7 +249,7 @@ bool cups_cache_reload(void) request->request.op.request_id = 1; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -265,12 +289,24 @@ bool cups_cache_reload(void) while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && - attr->value_tag == IPP_TAG_NAME) - name = attr->values[0].string.text; + attr->value_tag == IPP_TAG_NAME) { + if (!pull_utf8_talloc(frame, + &name, + attr->values[0].string.text, + &size)) { + goto out; + } + } if (strcmp(attr->name, "printer-info") == 0 && - attr->value_tag == IPP_TAG_TEXT) - info = attr->values[0].string.text; + attr->value_tag == IPP_TAG_TEXT) { + if (!pull_utf8_talloc(frame, + &info, + attr->values[0].string.text, + &size)) { + goto out; + } + } attr = attr->next; } @@ -299,6 +335,7 @@ bool cups_cache_reload(void) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -309,13 +346,15 @@ bool cups_cache_reload(void) static int cups_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ + char *user = NULL; char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + size_t size; DEBUG(5,("cups_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob)); @@ -329,7 +368,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -351,7 +390,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -360,8 +399,12 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + if (!push_utf8_talloc(frame, &user, pjob->user, &size)) { + goto out; + } + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, pjob->user); + NULL, user); /* * Do the request and get back a response... @@ -389,6 +432,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -399,13 +443,15 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru static int cups_job_pause(int snum, struct printjob *pjob) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ + char *user = NULL; char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + size_t size; DEBUG(5,("cups_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); @@ -419,7 +465,7 @@ static int cups_job_pause(int snum, struct printjob *pjob) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -441,7 +487,7 @@ static int cups_job_pause(int snum, struct printjob *pjob) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -450,8 +496,11 @@ static int cups_job_pause(int snum, struct printjob *pjob) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + if (!push_utf8_talloc(frame, &user, pjob->user, &size)) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, pjob->user); + NULL, user); /* * Do the request and get back a response... @@ -479,6 +528,7 @@ static int cups_job_pause(int snum, struct printjob *pjob) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -489,13 +539,15 @@ static int cups_job_pause(int snum, struct printjob *pjob) static int cups_job_resume(int snum, struct printjob *pjob) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ + char *user = NULL; char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + size_t size; DEBUG(5,("cups_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); @@ -509,7 +561,7 @@ static int cups_job_resume(int snum, struct printjob *pjob) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -531,7 +583,7 @@ static int cups_job_resume(int snum, struct printjob *pjob) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -540,8 +592,11 @@ static int cups_job_resume(int snum, struct printjob *pjob) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + if (!push_utf8_talloc(frame, &user, pjob->user, &size)) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, pjob->user); + NULL, user); /* * Do the request and get back a response... @@ -569,6 +624,7 @@ static int cups_job_resume(int snum, struct printjob *pjob) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -579,6 +635,7 @@ static int cups_job_resume(int snum, struct printjob *pjob) static int cups_job_submit(int snum, struct printjob *pjob) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ @@ -589,6 +646,12 @@ static int cups_job_submit(int snum, struct printjob *pjob) char *new_jobname = NULL; int num_options = 0; cups_option_t *options = NULL; + char *printername = NULL; + char *user = NULL; + char *jobname = NULL; + char *cupsoptions = NULL; + char *filename = NULL; + size_t size; char addr[INET6_ADDRSTRLEN]; DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); @@ -603,7 +666,7 @@ static int cups_job_submit(int snum, struct printjob *pjob) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -626,19 +689,25 @@ static int cups_job_submit(int snum, struct printjob *pjob) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); + if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { + goto out; + } slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", - PRINTERNAME(snum)); + printername); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); + if (!push_utf8_talloc(frame, &user, pjob->user, &size)) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, pjob->user); + NULL, user); clientname = client_name(get_client_fd()); if (strcmp(clientname, "UNKNOWN") == 0) { @@ -649,8 +718,14 @@ static int cups_job_submit(int snum, struct printjob *pjob) "job-originating-host-name", NULL, clientname); - if (asprintf(&new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX, - (unsigned int)pjob->smbjob, pjob->jobname) < 0) { + if (!push_utf8_talloc(frame, &jobname, pjob->jobname, &size)) { + goto out; + } + new_jobname = talloc_asprintf(frame, + "%s%.8u %s", PRINT_SPOOL_PREFIX, + (unsigned int)pjob->smbjob, + jobname); + if (new_jobname == NULL) { goto out; } @@ -661,9 +736,12 @@ static int cups_job_submit(int snum, struct printjob *pjob) * add any options defined in smb.conf */ + if (!push_utf8_talloc(frame, &cupsoptions, lp_cups_options(snum), &size)) { + goto out; + } num_options = 0; options = NULL; - num_options = cupsParseOptions(lp_cups_options(snum), num_options, &options); + num_options = cupsParseOptions(cupsoptions, num_options, &options); if ( num_options ) cupsEncodeOptions(request, num_options, options); @@ -672,8 +750,11 @@ static int cups_job_submit(int snum, struct printjob *pjob) * Do the request and get back a response... */ - slprintf(uri, sizeof(uri) - 1, "/printers/%s", PRINTERNAME(snum)); + slprintf(uri, sizeof(uri) - 1, "/printers/%s", printername); + if (!push_utf8_talloc(frame, &filename, pjob->filename, &size)) { + goto out; + } if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum), @@ -700,7 +781,7 @@ static int cups_job_submit(int snum, struct printjob *pjob) if (http) httpClose(http); - SAFE_FREE(new_jobname); + TALLOC_FREE(frame); return ret; } @@ -715,7 +796,8 @@ static int cups_queue_get(const char *sharename, print_queue_struct **q, print_status_struct *status) { - fstring printername; + TALLOC_CTX *frame = talloc_stackframe(); + char *printername = NULL; http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ @@ -726,13 +808,14 @@ static int cups_queue_get(const char *sharename, qalloc = 0; /* Number of queue entries allocated */ print_queue_struct *queue = NULL, /* Queue entries */ *temp; /* Temporary pointer for queue */ - const char *user_name, /* job-originating-user-name attribute */ - *job_name; /* job-name attribute */ + char *user_name = NULL, /* job-originating-user-name attribute */ + *job_name = NULL; /* job-name attribute */ int job_id; /* job-id attribute */ int job_k_octets; /* job-k-octets attribute */ time_t job_time; /* time-at-creation attribute */ ipp_jstate_t job_status; /* job-status attribute */ int job_priority; /* job-priority attribute */ + size_t size; static const char *jattrs[] = /* Requested job attributes */ { "job-id", @@ -757,9 +840,10 @@ static int cups_queue_get(const char *sharename, (which is basically what we do for non-cups printers ... using the lpq_command to get the queue listing). */ - fstrcpy( printername, lpq_command ); - - DEBUG(5,("cups_queue_get(%s, %p, %p)\n", printername, q, status)); + if (!push_utf8_talloc(frame, &printername, lpq_command, &size)) { + goto out; + } + DEBUG(5,("cups_queue_get(%s, %p, %p)\n", lpq_command, q, status)); /* * Make sure we don't ask for passwords... @@ -771,7 +855,7 @@ static int cups_queue_get(const char *sharename, * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -799,7 +883,7 @@ static int cups_queue_get(const char *sharename, language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -904,12 +988,24 @@ static int cups_queue_get(const char *sharename, job_time = attr->values[0].integer; if (strcmp(attr->name, "job-name") == 0 && - attr->value_tag == IPP_TAG_NAME) - job_name = attr->values[0].string.text; + attr->value_tag == IPP_TAG_NAME) { + if (!pull_utf8_talloc(frame, + &job_name, + attr->values[0].string.text, + &size)) { + goto out; + } + } if (strcmp(attr->name, "job-originating-user-name") == 0 && - attr->value_tag == IPP_TAG_NAME) - user_name = attr->values[0].string.text; + attr->value_tag == IPP_TAG_NAME) { + if (!pull_utf8_talloc(frame, + &user_name, + attr->values[0].string.text, + &size)) { + goto out; + } + } attr = attr->next; } @@ -933,8 +1029,8 @@ static int cups_queue_get(const char *sharename, LPQ_PRINTING; temp->priority = job_priority; temp->time = job_time; - strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1); - strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1); + strlcpy(temp->fs_user, user_name, sizeof(temp->fs_user)); + strlcpy(temp->fs_file, job_name, sizeof(temp->fs_file)); qcount ++; @@ -961,7 +1057,7 @@ static int cups_queue_get(const char *sharename, request->request.op.request_id = 1; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -1004,8 +1100,15 @@ static int cups_queue_get(const char *sharename, } if ((attr = ippFindAttribute(response, "printer-state-message", - IPP_TAG_TEXT)) != NULL) - fstrcpy(status->message, attr->values[0].string.text); + IPP_TAG_TEXT)) != NULL) { + char *msg = NULL; + if (!pull_utf8_talloc(frame, &msg, + attr->values[0].string.text, + &size)) { + goto out; + } + fstrcpy(status->message, msg); + } /* * Return the job queue... @@ -1023,6 +1126,7 @@ static int cups_queue_get(const char *sharename, if (http) httpClose(http); + TALLOC_FREE(frame); return qcount; } @@ -1033,13 +1137,16 @@ static int cups_queue_get(const char *sharename, static int cups_queue_pause(int snum) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ + char *printername = NULL; + char *username = NULL; char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + size_t size; DEBUG(5,("cups_queue_pause(%d)\n", snum)); @@ -1053,7 +1160,7 @@ static int cups_queue_pause(int snum) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -1075,18 +1182,24 @@ static int cups_queue_pause(int snum) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); + if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { + goto out; + } slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", - PRINTERNAME(snum)); + printername); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); + if (!push_utf8_talloc(frame, &username, current_user_info.unix_name, &size)) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, current_user_info.unix_name); + NULL, username); /* * Do the request and get back a response... @@ -1114,6 +1227,7 @@ static int cups_queue_pause(int snum) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -1124,13 +1238,16 @@ static int cups_queue_pause(int snum) static int cups_queue_resume(int snum) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ + char *printername = NULL; + char *username = NULL; char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + size_t size; DEBUG(5,("cups_queue_resume(%d)\n", snum)); @@ -1144,7 +1261,7 @@ static int cups_queue_resume(int snum) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -1166,18 +1283,24 @@ static int cups_queue_resume(int snum) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); + if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { + goto out; + } slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", - PRINTERNAME(snum)); + printername); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); + if (!push_utf8_talloc(frame, &username, current_user_info.unix_name, &size)) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, current_user_info.unix_name); + NULL, username); /* * Do the request and get back a response... @@ -1205,6 +1328,7 @@ static int cups_queue_resume(int snum) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -1226,15 +1350,16 @@ struct printif cups_printif = bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer) { + TALLOC_CTX *frame = talloc_stackframe(); http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ - char *name, /* printer-name attribute */ - *info, /* printer-info attribute */ - *location; /* printer-location attribute */ char uri[HTTP_MAX_URI]; + char *server = NULL; + char *sharename = NULL; + char *name = NULL; static const char *requested[] =/* Requested attributes */ { "printer-name", @@ -1242,6 +1367,7 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer) "printer-location" }; bool ret = False; + size_t size; DEBUG(5, ("pulling %s location\n", printer->sharename)); @@ -1255,7 +1381,7 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -1267,13 +1393,26 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); + if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) { + if (!push_utf8_talloc(frame, &server, lp_cups_server(), &size)) { + goto out; + } + } else { + server = talloc_strdup(frame,cupsServer()); + } + if (server) { + goto out; + } + if (!push_utf8_talloc(frame, &sharename, printer->sharename, &size)) { + goto out; + } slprintf(uri, sizeof(uri) - 1, "ipp://%s/printers/%s", - lp_cups_server(), printer->sharename); + server, sharename); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); @@ -1308,21 +1447,34 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer) * Pull the needed attributes from this printer... */ - name = NULL; - info = NULL; - location = NULL; - while ( attr && (attr->group_tag == IPP_TAG_PRINTER) ) { + if (strcmp(attr->name, "printer-name") == 0 && + attr->value_tag == IPP_TAG_NAME) { + if (!pull_utf8_talloc(frame, + &name, + attr->values[0].string.text, + &size)) { + goto out; + } + } + /* Grab the comment if we don't have one */ if ( (strcmp(attr->name, "printer-info") == 0) && (attr->value_tag == IPP_TAG_TEXT) && !strlen(printer->comment) ) { + char *comment = NULL; + if (!pull_utf8_talloc(frame, + &comment, + attr->values[0].string.text, + &size)) { + goto out; + } DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n", - attr->values[0].string.text)); + comment)); strlcpy(printer->comment, - attr->values[0].string.text, - sizeof(printer->comment)); + comment, + sizeof(printer->comment)); } /* Grab the location if we don't have one */ @@ -1330,21 +1482,29 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer) && (attr->value_tag == IPP_TAG_TEXT) && !strlen(printer->location) ) { + char *location = NULL; + if (!pull_utf8_talloc(frame, + &location, + attr->values[0].string.text, + &size)) { + goto out; + } DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n", - attr->values[0].string.text)); - fstrcpy(printer->location,attr->values[0].string.text); + location)); + strlcpy(printer->location, + location, + sizeof(printer->location)); } attr = attr->next; } /* - * See if we have everything needed... + * We have everything needed... */ - if (name == NULL) + if (name != NULL) break; - } ret = True; @@ -1359,6 +1519,7 @@ bool cups_pull_comment_location(NT_PRINTER_INFO_LEVEL_2 *printer) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } -- cgit From 9097a67def72ea41e85a4acb5d7cbcc46adaaa84 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 2 Oct 2008 02:17:04 +0200 Subject: Fix bug 5798: "CFLAGS info lost in configure" Michael, please check and merge to the other branches if it's right. Thanks, Volker --- source3/configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/configure.in b/source3/configure.in index f04ddbeaa5..545a5653de 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -128,7 +128,7 @@ fi if test "x$debug" = "xyes" ; then CFLAGS="${CFLAGS} -g" else - CFLAGS="-O" + CFLAGS="${CFLAGS} -O" fi m4_include(../lib/socket_wrapper/config.m4) -- cgit From 8641b54a736c5c924bf38cf4574d1f8e34d2d0cd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 2 Oct 2008 03:37:52 +0200 Subject: Attempt to fix the build on IRIX Under irix, "sa_family" is a #define to sa_union.sa_generic.sa_family2 --- source3/librpc/gen_ndr/nbt.h | 2 +- source3/librpc/gen_ndr/ndr_nbt.c | 6 +++--- source3/librpc/idl/nbt.idl | 2 +- source3/libsmb/dsgetdcname.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source3') diff --git a/source3/librpc/gen_ndr/nbt.h b/source3/librpc/gen_ndr/nbt.h index 264b00b84f..4b872d7936 100644 --- a/source3/librpc/gen_ndr/nbt.h +++ b/source3/librpc/gen_ndr/nbt.h @@ -391,7 +391,7 @@ struct nbt_dgram_packet { }/* [public,flag(LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_BIGENDIAN|LIBNDR_PRINT_ARRAY_HEX)] */; struct nbt_sockaddr { - uint32_t sa_family; + uint32_t sockaddr_family; const char * pdc_ip;/* [flag(LIBNDR_FLAG_BIGENDIAN)] */ DATA_BLOB remaining;/* [flag(LIBNDR_FLAG_REMAINING)] */ }/* [gensize,public] */; diff --git a/source3/librpc/gen_ndr/ndr_nbt.c b/source3/librpc/gen_ndr/ndr_nbt.c index 84cfabda57..c02b539da5 100644 --- a/source3/librpc/gen_ndr/ndr_nbt.c +++ b/source3/librpc/gen_ndr/ndr_nbt.c @@ -1531,7 +1531,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_nbt_sockaddr(struct ndr_push *ndr, int ndr_f { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sa_family)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->sockaddr_family)); { uint32_t _flags_save_ipv4address = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN); @@ -1554,7 +1554,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_nbt_sockaddr(struct ndr_pull *ndr, int ndr_f { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sa_family)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->sockaddr_family)); { uint32_t _flags_save_ipv4address = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN); @@ -1577,7 +1577,7 @@ _PUBLIC_ void ndr_print_nbt_sockaddr(struct ndr_print *ndr, const char *name, co { ndr_print_struct(ndr, name, "nbt_sockaddr"); ndr->depth++; - ndr_print_uint32(ndr, "sa_family", r->sa_family); + ndr_print_uint32(ndr, "sockaddr_family", r->sockaddr_family); ndr_print_ipv4address(ndr, "pdc_ip", r->pdc_ip); ndr_print_DATA_BLOB(ndr, "remaining", r->remaining); ndr->depth--; diff --git a/source3/librpc/idl/nbt.idl b/source3/librpc/idl/nbt.idl index 82571d96e6..f3590fcf2b 100644 --- a/source3/librpc/idl/nbt.idl +++ b/source3/librpc/idl/nbt.idl @@ -339,7 +339,7 @@ interface nbt */ typedef [public,gensize] struct { - uint32 sa_family; + uint32 sockaddr_family; [flag(NDR_BIG_ENDIAN)] ipv4address pdc_ip; [flag(NDR_REMAINING)] DATA_BLOB remaining; } nbt_sockaddr; diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 89769d8a76..d2ede1d875 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -200,7 +200,7 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx, /* FIXME */ r->sockaddr_size = 0x10; /* the w32 winsock addr size */ - r->sockaddr.sa_family = 2; /* AF_INET */ + r->sockaddr.sockaddr_family = 2; /* AF_INET */ r->sockaddr.pdc_ip = talloc_strdup(mem_ctx, addr); ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, r, -- cgit From af1c802791e3c9f54220d8c80c3de79ef422d726 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 2 Oct 2008 08:09:25 +0200 Subject: The IRIX compiler does not like embedded unnamed unions --- source3/libads/cldap.c | 2 +- source3/libsmb/clidgram.c | 4 ++-- source3/libsmb/dsgetdcname.c | 20 ++++++++++---------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index edabbed0e9..c37220c903 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -283,7 +283,7 @@ bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx, return false; } - *reply5 = reply->nt5_ex; + *reply5 = reply->data.nt5_ex; return true; } diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index e8799bce47..611ae0870c 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -279,8 +279,8 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, /* do we still need this ? */ *nt_version = r.ntver; - returned_domain = r.nt5_ex.domain; - returned_dc = r.nt5_ex.pdc_name; + returned_domain = r.data.nt5_ex.domain; + returned_dc = r.data.nt5_ex.pdc_name; if (!strequal(returned_domain, domain_name)) { DEBUG(3, ("GetDC: Expected domain %s, got %s\n", diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index d2ede1d875..18010aaa1c 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -272,12 +272,12 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response * case 3: case 18: case 19: - return r->nt5.server_type; + return r->data.nt5.server_type; case 4: case 5: case 6: case 7: - return r->nt5_ex.server_type; + return r->data.nt5_ex.server_type; case 8: case 9: case 10: @@ -286,7 +286,7 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response * case 13: case 14: case 15: - return r->nt5_ex.server_type; + return r->data.nt5_ex.server_type; case 20: case 21: case 22: @@ -296,11 +296,11 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response * case 26: case 27: case 28: - return r->nt5_ex.server_type; + return r->data.nt5_ex.server_type; case 29: case 30: case 31: - return r->nt5_ex.server_type; + return r->data.nt5_ex.server_type; default: return 0; } @@ -913,10 +913,10 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, } status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, - &r->nt5_ex, info); + &r->data.nt5_ex, info); if (NT_STATUS_IS_OK(status)) { return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, - nt_version, &r->nt5_ex); + nt_version, &r->data.nt5_ex); } return status; @@ -1035,7 +1035,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, logon1.domain = talloc_strdup_upper(mem_ctx, domain_name); NT_STATUS_HAVE_NO_MEMORY(logon1.domain); - r->nt4 = logon1; + r->data.nt4 = logon1; r->ntver = nt_version; namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); @@ -1049,10 +1049,10 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, make_reply: status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, - &r->nt5_ex, info); + &r->data.nt5_ex, info); if (NT_STATUS_IS_OK(status) && store_cache) { return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, - nt_version, &r->nt5_ex); + nt_version, &r->data.nt5_ex); } return status; -- cgit From f0c17496366547f14638763a6b8859c365f18792 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 2 Oct 2008 09:03:32 -0400 Subject: Fix bug 5805: don't close stdout - When calling setup_logging multiple times, the code was closing the debug file descriptor before opening or assigning the new one. We don't, however, want to close the debug file descriptor if it is stdout. Derrell --- source3/lib/debug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/lib/debug.c b/source3/lib/debug.c index d835ea7c17..d91b55dd23 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -578,7 +578,9 @@ void setup_logging(const char *pname, bool interactive) stdout_logging = False; if (dbf) { x_fflush(dbf); - (void) x_fclose(dbf); + if (dbf != x_stdout) { + (void) x_fclose(dbf); + } } dbf = NULL; -- cgit From e0dbac6873b816384f570ad8a7ceea7c96573d00 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Oct 2008 12:21:11 -0700 Subject: Don't reject a successful alloc :-(. Jeremy. --- source3/printing/print_cups.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index b46d83bb01..b9bed7a138 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -71,7 +71,7 @@ static http_t *cups_connect(TALLOC_CTX *frame) } else { server = talloc_strdup(frame,cupsServer()); } - if (server) { + if (!server) { return NULL; } -- cgit From 8e1d93e6a692676744c267dfd0d95802ff036a5f Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Fri, 3 Oct 2008 10:51:21 -0500 Subject: libaddns: Use the same prerequisite for DDNS update as Windows XP. Hostname, TYPE: CNAME, CLASS: NONE This has to have been broken for ages. I cannot see how it would have worked in any environment. --- source3/libaddns/dnsrecord.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3') diff --git a/source3/libaddns/dnsrecord.c b/source3/libaddns/dnsrecord.c index 500cbd6681..559c2644d4 100644 --- a/source3/libaddns/dnsrecord.c +++ b/source3/libaddns/dnsrecord.c @@ -378,10 +378,10 @@ DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx, if (!ERR_DNS_IS_OK(err)) return err; /* - * The zone must be used at all + * Use the same prereq as WinXP -- No CNAME records for this host. */ - err = dns_create_rrec(req, domainname, QTYPE_ANY, DNS_CLASS_ANY, + err = dns_create_rrec(req, hostname, QTYPE_CNAME, DNS_CLASS_NONE, 0, 0, NULL, &rec); if (!ERR_DNS_IS_OK(err)) goto error; -- cgit From c7625979ceb350d90d87d2add6ed7156440072c3 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Fri, 3 Oct 2008 10:51:54 -0500 Subject: net_dns: Make "lwinet ads dns register" honor the "interfaces" parameter. This is helpful on multihomed hosts that only require a subset of IP addresses be registered with DNS. --- source3/utils/net_dns.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c index 14d45e2b0f..46f38d42f6 100644 --- a/source3/utils/net_dns.c +++ b/source3/utils/net_dns.c @@ -150,9 +150,10 @@ int get_my_ip_address( struct sockaddr_storage **pp_ss ) struct sockaddr_storage *list = NULL; int count = 0; - /* find the first non-loopback address from our list of interfaces */ + /* Honor the configured list of interfaces to register */ - n = get_interfaces(nics, MAX_INTERFACES); + load_interfaces(); + n = iface_count(); if (n <= 0) { return -1; @@ -163,19 +164,17 @@ int get_my_ip_address( struct sockaddr_storage **pp_ss ) } for ( i=0; i