summaryrefslogtreecommitdiff
path: root/debian/patches-applied/hurd_no_setfsuid
blob: 8a27b2969462e8dfc02263b2f632cf167250317b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
On systems without setfsuid(), use setreuid() instead.

Authors: Steve Langasek <vorlon@debian.org>

Upstream status: to be forwarded, now that pam_modutil_{drop,regain}_priv
 are implemented

Index: pam-debian/libpam/pam_modutil_priv.c
===================================================================
--- pam-debian.orig/libpam/pam_modutil_priv.c	2011-10-10 16:21:57.858599186 -0700
+++ pam-debian/libpam/pam_modutil_priv.c	2011-10-10 17:31:02.805686298 -0700
@@ -14,7 +14,9 @@
 #include <syslog.h>
 #include <pwd.h>
 #include <grp.h>
+#ifdef HAVE_SYS_FSUID_H
 #include <sys/fsuid.h>
+#endif /* HAVE_SYS_FSUID_H */
 
 /*
  * Two setfsuid() calls in a row are necessary to check
@@ -22,17 +24,61 @@
  */
 static int change_uid(uid_t uid, uid_t *save)
 {
+#ifdef HAVE_SYS_FSUID_H
 	uid_t tmp = setfsuid(uid);
 	if (save)
 		*save = tmp;
 	return (uid_t) setfsuid(uid) == uid ? 0 : -1;
+#else
+	uid_t euid = geteuid();
+	uid_t ruid = getuid();
+	if (save)
+		*save = ruid;
+	if (ruid == uid && uid != 0)
+		if (setreuid(euid, uid))
+			return -1;
+	else {
+		if (setreuid(0, -1))
+			return -1;
+		if (setreuid(-1, uid)) {
+			if (setreuid(-1, 0))
+				return -1;
+			if (setreuid(0, -1))
+				return -1;
+			if (setreuid(-1, uid))
+				return -1;
+		}
+	}
+#endif
 }
 static int change_gid(gid_t gid, gid_t *save)
 {
+#ifdef HAVE_SYS_FSUID_H
 	gid_t tmp = setfsgid(gid);
 	if (save)
 		*save = tmp;
 	return (gid_t) setfsgid(gid) == gid ? 0 : -1;
+#else
+	gid_t egid = getegid();
+	gid_t rgid = getgid();
+	if (save)
+		*save = rgid;
+	if (rgid == gid)
+		if (setregid(egid, gid))
+			return -1;
+	else {
+		if (setregid(0, -1))
+			return -1;
+		if (setregid(-1, gid)) {
+			if (setregid(-1, 0))
+				return -1;
+			if (setregid(0, -1))
+				return -1;
+			if (setregid(-1, gid))
+				return -1;
+		}
+	}
+#endif
 }
 
 static int cleanup(struct pam_modutil_privs *p)