mirror of
https://git.freebsd.org/ports.git
synced 2025-05-22 11:48:35 -04:00
this and turn it on by default. Current gamin uses the current real uid to determine the location of the socket and during the security routines. It also forks off a copy of "gam_server" as the current real uid as well. This breaks gamin functionality with any application that uses effective an uid/gid for privilege separation, such as samba. Samba runs as root, but always sets the effective uid/gid to that of the connecting user. Since gamin is only aware of the real uid, it always creates a root-owned gamin socket that the effective user can't touch (gamin's own security checks refuse it). PR: ports/176203 Submitted by: Danny Warren <danny@dannywarren.com> Reviewed by: marcus@
95 lines
3 KiB
C
95 lines
3 KiB
C
--- libgamin/gam_fork.c.orig 2007-07-04 06:36:48.000000000 -0700
|
|
+++ libgamin/gam_fork.c 2013-02-16 20:37:31.298176973 -0800
|
|
@@ -42,6 +42,78 @@
|
|
return NULL;
|
|
}
|
|
|
|
+#ifdef RUN_AS_EUID
|
|
+/**
|
|
+ * gamin_drop_privileges
|
|
+ *
|
|
+ * Attempt to drop privileges to another user and group before forking
|
|
+ * a copy of the gam server
|
|
+ *
|
|
+ * Return 0 in case of success or -1 in case of detected error.
|
|
+ */
|
|
+int
|
|
+gamin_drop_privileges(int to_uid, int to_gid)
|
|
+{
|
|
+ GAM_DEBUG(DEBUG_INFO, "Dropping privileges to %d:%d before forking server\n", to_uid, to_gid);
|
|
+
|
|
+ /* Get the current real user and group */
|
|
+ int from_uid = getuid();
|
|
+ int from_gid = getgid();
|
|
+
|
|
+ /* Make sure we were able to get the user and group values */
|
|
+ if ( from_uid == -1 || to_uid == -1 || from_gid == -1 || to_gid == -1 ) {
|
|
+ gam_error(DEBUG_INFO, "failed to get user or group info, unable to drop privileges\n");
|
|
+ return(-1);
|
|
+ }
|
|
+
|
|
+ /* Refuse to run setuid if it would escalate privileges */
|
|
+ if ( from_uid != 0 && to_uid == 0 )
|
|
+ {
|
|
+ gam_error(DEBUG_INFO, "refusing to escalate user privileges from=%d to=%d\n", from_uid, to_uid);
|
|
+ return(-1);
|
|
+ }
|
|
+
|
|
+ /* Refuse to run setgid if it would escalate privileges */
|
|
+ if ( from_gid != 0 && to_gid == 0 )
|
|
+ {
|
|
+ gam_error(DEBUG_INFO, "refusing to escalate group privileges from=%d to=%d\n", from_gid, to_gid);
|
|
+ return(-1);
|
|
+ }
|
|
+
|
|
+ /* Run setuid to drop privileges to the effective user */
|
|
+ if ( from_uid != to_uid ) {
|
|
+ GAM_DEBUG(DEBUG_INFO, "Attempting setuid from=%d to=%d\n", from_uid, to_uid);
|
|
+
|
|
+ /* run setuid and check for errors */
|
|
+ if (setuid(to_uid) == -1) {
|
|
+ gam_error(DEBUG_INFO, "failed to run setuid from=%d to=%d\n", from_uid, to_uid);
|
|
+ return(-1);
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ GAM_DEBUG(DEBUG_INFO, "Already running as effective user, skipping setuid\n");
|
|
+ }
|
|
+
|
|
+ /* Run setgid to drop privileges to the effective group */
|
|
+ if ( from_gid != to_gid ) {
|
|
+ GAM_DEBUG(DEBUG_INFO, "Attempting setgid from=%d to=%d\n", from_gid, to_gid);
|
|
+
|
|
+ /* run setuid and check for errors */
|
|
+ if (setgid(to_gid) == -1) {
|
|
+ gam_error(DEBUG_INFO, "failed to run setgid from=%d to=%d\n", from_gid, to_gid);
|
|
+ return(-1);
|
|
+ }
|
|
+ }
|
|
+ else {
|
|
+ GAM_DEBUG(DEBUG_INFO, "Already running as effective group, skipping setgid\n");
|
|
+ }
|
|
+
|
|
+ GAM_DEBUG(DEBUG_INFO, "Succeeded in dropping privileges from %d:%d to %d:%d\n", from_uid, from_gid, to_uid, to_gid);
|
|
+
|
|
+ return(0);
|
|
+}
|
|
+#endif
|
|
+
|
|
/**
|
|
* gamin_fork_server:
|
|
* @fam_client_id: the client ID string to use
|
|
@@ -71,6 +143,13 @@
|
|
long open_max;
|
|
long i;
|
|
|
|
+#ifdef RUN_AS_EUID
|
|
+ /* Drop privileges to the current effective uid/gid and return on failure */
|
|
+ if(gamin_drop_privileges( geteuid(), getegid() ) == -1) {
|
|
+ return(-1);
|
|
+ }
|
|
+#endif
|
|
+
|
|
/* don't hold open fd opened from the client of the library */
|
|
open_max = sysconf (_SC_OPEN_MAX);
|
|
for (i = 0; i < open_max; i++)
|