Parcourir la source

nrpe_user directive doesn't work as expected?

Fix for issue https://github.com/NagiosEnterprises/nrpe/issues/40

I had changed the call to setuid() to seteuid() so the PID file
could be deleted. Unfortunately, when a popen() is done, some shells
(like bash which is a common default shell) reverts to the original
uid. So I added a call go setuid() in my_system() after the fork().

Also updated Changelog and added a missing #ifdef HAVE_SSL
John C. Frickson il y a 9 ans
Parent
commit
a3dd5d9217
3 fichiers modifiés avec 27 ajouts et 5 suppressions
  1. 16 0
      Changelog
  2. 1 1
      include/nrpe.h
  3. 10 4
      src/nrpe.c

+ 16 - 0
Changelog

@@ -4,10 +4,25 @@ NRPE Changelog
 
 3.0 = xx/xx/xxxx
 -----------------
+SECURITY
+- Fix for CVE-2014-2913
+- Added function to clean the environment before forking. (John Frickson)
+
 ENHANCEMENTS
+- Added support for optional config file to check_nrpe. With the new SSL
+  parameters, the line was getting long. The config file is specified with
+  --config-file=<path> or -f <path> parameters. The config file must look
+  like command line options, but the options can be on separate lines. It
+  MUST NOT include --config-file (-f), --command (-c) or --args (-a). If any
+  options are in both the config file and on the command line, the command line
+  options are used.
+- make can now add users and groups using "make install-groups-users" (John Frickson)
+- Added "nrpe-uninstall" script to the same directory nrpe get installed to (John Frickson)
 - Updated code so configure && make will work on AIX, HP-UX, Solaris, OS X.
   There should be no errors or warnings. Let me know if any errors or
   warning appear (John Frickson)
+- Added command-line option to prevent forking, since some of the init
+  replacements (such as systemd, etc.) don't want daemons to fork (John Frickson)
 - Added autoconf macros and additional files to better support multi-platform
   config and compile. The default will still set up to install to
   /usr/local/nagios but I added a new configure option:
@@ -25,6 +40,7 @@ ENHANCEMENTS
   to only send version 2 packets if the switch `-2` is used. (John Frickson)
 
 FIXES
+- Fixed configure to check more places for SSL headers/libs. (John Frickson)
 - Added ifdefs for complete_SSL_shutdown to compile without SSL. (Matthew L. Daniel)
 - Renamed configure.in to configure.ac and added check for sigaction (John Frickson)
 - Replaced all instances of signal() with sigaction() + blocking (John Frickson)

+ 1 - 1
include/nrpe.h

@@ -57,7 +57,7 @@ void free_memory(void);
 int my_system(char*, int, int*, char**);	/* executes a command via popen(), but also protects against timeouts */
 void my_system_sighandler(int);				/* handles timeouts when executing commands via my_system() */
 void my_connection_sighandler(int);			/* handles timeouts of connection */
-int drop_privileges(char *,char *);
+int drop_privileges(char *,char *, int);
 int write_pid_file(void);
 int remove_pid_file(void);
 int check_privileges(void);

+ 10 - 4
src/nrpe.c

@@ -573,7 +573,7 @@ void set_stdio_sigs(void)
 		exit(STATE_CRITICAL);
 
 	clean_environ(keep_env_vars, nrpe_user);
-	drop_privileges(nrpe_user, nrpe_group);	/* drop privileges */
+	drop_privileges(nrpe_user, nrpe_group, 0);	/* drop privileges */
 	check_privileges();			/* make sure we're not root */
 }
 
@@ -1477,6 +1477,7 @@ void handle_connection(int sock)
 #endif
 
 	/* do SSL handshake */
+#ifdef HAVE_SSL
 	if (use_ssl == TRUE) {
     	if ((ssl = SSL_new(ctx)) == NULL) {
         	syslog(LOG_ERR, "Error: Could not create SSL connection structure.");
@@ -1491,6 +1492,7 @@ void handle_connection(int sock)
 		if (handle_conn_ssl(sock, ssl) != OK)
 			return;
 	}
+#endif
 
 #ifdef HAVE_SSL
 	rc = read_packet(sock, ssl, &receive_packet, &v3_receive_packet);
@@ -2022,6 +2024,7 @@ int my_system(char *command, int timeout, int *early_timeout, char **output)
 
 	/* execute the command in the child process */
 	if (pid == 0) {
+		drop_privileges(nrpe_user, nrpe_group, 1);	/* drop privileges */
 		close(fd[0]);			/* close pipe for reading */
 		setpgid(0, 0);			/* become process group leader */
 
@@ -2148,7 +2151,7 @@ void my_connection_sighandler(int sig)
 }
 
 /* drops privileges */
-int drop_privileges(char *user, char *group)
+int drop_privileges(char *user, char *group, int full_drop)
 {
 	uid_t     uid = -1;
 	gid_t     gid = -1;
@@ -2195,8 +2198,8 @@ int drop_privileges(char *user, char *group)
 			/* else we were passed the UID */
 			uid = (uid_t) atoi(user);
 
-		/* set effective user ID if other than current EUID */
 		if (uid != geteuid()) {
+		/* set effective user ID if other than current EUID */
 #ifdef HAVE_INITGROUPS
 			/* initialize supplementary groups */
 			if (initgroups(user, gid) == -1) {
@@ -2211,7 +2214,10 @@ int drop_privileges(char *user, char *group)
 			}
 #endif
 
-			if (SETEUID(uid) == -1)
+			if (full_drop) {
+				if (setuid(uid) == -1)
+					syslog(LOG_ERR, "Warning: Could not set UID=%d", (int)uid);
+			} else if (SETEUID(uid) == -1)
 				syslog(LOG_ERR, "Warning: Could not set effective UID=%d", (int)uid);
 		}
 	}