Browse Source

- new config variables:
sock_mode = <permissions> (e.g. sock_mode=0600: default value = 0660)
ser unix sockets and fifo will be created with this permissions
(old name fifo_mode is still supported, but deprecated)
sock_user = username|"uid"
sock_group = groupname|"gid"
change the owner and/or group of the ser unix sockets or fifo
Short example config snippet:
sock_mode=0600 # ser socket/fifo mode
sock_user="www-data" # ser socket/fifo owner
sock_group=nogroup
user=nobody # ser user (ser will suid to it)
- typo fixed in socket_info (thanks to Jan)

Andrei Pelinescu-Onciul 21 years ago
parent
commit
71fd3ebd95
10 changed files with 187 additions and 57 deletions
  1. 11 0
      NEWS
  2. 13 3
      TODO
  3. 9 3
      cfg.lex
  4. 16 7
      cfg.y
  5. 10 6
      daemonize.c
  6. 16 6
      fifo_server.c
  7. 5 0
      globals.h
  8. 77 21
      main.c
  9. 1 1
      socket_info.c
  10. 29 10
      unixsock_server.c

+ 11 - 0
NEWS

@@ -31,6 +31,17 @@ core:
                               ==, !=, ~= for strings
                               ==, !=, >, <, >=, <= for integers
  - new config variables:
+   sock_mode = <permissions> (e.g. sock_mode=0600:  default value = 0660)
+       ser unix sockets and fifo will be created with this permissions
+       (old name fifo_mode is still supported, but deprecated)
+   sock_user = username|"uid"
+   sock_group = groupname|"gid"
+      change the owner and/or group of the ser unix sockets or fifo
+      Short example config snippet:
+           sock_mode=0600        # ser socket/fifo mode
+           sock_user="www-data"  # ser socket/fifo owner
+           sock_group=nogroup  
+           user=nobody       # ser user (ser will suid to it)
    disable_core_dump= yes|no 
        by default core dump limits are set to unlimited or a high enough
        value, set this config variable o yes to disable core dump-ing

+ 13 - 3
TODO

@@ -1,15 +1,25 @@
 $Id$
 
 ( - todo, x - done)
-
+- [core] parse_uri support for new uri params
+- [core] on sig_child, kill the processes if they don't exit in a 
+  reasonable time
 - [doc] document force_rport()
 - [fifo] fix fgets error handling (it does not set errno always,
    , right now kills all ser if interrupted by a signal on ?solaris?)
 - [mem] make shm_realloc be fragmentation friendly: call shm_compact_frags
    for the small frags?, don't produce smaller frags -- be wastefull?
-- [mem] qm_compact_frags (compacts frags if possible)
+- [mem] qm_compact_frags (compacts frags if possible), keep a 
+        fragment count/bucket and if too much mem. is blocked in one bucket
+        de-frag.
+- [mem] investigate: don't produce frag if frag size < request
+      (should reduce the unrequested fragments number)
+- [mem] investigate: keep an used/unused flag per fragment, on free
+      check if neighboring frags were not used and if so defragment
 - [timer] multiple timers? at least ticks should no be affected by the amount
    of work done in the timer handlers
+- [tcp] ser intiated tcp connections use INADDR_ANY (they should be bound first
+  to some ip/port ?function of the dest?)
 - [tcp] need to confirm fd receipt after send_fd, before closing it (this might
  happen in tcp_send new conn.) (see FreeBSD send BUGS for more info)
 x [tcp] make send_all, send  non-blocking ready ?
@@ -36,7 +46,7 @@ x update all package specs from stable
    should have it, but it would be slower on systems emulating it, like
    older linuxes)
 - [tcp] switch to epoll if HAVE_EPOLL defined (linux 2.6.*)
-- [tcp] switch to SIGIO if no epoll (linux only, better than poll?)
+- [tcp] switch to SIGIO if no epoll (linux only, better than poll)
 x tcp_main_loop: BUG cases should "conitnue;"
 x change len_gt into and expr (e.g msg:len).
 x sipit: uri == myself doesn't match tls port = 5061 

+ 9 - 3
cfg.lex

@@ -45,7 +45,9 @@
  *  2003-10-28  added tcp_accept_aliases (andrei)
  *  2003-11-29  added {tcp_send, tcp_connect, tls_*}_timeout (andrei)
  *  2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
- * 2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
+ *  2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
+ *  2004-04-28  added sock_mode (replaces fifo_mode), sock_user &
+ *               sock_group  (andrei)
  */
 
 
