summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/nsswitch/wb_common.c55
-rw-r--r--source3/smbd/trans2.c10
2 files changed, 52 insertions, 13 deletions
diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c
index ef8fc3e40f..9caf7affc3 100644
--- a/source3/nsswitch/wb_common.c
+++ b/source3/nsswitch/wb_common.c
@@ -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;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 91196766d1..ba2931d809 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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));
}