Sophie

Sophie

distrib > Mageia > 1 > i586 > media > core-updates-src > by-pkgid > e94d8e4decf5b88bc3ad2f6b46580f6c > files > 8

samba-3.5.8-1.3.mga1.src.rpm

diff -Naurp samba-3.5.10/client/mount.cifs.c samba-3.5.10.oden/client/mount.cifs.c
--- samba-3.5.10/client/mount.cifs.c	2011-07-24 20:04:44.000000000 +0000
+++ samba-3.5.10.oden/client/mount.cifs.c	2011-10-11 07:31:50.000000000 +0000
@@ -41,6 +41,7 @@
 #include <limits.h>
 #include <fstab.h>
 #include "mount.h"
+#include <signal.h>
 
 #define MOUNT_CIFS_VERSION_MAJOR "1"
 #define MOUNT_CIFS_VERSION_MINOR "14"
@@ -338,9 +339,9 @@ static void mount_cifs_usage(FILE *strea
 }
 
 /* caller frees username if necessary */
-static char * getusername(void) {
+static char * getusername(uid_t uid) {
 	char *username = NULL;
-	struct passwd *password = getpwuid(getuid());
+	struct passwd *password = getpwuid(uid);
 
 	if (password) {
 		username = password->pw_name;
@@ -1243,6 +1244,7 @@ int main(int argc, char ** argv)
 	char * resolved_path = NULL;
 	char * temp;
 	char * dev_name;
+	char * mount_user = NULL;
 	int rc = 0;
 	int rsize = 0;
 	int wsize = 0;
@@ -1251,6 +1253,7 @@ int main(int argc, char ** argv)
 	int gid = 0;
 	int optlen = 0;
 	int orgoptlen = 0;
+	int fd, tmprc;
 	size_t options_size = 0;
 	size_t current_len;
 	int retry = 0; /* set when we have to retry mount with uppercase */
@@ -1259,7 +1262,9 @@ int main(int argc, char ** argv)
 	struct mntent mountent;
 	struct sockaddr_in *addr4;
 	struct sockaddr_in6 *addr6;
+	struct stat statbuf;
 	FILE * pmntfile;
+	sigset_t mask, oldmask;
 
 	if (check_setuid())
 		return EX_USAGE;
@@ -1539,7 +1544,7 @@ int main(int argc, char ** argv)
 		if (getenv("USER"))
 			user_name = strdup(getenv("USER"));
 		if (user_name == NULL)
-			user_name = getusername();
+			user_name = getusername(getuid());
 		got_user = 1;
 	}
        
@@ -1712,6 +1717,38 @@ mount_retry:
 
 	if (nomtab)
 		goto mount_exit;
+
+	uid = getuid();
+	if (uid != 0)
+		mount_user = getusername(uid);
+
+	/*
+	 * Set the real uid to the effective uid. This prevents unprivileged
+	 * users from sending signals to this process, though ^c on controlling
+	 * terminal should still work.
+	 */
+	rc = setreuid(geteuid(), -1);
+	if (rc != 0) {
+		fprintf(stderr, "Unable to set real uid to effective uid: %s\n",
+				strerror(errno));
+		rc = EX_FILEIO;
+		goto mount_exit;
+	}
+
+	rc = sigfillset(&mask);
+	if (rc) {
+		fprintf(stderr, "Unable to set filled signal mask\n");
+		rc = EX_FILEIO;
+		goto mount_exit;
+	}
+
+	rc = sigprocmask(SIG_SETMASK, &mask, &oldmask);
+	if (rc) {
+		fprintf(stderr, "Unable to make process ignore signals\n");
+		rc = EX_FILEIO;
+		goto mount_exit;
+	}
+
 	atexit(unlock_mtab);
 	rc = lock_mtab();
 	if (rc) {
@@ -1725,12 +1762,27 @@ mount_retry:
 		rc = EX_FILEIO;
 		goto mount_exit;
 	}
+	fd = fileno(pmntfile);
+	if (fd < 0) {
+		fprintf(stderr, "mntent does not appear to be valid\n");
+		unlock_mtab();
+		rc = EX_FILEIO;
+		goto mount_exit;
+	}
+	rc = fstat(fd, &statbuf);
+	if (rc != 0) {
+		fprintf(stderr, "unable to fstat open mtab\n");
+		endmntent(pmntfile);
+		unlock_mtab();
+		rc = EX_FILEIO;
+		goto mount_exit;
+	}
+
 	mountent.mnt_fsname = dev_name;
 	mountent.mnt_dir = mountpoint;
 	mountent.mnt_type = CONST_DISCARD(char *,"cifs");
 	mountent.mnt_opts = (char *)malloc(220);
 	if(mountent.mnt_opts) {
-		char * mount_user = getusername();
 		memset(mountent.mnt_opts,0,200);
 		if(flags & MS_RDONLY)
 			strlcat(mountent.mnt_opts,"ro",220);
@@ -1757,12 +1809,21 @@ mount_retry:
 	}
 	mountent.mnt_freq = 0;
 	mountent.mnt_passno = 0;
-	rc = addmntent(pmntfile,&mountent);
-	endmntent(pmntfile);
+	rc = addmntent(pmntfile, &mountent);
+	if (rc) {
+		fprintf(stderr, "unable to add mount entry to mtab\n");
+		ftruncate(fd, statbuf.st_size);
+	}
+	tmprc = my_endmntent(pmntfile, statbuf.st_size);
+	if (tmprc) {
+		fprintf(stderr, "error %d detected on close of mtab\n", tmprc);
+		rc = EX_FILEIO;
+	}
 	unlock_mtab();
 	SAFE_FREE(mountent.mnt_opts);
 	if (rc)
 		rc = EX_FILEIO;
+	sigprocmask(SIG_SETMASK, &oldmask, NULL);
 mount_exit:
 	if(mountpassword) {
 		int len = strlen(mountpassword);
diff -Naurp samba-3.5.10/client/mount.h samba-3.5.10.oden/client/mount.h
--- samba-3.5.10/client/mount.h	2011-07-24 20:04:44.000000000 +0000
+++ samba-3.5.10.oden/client/mount.h	2011-10-11 07:31:50.000000000 +0000
@@ -34,5 +34,6 @@
 
 extern int lock_mtab(void);
 extern void unlock_mtab(void);
+extern int my_endmntent(FILE *stream, off_t size);
 
 #endif /* ! _MOUNT_H_ */
diff -Naurp samba-3.5.10/client/mtab.c samba-3.5.10.oden/client/mtab.c
--- samba-3.5.10/client/mtab.c	2011-07-24 20:04:44.000000000 +0000
+++ samba-3.5.10.oden/client/mtab.c	2011-10-11 07:31:50.000000000 +0000
@@ -218,3 +218,30 @@ lock_mtab (void) {
 	return 0;
 }
 
+/*
+ * Call fflush and fsync on the mtab, and then endmntent. If either fflush
+ * or fsync fails, then truncate the file back to "size". endmntent is called
+ * unconditionally, and the errno (if any) from fflush and fsync are returned.
+ */
+int
+my_endmntent(FILE *stream, off_t size)
+{
+	int rc, fd;
+
+	fd = fileno(stream);
+	if (fd < 0)
+		return -EBADF;
+
+	rc = fflush(stream);
+	if (!rc)
+		rc = fsync(fd);
+
+	/* truncate file back to "size" -- best effort here */
+	if (rc) {
+		rc = errno;
+		ftruncate(fd, size);
+	}
+
+	endmntent(stream);
+	return rc;
+}