@@ -173,7 +175,9 @@ MEMLOG		"memlog"|"mem_log"
 SIP_WARNING sip_warning
 FIFO fifo
 FIFO_DIR  fifo_dir
-FIFO_MODE fifo_mode
+SOCK_MODE "fifo_mode"|"sock_mode"|"file_mode"
+SOCK_USER "fifo_user"|"sock_user"
+SOCK_GROUP "fifo_group"|"sock_group"
 FIFO_DB_URL fifo_db_url
 UNIX_SOCK unix_sock
 UNIX_SOCK_CHILDREN unix_sock_children
@@ -371,7 +375,9 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{FIFO}	{ count(); yylval.strval=yytext; return FIFO; }
 <INITIAL>{FIFO_DIR}	{ count(); yylval.strval=yytext; return FIFO_DIR; }
 <INITIAL>{FIFO_DB_URL}	{ count(); yylval.strval=yytext; return FIFO_DB_URL; }
-<INITIAL>{FIFO_MODE}	{ count(); yylval.strval=yytext; return FIFO_MODE; }
+<INITIAL>{SOCK_MODE}	{ count(); yylval.strval=yytext; return SOCK_MODE; }
+<INITIAL>{SOCK_USER}	{ count(); yylval.strval=yytext; return SOCK_USER; }
+<INITIAL>{SOCK_GROUP}	{ count(); yylval.strval=yytext; return SOCK_GROUP; }
 <INITIAL>{UNIX_SOCK} { count(); yylval.strval=yytext; return UNIX_SOCK; }
 <INITIAL>{UNIX_SOCK_CHILDREN} { count(); yylval.strval=yytext; return UNIX_SOCK_CHILDREN; }
 <INITIAL>{UNIX_TX_TIMEOUT} { count(); yylval.strval=yytext; return UNIX_TX_TIMEOUT; }

+ 16 - 7
cfg.y

@@ -52,6 +52,7 @@
  * 2003-11-20  added {tcp_connect, tcp_send, tls_*}_timeout (andrei)
  * 2004-02-24  added LOAD_AVP_T and AVP_TO_URI_T (bogdan)
  * 2004-03-30  added DISABLE_CORE and OPEN_FD_LIMIT (andrei)
+ * 2004-04-29  added SOCK_MODE, SOCK_USER & SOCK_GROUP (andrei)
  */
 
 
@@ -199,7 +200,9 @@ static struct id_list* mk_listen_id(char*, int, int);
 %token SIP_WARNING
 %token FIFO
 %token FIFO_DIR
-%token FIFO_MODE
+%token SOCK_MODE
+%token SOCK_USER
+%token SOCK_GROUP
 %token FIFO_DB_URL
 %token UNIX_SOCK
 %token UNIX_SOCK_CHILDREN
@@ -411,14 +414,20 @@ assign_stm:	DEBUG EQUAL NUMBER { debug=$3; }
 		| FIFO EQUAL error { yyerror("string value expected"); }
 		| FIFO_DIR EQUAL STRING { fifo_dir=$3; }
 		| FIFO_DIR EQUAL error { yyerror("string value expected"); }
-		| FIFO_MODE EQUAL NUMBER { fifo_mode=$3; }
-		| FIFO_MODE EQUAL error { yyerror("int value expected"); }
+		| SOCK_MODE EQUAL NUMBER { sock_mode=$3; }
+		| SOCK_MODE EQUAL error { yyerror("int value expected"); }
+		| SOCK_USER EQUAL STRING { sock_user=$3; }
+		| SOCK_USER EQUAL ID     { sock_user=$3; }
+		| SOCK_USER EQUAL error { yyerror("string value expected"); }
+		| SOCK_GROUP EQUAL STRING { sock_group=$3; }
+		| SOCK_GROUP EQUAL ID     { sock_group=$3; }
+		| SOCK_GROUP EQUAL error { yyerror("string value expected"); }
 		| FIFO_DB_URL EQUAL STRING { fifo_db_url=$3; }
 		| FIFO_DB_URL EQUAL error  { yyerror("string value expected"); }
