r698: Now wb pipe is non-blocking remember to read in non-blocking mode...
authorJeremy Allison <jra@samba.org>
Thu, 13 May 2004 18:37:54 +0000 (18:37 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:51:34 +0000 (10:51 -0500)
Jeremy.

source/nsswitch/wb_common.c
source/smbd/trans2.c

index ef8fc3e40fd48fc4c74ca663bd253e4b6813fe1e..9caf7affc3934a2e517e1bf4be20c46ae17f63fc 100644 (file)
@@ -410,25 +410,58 @@ int write_sock(void *buffer, int count)
 static int read_sock(void *buffer, int count)
 {
        int result = 0, nread = 0;
+       int total_time = 0, selret;
 
        /* Read data from socket */
-       
        while(nread < count) {
+               struct timeval tv;
+               fd_set r_fds;
                
-               result = read(winbindd_fd, (char *)buffer + nread, 
-                             count - nread);
+               /* Catch pipe close on other end by checking if a read()
+                  call would not block by calling select(). */
+
+               FD_ZERO(&r_fds);
+               FD_SET(winbindd_fd, &r_fds);
+               ZERO_STRUCT(tv);
+               /* Wait for 5 seconds for a reply. May need to parameterise this... */
+               tv.tv_sec = 5;
+
+               if ((selret = select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv)) == -1) {
+                       close_sock();
+                       return -1;                   /* Select error */
+               }
                
-               if ((result == -1) || (result == 0)) {
+               if (selret == 0) {
+                       /* Not ready for read yet... */
+                       if (total_time >= 30) {
+                               /* Timeout */
+                               close_sock();
+                               return -1;
+                       }
+                       total_time += 5;
+                       continue;
+               }
+
+               if (FD_ISSET(winbindd_fd, &r_fds)) {
                        
-                       /* Read failed.  I think the only useful thing we
-                          can do here is just return -1 and fail since the
-                          transaction has failed half way through. */
+                       /* Do the Read */
+                       
+                       result = read(winbindd_fd, (char *)buffer + nread, 
+                             count - nread);
+                       
+                       if ((result == -1) || (result == 0)) {
+                               
+                               /* Read failed.  I think the only useful thing we
+                                  can do here is just return -1 and fail since the
+                                  transaction has failed half way through. */
+                       
+                               close_sock();
+                               return -1;
+                       }
+                       
+                       nread += result;
                        
-                       close_sock();
-                       return -1;
                }
-               
-               nread += result;
        }
        
        return result;
index 91196766d1dac6de929b2f67a6f7e31b5a0612b9..ba2931d80914cdcb2a1bb09792cada6cd858016e 100644 (file)
@@ -3506,12 +3506,17 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                        srvstr_pull(inbuf, link_target, pdata, sizeof(link_target), -1, STR_TERMINATE);
 
                        /* !widelinks forces the target path to be within the share. */
+                       /* This means we can interpret the target as a pathname. */
                        if (!lp_widelinks(SNUM(conn))) {
                                pstring rel_name;
                                char *last_dirp = NULL;
 
-                               unix_format(link_target);
-
+                               srvstr_get_path(inbuf, link_target, pdata, sizeof(link_target),
+                                               -1, STR_TERMINATE, &status);
+                               if (!NT_STATUS_IS_OK(status)) {
+                                       return ERROR_NT(status);
+                               }
+                               unix_convert(link_target,conn,0,&bad_path,&sbuf);
                                pstrcpy(rel_name, newname);
                                last_dirp = strrchr_m(rel_name, '/');
                                if (last_dirp) {
@@ -3520,6 +3525,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
                                        pstrcpy(rel_name, "./");
                                }
                                pstrcat(rel_name, link_target);
+
                                if (ensure_link_is_safe(conn, rel_name) != 0) {
                                        return(UNIXERROR(ERRDOS,ERRnoaccess));
                                }