r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[bbaumbach/samba-autobuild/.git] / source3 / libsmb / libsmbclient.c
index 4778274ca9d55b729ed3fb80e6a0f5e2dc471f9e..90cde9100af4d33ca01ba7ea26bdcb53ee3a8e22 100644 (file)
@@ -9,7 +9,7 @@
    
    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
-   the Free Software Foundation; either version 2 of the License, or
+   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,
@@ -18,8 +18,7 @@
    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, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
@@ -339,14 +338,15 @@ smbc_parse_path(SMBCCTX *context,
            goto decoding;
 
        if (*p == '/') {
+               int wl = strlen(context->workgroup);
 
-               strncpy(server, context->workgroup, 
-                       ((strlen(context->workgroup) < 16)
-                         ? strlen(context->workgroup)
-                         : 16));
-                server[server_len - 1] = '\0';
+               if (wl > 16) {
+                       wl = 16;
+               }
+
+               strncpy(server, context->workgroup, wl);
+                server[wl] = '\0';
                return 0;
-               
        }
 
        /*
@@ -499,8 +499,30 @@ static int
 smbc_check_server(SMBCCTX * context,
                   SMBCSRV * server) 
 {
-       if ( send_keepalive(server->cli->fd) == False )
-               return 1;
+        socklen_t size;
+        struct sockaddr addr;
+
+        /*
+         * Although the use of port 139 is not a guarantee that we're using
+         * netbios, we assume so.  We don't want to send a keepalive packet if
+         * not netbios because it's not valid, and Vista, at least,
+         * disconnects the client on such a request.
+         */
+        if (server->cli->port == 139) {
+                /* Assuming netbios.  Send a keepalive packet */
+                if ( send_keepalive(server->cli->fd) == False ) {
+                        return 1;
+                }
+        } else {
+                /*
+                 * Assuming not netbios.  Try a different method to detect if
+                 * the connection is still alive.
+                 */
+                size = sizeof(addr);
+                if (getpeername(server->cli->fd, &addr, &size) == -1) {
+                        return 1;
+                }
+        }
 
        /* connection is ok */
        return 0;
@@ -652,7 +674,8 @@ smbc_server(SMBCCTX *context,
         int port_try_first;
         int port_try_next;
         const char *username_used;
-  
+       NTSTATUS status;
+
        zero_ip(&ip);
        ZERO_STRUCT(c);
 
@@ -772,17 +795,19 @@ smbc_server(SMBCCTX *context,
 
         c->port = port_try_first;
 
-       if (!cli_connect(c, server_n, &ip)) {
+       status = cli_connect(c, server_n, &ip);
+       if (!NT_STATUS_IS_OK(status)) {
 
                 /* First connection attempt failed.  Try alternate port. */
                 c->port = port_try_next;
 
-                if (!cli_connect(c, server_n, &ip)) {
-                        cli_shutdown(c);
-                        errno = ETIMEDOUT;
-                        return NULL;
-                }
-       }
+                status = cli_connect(c, server_n, &ip);
+               if (!NT_STATUS_IS_OK(status)) {
+                       cli_shutdown(c);
+                       errno = ETIMEDOUT;
+                       return NULL;
+               }
+       }
 
        if (!cli_session_request(c, &calling, &called)) {
                cli_shutdown(c);
@@ -917,6 +942,7 @@ smbc_attr_server(SMBCCTX *context,
                  fstring password,
                  POLICY_HND *pol)
 {
+        int flags;
         struct in_addr ip;
        struct cli_state *ipc_cli;
        struct rpc_pipe_client *pipe_hnd;
@@ -951,12 +977,17 @@ smbc_attr_server(SMBCCTX *context,
                         }
                 }
         
+                flags = 0;
+                if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) {
+                        flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
+                }
+
                 zero_ip(&ip);
                 nt_status = cli_full_connection(&ipc_cli,
                                                 global_myname(), server, 
                                                 &ip, 0, "IPC$", "?????",  
                                                 username, workgroup,
-                                                password, 0,
+                                                password, flags,
                                                 Undefined, NULL);
                 if (! NT_STATUS_IS_OK(nt_status)) {
                         DEBUG(1,("cli_full_connection failed! (%s)\n",
@@ -1116,13 +1147,6 @@ smbc_open_ctx(SMBCCTX *context,
                }
                /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/
                
-               if ( targetcli->dfsroot )
-               {
-                       pstring temppath;
-                       pstrcpy(temppath, targetpath);
-                       cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath);
-               }
-               
                if ((fd = cli_open(targetcli, targetpath, flags,
                                    context->internal->_share_mode)) < 0) {
 
@@ -1519,14 +1543,6 @@ smbc_getatr(SMBCCTX * context,
                return False;
        }
        
-       if ( targetcli->dfsroot )
-       {
-               pstring temppath;
-               pstrcpy(temppath, targetpath);
-               cli_dfs_make_full_path(targetpath, targetcli->desthost,
-                                       targetcli->share, temppath);
-       }
-  
        if (!srv->no_pathinfo2 &&
             cli_qpathinfo2(targetcli, targetpath,
                            create_time_ts,
@@ -3832,7 +3848,7 @@ convert_string_to_sid(struct cli_state *ipc_cli,
         }
 
        if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx, 
-                                                 pol, 1, &str, NULL, &sids, 
+                                                 pol, 1, &str, NULL, 1, &sids, 
                                                  &types))) {
                result = False;
                goto done;
@@ -4532,7 +4548,7 @@ cacl_get(SMBCCTX *context,
                                                 return -1;
                                         }
                                         n = strlen(p);
-                                } else {
+                                } else if (sidstr[0] != '\0') {
                                         n = snprintf(buf, bufsize,
                                                      ",OWNER:%s", sidstr);
                                 }
@@ -4577,7 +4593,7 @@ cacl_get(SMBCCTX *context,
                                                 return -1;
                                         }
                                         n = strlen(p);
-                                } else {
+                                } else if (sidstr[0] != '\0') {
                                         n = snprintf(buf, bufsize,
                                                      ",GROUP:%s", sidstr);
                                 }
@@ -4685,7 +4701,7 @@ cacl_get(SMBCCTX *context,
                                                              ace->access_mask);
                                         }
                                 }
-                                if (n > bufsize) {
+                                if (!determine_size && n > bufsize) {
                                         errno = ERANGE;
                                         return -1;
                                 }
@@ -5303,7 +5319,9 @@ smbc_setxattr_ctx(SMBCCTX *context,
                 ipc_srv = smbc_attr_server(context, server, share,
                                            workgroup, user, password,
                                            &pol);
-                srv->no_nt_session = True;
+                if (! ipc_srv) {
+                        srv->no_nt_session = True;
+                }
         } else {
                 ipc_srv = NULL;
         }
@@ -5728,7 +5746,9 @@ smbc_removexattr_ctx(SMBCCTX *context,
                 ipc_srv = smbc_attr_server(context, server, share,
                                            workgroup, user, password,
                                            &pol);
-                srv->no_nt_session = True;
+                if (! ipc_srv) {
+                        srv->no_nt_session = True;
+                }
         } else {
                 ipc_srv = NULL;
         }