Sophie

Sophie

distrib > Mageia > 5 > i586 > media > core-release-src > by-pkgid > a7fe86b581f2eef34cb4cb3b972bd3a8 > files > 5

ncpfs-2.2.6-18.mga5.src.rpm

diff -Naurp ncpfs-2.2.6/sutil/ncpm_common.c ncpfs-2.2.6.oden/sutil/ncpm_common.c
--- ncpfs-2.2.6/sutil/ncpm_common.c	2005-01-27 12:35:59.000000000 -0500
+++ ncpfs-2.2.6.oden/sutil/ncpm_common.c	2010-02-23 08:41:30.000000000 -0500
@@ -444,7 +444,7 @@ static int ncp_mount_v2(const char* moun
 	}
         datav2.file_mode   = data->file_mode;
         datav2.dir_mode    = data->dir_mode;
-	err = proc_ncpm_mount(mount_name, data->mount_point, "ncpfs", flags, (void*) &datav2);
+	err = proc_ncpm_mount(mount_name, ".", "ncpfs", flags, (void*) &datav2);
 	if (err)
 		return errno;
 	return 0;
@@ -508,7 +508,7 @@ static int ncp_mount_v3(const char* moun
 		exit(0);	/* Should not return from process_connection */
 	}
 	close(pp[0]);