-                | UNIX_SOCK EQUAL STRING { unixsock_name=$3; }
-                | UNIX_SOCK EQUAL error { yyerror("string value expected"); }
-                | UNIX_SOCK_CHILDREN EQUAL NUMBER { unixsock_children=$3; }
-                | UNIX_SOCK_CHILDREN EQUAL error { yyerror("int value expected\n"); }
+		| UNIX_SOCK EQUAL STRING { unixsock_name=$3; }
+		| UNIX_SOCK EQUAL error { yyerror("string value expected"); }
+		| UNIX_SOCK_CHILDREN EQUAL NUMBER { unixsock_children=$3; }
+		| UNIX_SOCK_CHILDREN EQUAL error { yyerror("int value expected\n"); }
 		| UNIX_TX_TIMEOUT EQUAL NUMBER { unixsock_tx_timeout=$3; }
 		| UNIX_TX_TIMEOUT EQUAL error { yyerror("int value expected\n"); }
 		| AVP_DB_URL EQUAL STRING { avp_db_url=$3; }

+ 10 - 6
daemonize.c

@@ -166,14 +166,18 @@ error:
 
 int do_suid()
 {
-	if (gid&&(setgid(gid)<0)){
-		LOG(L_CRIT, "cannot change gid to %d: %s\n", gid, strerror(errno));
-		goto error;
+	if (gid){
+		if(setgid(gid)<0){
+			LOG(L_CRIT, "cannot change gid to %d: %s\n", gid, strerror(errno));
+			goto error;
+		}
 	}
 	
-	if(uid&&(setuid(uid)<0)){
-		LOG(L_CRIT, "cannot change uid to %d: %s\n", uid, strerror(errno));
-		goto error;
+	if(uid){
+		if(setuid(uid)<0){
+			LOG(L_CRIT, "cannot change uid to %d: %s\n", uid, strerror(errno));
+			goto error;
+		}
 	}
 	return 0;
 error:

+ 16 - 6
fifo_server.c

@@ -61,6 +61,7 @@
  *  2003-10-13  addef fifo_dir for reply fifos (andrei)
  *  2003-10-30  DB interface exported via FIFO (bogdan)
  *  2004-03-09  open_fifo_server split into init_ and start_ (andrei)
+ *  2004-04-29  added chown(sock_user, sock_group)  (andrei)
  */
 
 
@@ -94,7 +95,6 @@
 /* FIFO server vars */
 char *fifo=0; /* FIFO name */
 char* fifo_dir=DEFAULT_FIFO_DIR; /* dir where reply fifos are allowed */
-int fifo_mode=S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ;
 char *fifo_db_url = 0;
 pid_t fifo_pid;
 /* file descriptors */
@@ -565,20 +565,30 @@ int init_fifo_server()
 			strerror(errno));
 	}
 		/* create FIFO ... */
-		if ((mkfifo(fifo, fifo_mode)<0)) {
+		if ((mkfifo(fifo, sock_mode)<0)) {
 			LOG(L_ERR, "ERROR: open_fifo_server; can't create FIFO: "
 					"%s (mode=%d)\n",
-					strerror(errno), fifo_mode);
+					strerror(errno), sock_mode);
 			return -1;
 		} 
 		DBG("DEBUG: FIFO created @ %s\n", fifo );
-		if ((chmod(fifo, fifo_mode)<0)) {
+		if ((chmod(fifo, sock_mode)<0)) {
 			LOG(L_ERR, "ERROR: open_fifo_server; can't chmod FIFO: "
 					"%s (mode=%d)\n",
-					strerror(errno), fifo_mode);
+					strerror(errno), sock_mode);
 			return -1;
 		}
-	DBG("DEBUG: fifo %s opened, mode=%d\n", fifo, fifo_mode );
+		if ((sock_uid!=-1) || (sock_gid!=-1)){
+			if (chown(fifo, sock_uid, sock_gid)<0){
+			LOG(L_ERR, "ERROR: open_fifo_server: failed to change the"
+					" owner/group for %s  to %d.%d; %s[%d]\n",
+					fifo, sock_uid, sock_gid, strerror(errno), errno);
+			return -1;
+		}
+	}
+
+		
+	DBG("DEBUG: fifo %s opened, mode=%d\n", fifo, sock_mode );
 	time(&up_since);
 	t=ctime(&up_since);
 	if (strlen(t)+1>=MAX_CTIME_LEN) {

+ 5 - 0
globals.h

@@ -93,6 +93,11 @@ extern int sip_warning;
 extern int server_signature;
 extern char* user;
 extern char* group;
+extern char* sock_user;
+extern char* sock_group;
+extern int sock_uid;
+extern int sock_gid;
+extern int sock_mode;
 extern char* chroot_dir;
 extern char* working_dir;
 

+ 77 - 21
main.c

@@ -48,6 +48,8 @@
  *  2004-02-06  added support for user pref. - init_avp_child() (bogdan)
  *  2004-03-30  core dump is enabled by default
  *              added support for increasing the open files limit    (andrei)
+ *  2004-04-28  sock_{user,group,uid,gid,mode} added
+ *              user2uid() & user2gid() added  (andrei)
  *
  */
 
@@ -329,6 +331,12 @@ char* user=0;
 char* group=0;
 int uid = 0;
 int gid = 0;
+char* sock_user=0;
+char* sock_group=0;
+int sock_uid= -1;
+int sock_gid= -1;
+int sock_mode= S_IRUSR| S_IWUSR| S_IRGRP| S_IWGRP; /* rw-rw---- */
+
 /* more config stuff */
 int disable_core_dump=0; /* by default enabled */
 int open_files_limit=-1; /* don't touch it by default */
@@ -644,6 +652,57 @@ error:
 
 
 
+/* converts a username into uid:gid,
+ * returns -1 on error & 0 on success */
+static int user2uid(int* uid, int* gid, char* user)
+{
+	char* tmp;
+	struct passwd *pw_entry;
+	
+	if (user){
+		*uid=strtol(user, &tmp, 10);
+		if ((tmp==0) ||(*tmp)){
+			/* maybe it's a string */
+			pw_entry=getpwnam(user);
+			if (pw_entry==0){
+				goto error;
+			}
+			*uid=pw_entry->pw_uid;
+			if (gid) *gid=pw_entry->pw_gid;
+		}
+		return 0;
+	}
+error:
+	return -1;
+}
+
+
+
+/* converts a group name into a gid
+ * returns -1 on error, 0 on success */
+static int group2gid(int* gid, char* group)
+{
+	char* tmp;
+	struct group  *gr_entry;
+	
+	if (group){
+		*gid=strtol(group, &tmp, 10);
+		if ((tmp==0) ||(*tmp)){
+			/* maybe it's a string */
+			gr_entry=getgrnam(group);
+			if (gr_entry==0){
+				goto error;
+			}
+			*gid=gr_entry->gr_gid;
+		}
+		return 0;
+	}
+error:
+	return -1;
+}
+
+
+
 /* main loop */
 int main_loop()
 {
@@ -1042,8 +1101,6 @@ int main(int argc, char** argv)
 	char *tmp;
 	char *options;
 	int ret;
-	struct passwd *pw_entry;
-	struct group  *gr_entry;
 	unsigned int seed;
 	int rfd;
 
@@ -1299,31 +1356,30 @@ try_again:
 	
 	/* get uid/gid */
 	if (user){
-		uid=strtol(user, &tmp, 10);
-		if ((tmp==0) ||(*tmp)){
-			/* maybe it's a string */
-			pw_entry=getpwnam(user);
-			if (pw_entry==0){
-				fprintf(stderr, "bad user name/uid number: -u %s\n", user);
-				goto error;
-			}
-			uid=pw_entry->pw_uid;
-			gid=pw_entry->pw_gid;
+		if (user2uid(&uid, &gid, user)<0){
+			fprintf(stderr, "bad user name/uid number: -u %s\n", user);
+			goto error;
 		}
 	}
 	if (group){
-		gid=strtol(group, &tmp, 10);
-		if ((tmp==0) ||(*tmp)){
-			/* maybe it's a string */
-			gr_entry=getgrnam(group);
-			if (gr_entry==0){
+		if (group2gid(&gid, group)<0){
 				fprintf(stderr, "bad group name/gid number: -u %s\n", group);
-				goto error;
-			}
-			gid=gr_entry->gr_gid;
+			goto error;
+		}
+	}
+	/* fix sock/fifo uid/gid */
+	if (sock_user){
+		if (user2uid(&sock_uid, 0, sock_user)<0){
+			fprintf(stderr, "bad socket user name/uid number %s\n", user);
+			goto error;
+		}
+	}
+	if (sock_group){
+		if (group2gid(&sock_gid, sock_group)<0){
+			fprintf(stderr, "bad group name/gid number: -u %s\n", group);
+			goto error;
 		}
 	}
-	
 	if (fix_all_socket_lists()!=0){
 		fprintf(stderr,  "failed to initialize liste addresses\n");
 		goto error;

+ 1 - 1
socket_info.c

@@ -492,7 +492,7 @@ static int fix_socket_list(struct socket_info **list)
 						 l->name.s, l->address_str.s);
 #endif
 				/* add the name to the alias list*/
-				if ((!(l->flags&& SI_IS_IP)) && (
+				if ((!(l->flags& SI_IS_IP)) && (
 						(l->name.len!=si->name.len)||
 						(strncmp(l->name.s, si->name.s, si->name.len)!=0))
 					)

+ 29 - 10
unixsock_server.c

@@ -29,6 +29,7 @@
 /* History:
  *              created by janakj
  *  2004-03-03  added tcp init code (andrei)
+ *  2004-04-29  added chmod(sock_perm) & chown(sock_user,sock_group)  (andrei)
  */
 
 #include <unistd.h>
@@ -311,7 +312,7 @@ int init_unixsock_socket(void)
 		DBG("init_unixsock_socket: Unix domain socket server disabled\n");
 		return 1;
 	} else if (len > 107) {
-		LOG(L_ERR, "init_unixsock_socket: Socket name too long\n");
+		LOG(L_ERR, "ERROR: init_unixsock_socket: Socket name too long\n");
 		return -1;
 	}
 
@@ -320,7 +321,7 @@ int init_unixsock_socket(void)
 
 	if (unlink(unixsock_name) == -1) {
 		if (errno != ENOENT) {
-			LOG(L_ERR, "init_unixsock_socket: Error while unlinking "
+			LOG(L_ERR, "ERROR: init_unixsock_socket: Error while unlinking "
 			    "old socket (%s): %s\n", unixsock_name, strerror(errno));
 			return -1;
 		}
@@ -328,8 +329,8 @@ int init_unixsock_socket(void)
 
 	rx_sock = socket(PF_LOCAL, SOCK_DGRAM, 0);
 	if (rx_sock == -1) {
-		LOG(L_ERR, "init_unixsock_socket: Cannot create RX socket: %s\n", 
-		    strerror(errno));
+		LOG(L_ERR, "ERROR: init_unixsock_socket: Cannot create RX "
+				"socket: %s\n", strerror(errno));
 		return -1;
 	}
 
@@ -338,28 +339,46 @@ int init_unixsock_socket(void)
 	memcpy(addr.sun_path, unixsock_name, len);
 
 	if (bind(rx_sock, (struct sockaddr*)&addr, SUN_LEN(&addr)) == -1) {
-		LOG(L_ERR, "init_unixsock_socket: bind: %s\n", strerror(errno));
+		LOG(L_ERR, "ERROR: init_unixsock_socket: bind: %s\n", strerror(errno));
 		goto err_rx;
 	}
+	/* try to change the permissions */
+	if (sock_mode){ /* sock_mode==0 doesn't make sense, nobody can read/write*/
+		if (chmod(unixsock_name, sock_mode)<0){
+			LOG(L_ERR, "ERROR: init_unixsock_socket: failed to change the"
+					" permissions for %s to %04o: %s[%d]\n",
+					unixsock_name, sock_mode, strerror(errno), errno);
+			goto err_rx;
+		}
+	}
+	/* try to change the ownership */
+	if ((sock_uid!=-1) || (sock_gid!=-1)){
+		if (chown(unixsock_name, sock_uid, sock_gid)<0){
+			LOG(L_ERR, "ERROR: init_unixsock_socket: failed to change the"
+					" owner/group for %s  to %d.%d; %s[%d]\n",
+					unixsock_name, sock_uid, sock_gid, strerror(errno), errno);
+			goto err_rx;
+		}
+	}
 
 	tx_sock = socket(PF_LOCAL, SOCK_DGRAM, 0);
 	if (tx_sock == -1) {
-		LOG(L_ERR, "init_unixsock_socket: Cannot create TX socket: %s\n",
-		    strerror(errno));
+		LOG(L_ERR, "ERROR: init_unixsock_socket: Cannot create TX socket:"
+				" %s\n", strerror(errno));
 		goto err_rx;
 	}
 
 	     /* Turn non-blocking mode on */
 	flags = fcntl(tx_sock, F_GETFL);
 	if (flags == -1){
-		LOG(L_ERR, "init_unixsock_socket: fcntl failed: %s\n",
+		LOG(L_ERR, "ERROR: init_unixsock_socket: fcntl failed: %s\n",
 		    strerror(errno));
 		goto err_both;
 	}
 		
 	if (fcntl(tx_sock, F_SETFL, flags | O_NONBLOCK) == -1) {
-		LOG(L_ERR, "init_unixsock_socket: fcntl: set non-blocking failed:"
-		    " %s\n", strerror(errno));
+		LOG(L_ERR, "ERROR: init_unixsock_socket: fcntl: "
+				"set non-blocking failed: %s\n", strerror(errno));
 		goto err_both;
 	}