diff --git a/fanout.c b/fanout.c
index a49974ef96ebc8e3c38824d8c47758960dd745f2..bc064d11d6569ec9e7429eb5936509b18c366718 100644
--- a/fanout.c
+++ b/fanout.c
@@ -8,7 +8,10 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <ctype.h>
 #include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <netinet/in.h>
@@ -39,6 +42,7 @@ struct channel
     u_int subscription_count;
 };
 
+
 struct subscription
 {
     struct client *client;
@@ -47,6 +51,8 @@ struct subscription
     struct subscription *previous;
 };
 
+
+int is_numeric (char *str);
 int strcpos (const char *haystack, const char c);
 char *substr (const char *s, int start, int stop);
 void str_swap_free (char **target, char *source);
@@ -138,6 +144,14 @@ int main (int argc, char *argv[])
     server_start_time = (long)time (NULL);
     char buffer[1025];
 
+    struct passwd *pwd;
+    struct group *grp;
+
+    char *user;
+    char *group;
+    uid_t user_id = -1;
+    gid_t group_id = -1;
+
     struct epoll_event ev, events[max_events];
 
     struct client *client_i = NULL;
@@ -154,6 +168,7 @@ int main (int argc, char *argv[])
         {"debug-level", 1, 0, 0},
         {"help", 0, 0, 0},
         {"client-limit", 1, 0, 0},
+        {"run-as", 1, 0, 0},
         {NULL, 0, NULL, 0}
     };
 
@@ -191,6 +206,8 @@ int main (int argc, char *argv[])
                         printf("Recognized options are:\n");
                         printf("  --port=PORT           port to run the service\
  on\n");
+                        printf("  --run-as=USER[:GROUP] drop permissions to def\
+ined levels\n");
                         printf("                        1986 (default)\n");
                         printf("  --daemon              fork to background\n");
                         printf("  --client-limit=LIMIT  max connections\n");
@@ -222,6 +239,37 @@ fs.file-max=100000\n");
                         }
                         break;
 
+                    //run-as
+                    case 7:
+                        fanout_debug (3, "requsting permissions %s\n", optarg);
+                        user = strtok (optarg, ":");
+                        group = strtok (NULL, ":");
+                        if (user != NULL) {
+                            if (is_numeric (user)) {
+                                user_id = (uid_t) atoi (user);
+                            } else {
+                                if ((pwd = getpwnam (user)) == NULL) {
+                                    fanout_error ("failed getting user_id");
+                                } else {
+                                    user_id = pwd->pw_uid;
+                                }
+                            }
+                        }
+
+                        if (group != NULL) {
+                            if (is_numeric (group)) {
+                                group_id = (gid_t) atoi (group);
+                            } else {
+                                if ((grp = getgrnam (group)) == NULL) {
+                                    fanout_error ("failed getting group_id");
+                                } else {
+                                    group_id = grp->gr_gid;
+                                }
+                            }
+                        }
+
+                        break;
+
                 }
                 break;
             default:
@@ -237,7 +285,6 @@ fs.file-max=100000\n");
         exit (EXIT_FAILURE);
     }
 
-
     if ( ! portno > 0) {
         fanout_debug (0, "ERROR invalid port\n");
         exit (EXIT_FAILURE);
@@ -246,13 +293,14 @@ fs.file-max=100000\n");
     srvsock = socket (AF_INET, SOCK_STREAM, 0);
     if (srvsock < 0)
         fanout_error ("ERROR opening socket");
-    
+
     bzero((char *) &serv_addr, sizeof (serv_addr));
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons (portno);
-    
+
     setsockopt (srvsock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof (yes));
+
     if (bind (srvsock, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
     {
         fanout_error ("ERROR on binding");
@@ -319,6 +367,9 @@ fs.file-max=100000\n");
     // epollfd, srvsock, extra for reporting busy
     base_fds = 3;
 
+    //additional padding for safety
+    base_fds += 10;
+
     //stdin/out/err
     if ( ! daemonize) {
         base_fds += 3;
@@ -353,8 +404,28 @@ fs.file-max=100000\n");
     } else {
         client_limit = calculated_client_limit;
     }
-    
-    fanout_debug (1, "rlimit set at: Soft=%d Hard=%d\n", s_rlimit.rlim_cur, s_rlimit.rlim_max);
+
+
+    //set group first so as to not lose root permissions for user set below
+    if ((int) group_id > -1) {
+        fanout_debug (3, "attempting to set group %s\n",
+                       getgrgid (group_id)->gr_name);
+        if (setgid (group_id) == -1) {
+            fanout_error ("failed setting group");
+        }
+    }
+
+    //set user
+    if ((int) user_id > -1) {
+        fanout_debug (3, "attempting to set user %s\n", 
+                       getpwuid (user_id)->pw_name);
+        if (setuid (user_id) == -1) {
+            fanout_error ("failed setting user");
+        }
+    }
+
+    fanout_debug (1, "rlimit set at: Soft=%d Hard=%d\n", s_rlimit.rlim_cur,
+                   s_rlimit.rlim_max);
     fanout_debug (2, "base fds: %d\n", base_fds);
     fanout_debug (2, "max client connections: %d\n", client_limit);
 
@@ -475,6 +546,16 @@ resetting counter\n");
 }
 
 
+int is_numeric (char *str)
+{
+    while (*str) {
+        if (!isdigit (*str))
+            return 0;
+        str++;
+    }
+    return 1;
+}
+
 
 int strcpos (const char *haystack, const char c)
 {
@@ -920,7 +1001,8 @@ resetting counter\n");
         }
         subscription_i = subscription_i->next;
     }
-    fanout_debug (2, "announced messge %s", s);
+    fanout_debug (2, "announced messge to %d client(s) %s",
+                   get_channel (channel)->subscription_count, s);
     if (announcements_count == ULLONG_MAX) {
         fanout_debug (1, "wow, you've announced alot..resetting counter\n");
         announcements_count = 0;