[prev in list] [next in list] [prev in thread] [next in thread] 

List:       trousers-tech
Subject:    [TrouSerS-tech] svrside.c.patch
From:       Wyllys Ingersoll <wyllys.ingersoll () sun ! com>
Date:       2008-12-09 14:13:58
Message-ID: 493E7D26.2050001 () sun ! com
[Download RAW message or body]

Attached is a patch for src/tcsd/svrside.c

Changes:
* added "daemon" function for Solaris
* added code to make tcsd privilege-aware on Solaris.  This allows
  it to run as root:sys but with reduced privileges as opposed to
  running as a separate user:group
* includes SO_REUSEADDR fix from another patch as well.

-Wyllys Ingersoll


["svrside.c.patch" (text/plain)]

*** src/tcsd/svrside.c.old	Fri Dec  5 07:32:55 2008
--- src/tcsd/svrside.c	Fri Dec  5 07:42:06 2008
***************
*** 23,28 ****
--- 23,32 ----
  #include <arpa/inet.h>
  #include <errno.h>
  #include <getopt.h>
+ #ifdef __sun__
+ #include <fcntl.h>
+ #include <priv.h>
+ #endif /* __sun__ */
  
  #include "trousers/tss.h"
  #include "trousers_types.h"
***************
*** 210,221 ****
  	fprintf(stderr, "\n");
  }
  
  int
  main(int argc, char **argv)
  {
  	struct sockaddr_in serv_addr, client_addr;
  	TSS_RESULT result;
! 	int sd, newsd, c, option_index = 0;
  	unsigned client_len;
  	char *hostname = NULL;
  	struct hostent *client_hostent = NULL;
--- 214,300 ----
  	fprintf(stderr, "\n");
  }
  
+ #ifdef __sun__
+ 
+ /*
+  * For Solaris, make the tcsd privilege aware and drop
+  * risky privileges if they are not needed.
+  */
+ static int
+ drop_privs()
+ {
+ 	priv_set_t *myprivs;
+ 	int rv;
+ 
+ 	/*
+ 	 * Drop unneeded privs such as fork/exec.
+ 	 *
+ 	 * Remove from 'basic' privs we know we don't want,
+ 	 * invert the result and remove the resulting set from P.
+ 	 * 
+ 	 */
+ 	if ((myprivs = priv_str_to_set("basic", ",", NULL)) == NULL) {
+ 		LogError("priv_str_to_set failed: %s", strerror(errno));
+ 		return (1);
+ 	} else {
+ 		(void) priv_delset(myprivs, PRIV_PROC_EXEC);
+ 		(void) priv_delset(myprivs, PRIV_PROC_FORK);
+ 		(void) priv_delset(myprivs, PRIV_FILE_LINK_ANY);
+ 		(void) priv_delset(myprivs, PRIV_PROC_INFO);
+ 		(void) priv_delset(myprivs, PRIV_PROC_SESSION);
+ 
+ 		priv_inverse(myprivs);
+ 
+ 		rv = setppriv(PRIV_OFF, PRIV_PERMITTED, myprivs);
+ 		if (rv)
+ 			return (rv);
+ 		(void) priv_freeset(myprivs);
+ 	}
+ 	return (0);
+ }
+ 
+ static int
+ daemon(int nochdir, int noclose) {
+ 	int rv, fd;
+ 
+ 	switch (fork()) {
+ 		case -1:
+ 			return (-1);
+ 		case 0:
+ 			break;
+ 		default:
+ 		exit (0);
+ 	}
+ 	/*
+ 	 * Run TCSD as root:sys on Solaris so it can
+ 	 * perform auditing if necessary, but drop privileges
+ 	 * for extra protection.
+ 	 */
+ 	rv = drop_privs();
+ 	if (rv)
+ 		return (rv);
+ 
+ 	if (setsid() == -1)
+ 		return (-1);
+ 	if (!nochdir)
+ 		(void) chdir("/");
+ 	if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
+ 		(void) dup2(fd, STDIN_FILENO);
+ 		(void) dup2(fd, STDOUT_FILENO);
+ 		(void) dup2(fd, STDERR_FILENO);
+ 		if (fd > 2)
+ 			(void)close (fd);
+ 	}
+ 	return (0);
+ }
+ #endif /* __sun__ */
+ 
  int
  main(int argc, char **argv)
  {
  	struct sockaddr_in serv_addr, client_addr;
  	TSS_RESULT result;
! 	int sd, newsd, c, rv, option_index = 0;
  	unsigned client_len;
  	char *hostname = NULL;
  	struct hostent *client_hostent = NULL;
***************
*** 225,231 ****
  		{0, 0, 0, 0}
  	};
  
- 
  	while ((c = getopt_long(argc, argv, "fh", long_options, &option_index)) != -1) {
  		switch (c) {
  			case 'f':
--- 305,310 ----
***************
*** 249,255 ****
--- 328,344 ----
  			tcsd_shutdown();
  			return -1;
  		}
+ #ifndef __sun__
  	}
+ #else
+ 	/* For Solaris, drop privileges in foreground mode */
+ 	} else {
+ 		
+ 		rv = drop_privs();
+ 		if (rv)
+ 			return (rv);
+ 	}
+ #endif /* __sun__ */
  
  	sd = socket(AF_INET, SOCK_STREAM, 0);
  	if (sd < 0) {
***************
*** 268,273 ****
--- 357,366 ----
  	else
  		serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  
+ 	c = 1;
+ 	if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &c, sizeof (c)) < 0)
+ 		perror("Error setting REUSEADDR option");
+ 
  	if (bind(sd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
  		LogError("Failed bind: %s", strerror(errno));
  		return -1;


------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you.  Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/

_______________________________________________
TrouSerS-tech mailing list
TrouSerS-tech@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/trousers-tech


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic