Bladeren bron

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 9 jaren geleden
bovenliggende
commit
a3dd5d9217
3 gewijzigde bestanden met toevoegingen van 27 en 5 verwijderingen
  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
 3.0 = xx/xx/xxxx
 -----------------
 -----------------
+SECURITY
+- Fix for CVE-2014-2913
+- Added function to clean the environment before forking. (John Frickson)
+
 ENHANCEMENTS
 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.
 - 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
   There should be no errors or warnings. Let me know if any errors or
   warning appear (John Frickson)
   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
 - Added autoconf macros and additional files to better support multi-platform
   config and compile. The default will still set up to install to
   config and compile. The default will still set up to install to
   /usr/local/nagios but I added a new configure option:
   /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)
   to only send version 2 packets if the switch `-2` is used. (John Frickson)
 
 
 FIXES
 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)
 - 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)
 - Renamed configure.in to configure.ac and added check for sigaction (John Frickson)
 - Replaced all instances of signal() with sigaction() + blocking (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 */
 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_system_sighandler(int);				/* handles timeouts when executing commands via my_system() */
 void my_connection_sighandler(int);			/* handles timeouts of connection */
 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 write_pid_file(void);
 int remove_pid_file(void);
 int remove_pid_file(void);
 int check_privileges(void);
 int check_privileges(void);

+ 10 - 4
src/nrpe.c

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