-	err=proc_ncpm_mount(mount_name, data->mount_point, "ncpfs", flags, (void*) &datav3);
+	err=proc_ncpm_mount(mount_name, ".", "ncpfs", flags, (void*) &datav3);
 	if (err) {
 		err = errno;
 		/* Mount unsuccesful so we have to kill daemon */
@@ -559,7 +559,7 @@ static int ncp_mount_v4(const char* moun
 		sprintf(mountopts, "version=%u,flags=%u,owner=%u,uid=%u,gid=%u,mode=%u,dirmode=%u,timeout=%u,retry=%u,wdogpid=%u,ncpfd=%u,infofd=%u",
 			NCP_MOUNT_VERSION_V5, ncpflags, data->mounted_uid, data->uid, data->gid, data->file_mode,
 			data->dir_mode, data->time_out, data->retry_count, wdog_pid, data->ncp_fd, pp[1]);
-		err=proc_ncpm_mount(mount_name, data->mount_point, "ncpfs", flags, mountopts);
+		err=proc_ncpm_mount(mount_name, ".", "ncpfs", flags, mountopts);
 	} else {
 		err=-1;
 	}
@@ -577,7 +577,7 @@ static int ncp_mount_v4(const char* moun
 	        datav4.file_mode   = data->file_mode;
         	datav4.dir_mode    = data->dir_mode;
 		datav4.wdog_pid	   = wdog_pid;
-		err = proc_ncpm_mount(mount_name, data->mount_point, "ncpfs", flags, (void*)&datav4);
+		err = proc_ncpm_mount(mount_name, ".", "ncpfs", flags, (void*)&datav4);
 		if (err) {
 			err = errno;
 			/* Mount unsuccesful so we have to kill daemon */
@@ -1395,6 +1395,17 @@ process_connection (const struct ncp_mou
 }
 #endif /* MOUNT3 */
 
+static int check_name(const char *name)
+{
+	char *s;
+	for (s = "\n\t\\"; *s; s++) {
+		if (strchr(name, *s)) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
 static const struct smntflags {
 	unsigned int	flag;
 	const char*	name;
@@ -1416,6 +1427,9 @@ void add_mnt_entry(char* mount_name, cha
 	int fd;
 	FILE* mtab;
 
+	if (check_name(mount_name) == -1 || check_name(mpnt) == -1)
+		errexit(107, _("Illegal character in mount entry\n"));
+
 	ment.mnt_fsname = mount_name;
 	ment.mnt_dir = mpnt;
 	ment.mnt_type = (char*)"ncpfs";
diff -Naurp ncpfs-2.2.6/sutil/ncpmount.c ncpfs-2.2.6.oden/sutil/ncpmount.c
--- ncpfs-2.2.6/sutil/ncpmount.c	2005-01-27 12:35:59.000000000 -0500
+++ ncpfs-2.2.6.oden/sutil/ncpmount.c	2010-02-23 08:41:30.000000000 -0500
@@ -359,11 +359,17 @@ main(int argc, char *argv[])
 		usage();
 		return -1;
 	}
+
 	realpath(argv[optind], mount_point);
 
-	if (stat(mount_point, &st) == -1)
+	if (chdir(mount_point))
+	{
+		errexit(31, _("Could not change directory into mount target %s: %s\n"),
+			mount_point, strerror(errno));
+	}
+	if (stat(".", &st) == -1)
 	{
-		errexit(31, _("Could not find mount point %s: %s\n"),
+		errexit(31, _("Mount point %s does not exist: %s\n"),
 			mount_point, strerror(errno));
 	}
 	if (mount_ok(&st) != 0)
diff -Naurp ncpfs-2.2.6/sutil/ncpumount.c ncpfs-2.2.6.oden/sutil/ncpumount.c
--- ncpfs-2.2.6/sutil/ncpumount.c	2005-01-27 12:35:59.000000000 -0500
+++ ncpfs-2.2.6.oden/sutil/ncpumount.c	2010-02-23 08:41:30.000000000 -0500
@@ -70,10 +70,19 @@
 #include <mntent.h>
 #include <pwd.h>
 
+#include <sched.h>
+
 #include "private/libintl.h"
 
 #define _(X) X
 
+#ifndef MS_REC
+#define MS_REC 16384
+#endif
+#ifndef MS_SLAVE
+#define MS_SLAVE (1<<19)
+#endif
+
 static char *progname;
 static int is_ncplogout = 0;
 
@@ -229,11 +238,188 @@ static int clearMtab (const char* mount_
 	return err;
 }
 
+
+int ncp_mnt_umount(const char *abs_mnt, const char *rel_mnt)
+{
+	if (umount(rel_mnt) != 0) {
+		eprintf(_("Could not umount %s: %s\n"),
+			abs_mnt, strerror(errno));
+		return -1;
+	}
+	return 0;
+}
+
+
+static int check_is_mount_child(void *p)
+{
+	const char **a = p;
+	const char *last = a[0];
+	const char *mnt = a[1];
+	int res;
+	const char *procmounts = "/proc/mounts";
+	int found;
+	FILE *fp;
+	struct mntent *entp;
+
+	res = mount("", "/", "", MS_SLAVE | MS_REC, NULL);
+	if (res == -1) {
+		eprintf(_("Failed to mark mounts slave: %s\n"),
+			strerror(errno));
+		return 1;
+	}
+
+	res = mount(".", "/tmp", "", MS_BIND | MS_REC, NULL);
+	if (res == -1) {
+		eprintf(_("Failed to bind parent to /tmp: %s\n"),
+			strerror(errno));
+		return 1;
+	}
+
+	fp = setmntent(procmounts, "r");
+	if (fp == NULL) {
+		eprintf(_("Failed to open %s: %s\n"),
+			procmounts, strerror(errno));
+		return 1;
+	}
+
+	found = 0;
+	while ((entp = getmntent(fp)) != NULL) {
+		if (strncmp(entp->mnt_dir, "/tmp/", 5) == 0 &&
+		    strcmp(entp->mnt_dir + 5, last) == 0) {
+			found = 1;
+			break;
+		}
+	}
+	endmntent(fp);
+
+	if (!found) {
+		eprintf(_("%s not mounted\n"), mnt);
+		return 1;
+	}
+
+	return 0;
+}
+
+
+static int check_is_mount(const char *last, const char *mnt)
+{
+	char buf[131072];
+	pid_t pid, p;
+	int status;
+	const char *a[2] = { last, mnt };
+
+	pid = clone(check_is_mount_child, buf + 65536, CLONE_NEWNS, (void *) a);
+	if (pid == (pid_t) -1) {
+		eprintf(_("Failed to clone namespace: %s\n"),
+			strerror(errno));
+		return -1;
+	}
+	p = waitpid(pid, &status, __WCLONE);
+	if (p == (pid_t) -1) {
+		eprintf(_("Waitpid failed: %s\n"),
+			strerror(errno));
+		return -1;
+	}
+	if (!WIFEXITED(status)) {
+		eprintf(_("Child terminated abnormally (status %i)\n"),
+			status);
+		return -1;
+	}
+	if (WEXITSTATUS(status) != 0)
+		return -1;
+
+	return 0;
+}
+
+
+static int chdir_to_parent(char *copy, const char **lastp, int *currdir_fd)
+{
+	char *tmp;
+	const char *parent;
+	char buf[PATH_MAX];
+	int res;
+
+	tmp = strrchr(copy, '/');
+	if (tmp == NULL || tmp[1] == '\0') {
+		eprintf(_("Internal error: invalid abs path: <%s>\n"),
+			copy);
+		return -1;
+	}
+	if (tmp != copy) {
+		*tmp = '\0';
+		parent = copy;
+		*lastp = tmp + 1;
+	} else if (tmp[1] != '\0') {
+		*lastp = tmp + 1;
+		parent = "/";
+	} else {
+		*lastp = ".";
+		parent = "/";
+	}
+	*currdir_fd = open(".", O_RDONLY);
+	if (*currdir_fd == -1) {
+		eprintf(_("Failed to open current directory: %s\n"),
+			strerror(errno));
+		return -1;
+	}
+	res = chdir(parent);
+	if (res == -1) {
+		eprintf(_("Failed to chdir to %s: %s\n"),
+			parent, strerror(errno));
+		return -1;
+	}
+	if (getcwd(buf, sizeof(buf)) == NULL) {
+		eprintf(_("Failed to obtain current directory: %s\n"),
+			strerror(errno));
+		return -1;
+	}
+	if (strcmp(buf, parent) != 0) {
+		eprintf(_("Mountpoint moved (%s -> %s)\n"),
+			parent, buf);
+		return -1;
+
+	}
+
+	return 0;
+}
+
+
+static int unmount_ncp(const char *mount_point)
+{
+	int currdir_fd = -1;
+	char *copy;
+	const char *last;
+	int res;
+
+	copy = strdup(mount_point);
+	if (copy == NULL) {
+		eprintf(_("Failed to allocate memory\n"));
+		return -1;
+	}
+	res = chdir_to_parent(copy, &last, &currdir_fd);
+	if (res == -1)
+		goto out;
+	res = check_is_mount(last, mount_point);
+	if (res == -1)
+		goto out;
+	res = ncp_mnt_umount(mount_point, last);
+
+out:
+	free(copy);
+	if (currdir_fd != -1) {
+		fchdir(currdir_fd);
+		close(currdir_fd);
+	}
+
+	return res;
+}
+
 static int
 do_umount(const char *mount_point)
 {
 	int fid = open(mount_point, O_RDONLY, 0);
 	uid_t mount_uid;
+	int res;
 
 	if (fid == -1) {
 		eprintf(_("Could not open %s: %s\n"),
@@ -253,12 +439,8 @@ do_umount(const char *mount_point)
 		return -1;
 	}
 	close(fid);
-	if (umount(mount_point) != 0) {
-		eprintf(_("Could not umount %s: %s\n"),
-			mount_point, strerror(errno));
-		return -1;
-	}
-	return 0;
+	res = unmount_ncp(mount_point);
+	return res;
 }