diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 `hdaemonize`
 =================
-[![Build Status](https://travis-ci.org/greydot/hdaemonize.svg?branch=master)](https://travis-ci.org/greydot/hdaemonize)
+[![Build Status](https://travis-ci.org/unprolix/hdaemonize.svg?branch=master)](https://travis-ci.org/unprolix/hdaemonize)
 
 `hdaemonize` is a simple library that hides some of the complexities
 of writing UNIX daemons in Haskell.
@@ -9,7 +9,7 @@
 -----------
 
 The latest version is available (BSD license) at
-[GitHub](https://github.com/greydot/hdaemonize).
+[GitHub](https://github.com/unprolix/hdaemonize).
 
 Using
 -------
@@ -60,14 +60,27 @@
     # mydaemon stop
     # mydaemon restart
 
-Finally, `mydaemon` drops privileges.  By default it changes the
-effective user and group ids to those of the `daemon` user, but it
-prefers to use those of `mydaemon`, if present.
+Finally, if configured to do so, `mydaemon` drops privileges by
+changing its effective user/group ID. (If no user/group ID are
+specified, it will continue execution as the original user and group.)
 
+Note that if you wish to parse your own commandline arguments, you can
+replace invocation of the `serviced` function with `serviced'`. This
+requires specification of an `Operation` which indicates whether the
+daemon should be started, stopped, restarted, or whether its status
+should be queried.
 
 Changelog
 ---------
 
+* 0.5.6
+    * Add `serviced'` function and `Operation` (`Start`, `Stop`, etc.) to allow invocation separated from commandline
+    * Only attempt to change effective user/group ID when explicitly specified.
+    * Do not attempt to set user or group to the daemon's name in the absence of a specified user or group.
+
+* 0.5.5
+    * Fix a bug where hdaemonize fails when user or group "daemon" is absent
+
 * 0.5.4
     * Update to use hsyslog == 5.
 
@@ -93,6 +106,8 @@
 
 Authors
 -------
+Jeremy Bornstein <jeremy@jeremy.org>
+
 Lana Black <lanablack@amok.cc>
 
 Anton Tayanovskyy <name.surname@gmail.com>.
diff --git a/System/Posix/Daemonize.hs b/System/Posix/Daemonize.hs
--- a/System/Posix/Daemonize.hs
+++ b/System/Posix/Daemonize.hs
@@ -4,7 +4,7 @@
   -- * Simple daemonization
   daemonize,
   -- * Building system services
-  serviced, CreateDaemon(..), simpleDaemon,
+  serviced, serviced', CreateDaemon(..), simpleDaemon, Operation(..),
   -- * Intradaemon utilities
   fatalError, exitCleanly,
   -- * Logging utilities
@@ -40,11 +40,13 @@
 import Data.Maybe (isNothing, fromMaybe, fromJust)
 import System.Environment
 import System.Exit
-import System.Posix
+import System.Posix hiding (Start, Stop)
 import System.Posix.Syslog (Priority(..), Facility(Daemon), Option, withSyslog)
 import qualified System.Posix.Syslog as Log
 import System.FilePath.Posix (joinPath)
 
+data Operation = Start | Stop | Restart | Status deriving (Eq, Show)
+
 syslog :: Priority -> ByteString -> IO ()
 syslog pri msg = unsafeUseAsCStringLen msg (Log.syslog (Just Daemon) pri)
 
@@ -121,11 +123,26 @@
 
 serviced :: CreateDaemon a -> IO ()
 serviced daemon = do
+        args <- getArgs
+
+        let mOperation :: Maybe Operation
+            mOperation = case args of
+              ("start" : _)   -> Just Start
+              ("stop" : _)    -> Just Stop
+              ("restart" : _) -> Just Restart
+              ("status" : _)  -> Just Status
+              _               -> Nothing
+
+        if isNothing mOperation
+          then getProgName >>= \pname -> putStrLn $ "usage: " ++ pname ++ " {start|stop|status|restart}"
+          else serviced' daemon $ fromJust mOperation
+
+serviced' :: CreateDaemon a -> Operation -> IO ()
+serviced' daemon operation = do
         systemName <- getProgName
         let daemon' = daemon { name = if isNothing (name daemon)
                                         then Just systemName else name daemon }
-        args <- getArgs
-        process daemon' args
+        process daemon' operation
     where
       program' daemon = withSyslog (fromJust (name daemon)) (syslogOptions daemon) Daemon $
                       do let log = syslog Notice
@@ -135,12 +152,12 @@
                          dropPrivileges daemon
                          forever $ program daemon privVal
 
-      process daemon ["start"] = pidExists daemon >>= f where
+      process daemon Start = pidExists daemon >>= f where
           f True  = do error "PID file exists. Process already running?"
                        exitImmediately (ExitFailure 1)
           f False = daemonize (program' daemon)
 
-      process daemon ["stop"]  =
+      process daemon Stop  =
           do pid <- pidRead daemon
              case pid of
                Nothing  -> pass
@@ -152,10 +169,10 @@
                    `finally`
                    removeLink (pidFile daemon)
 
-      process daemon ["restart"] = do process daemon ["stop"]
-                                      process daemon ["start"]
+      process daemon Restart = do process daemon Stop
+                                  process daemon Start
 
-      process daemon ["status"] = pidExists daemon >>= f where
+      process daemon Status = pidExists daemon >>= f where
         f True =
           do pid <- pidRead daemon
              case pid of
@@ -167,9 +184,6 @@
                          else putStrLn $ fromJust (name daemon) ++ " is not running, but pidfile is remaining."
         f False = putStrLn $ fromJust (name daemon) ++ " is not running."
 
-      process _      _ =
-        getProgName >>= \pname -> putStrLn $ "usage: " ++ pname ++ " {start|stop|status|restart}"
-
       -- Wait 'secs' seconds for the process to exit, checking
       -- for liveness once a second.  If still alive send sigKILL.
       wait :: Maybe Int -> CPid -> IO ()
@@ -298,30 +312,27 @@
         f (Left _)    = Nothing
         f (Right uid) = Just uid
 
+-- only drop privileges if a user is specified
 dropPrivileges :: CreateDaemon a -> IO ()
-dropPrivileges daemon =
-    do let targetUser = fromJust $ asum [ user daemon
-                                        , name daemon
-                                        , Just "daemon"
-                                        ]
-           targetGroup = fromJust $ asum [ group daemon
-                                         , name daemon
-                                         , Just "daemon"
-                                         ]
-       mud <- getUserID targetUser
-       mgd <- getGroupID targetGroup
-       u <- case mud of
-           Nothing -> do syslog Error "Privilege drop failure, no suitable user."
-                         exitImmediately (ExitFailure 1)
-                         undefined
-           Just ud -> pure ud
-       g <- case mgd of
-           Nothing -> do syslog Error "Privilege drop failure, no suitable group."
-                         exitImmediately (ExitFailure 1)
-                         undefined
-           Just gd -> pure gd
-       setGroupID g
-       setUserID u
+dropPrivileges daemon = do
+    case group daemon of
+      Nothing -> pure ()
+      Just targetGroup -> do
+        mud <- getGroupID targetGroup
+        case mud of
+          Nothing -> do syslog Error "Privilege drop failure, could not identify specified group."
+                        exitImmediately (ExitFailure 1)
+                        undefined
+          Just gd -> setGroupID gd
+    case user daemon of
+      Nothing -> pure ()
+      Just targetUser -> do
+        mud <- getUserID targetUser
+        case mud of
+          Nothing -> do syslog Error "Privilege drop failure, could not identify specified user."
+                        exitImmediately (ExitFailure 1)
+                        undefined
+          Just ud -> setUserID ud
 
 pidFile:: CreateDaemon a -> String
 pidFile daemon = joinPath [dir, fromJust (name daemon) ++ ".pid"]
diff --git a/hdaemonize.cabal b/hdaemonize.cabal
--- a/hdaemonize.cabal
+++ b/hdaemonize.cabal
@@ -1,21 +1,22 @@
 Name:		hdaemonize
-Version:	0.5.5
+Version:	0.5.6
 Cabal-Version:  >= 1.6
 License:	BSD3
 License-file:   LICENSE
-Author:         Anton Tayanovskyy, Fred Ross
-Maintainer:     Lana Black <lanablack at amok dot cc>
-Homepage:       http://github.com/greydot/hdaemonize
+Author:         Anton Tayanovskyy, Fred Ross, Lana Black
+Maintainer:     Jeremy Bornstein <jeremy@jeremy.org>
+Homepage:       http://github.com/unprolix/hdaemonize
 Category:	System
 Synopsis:       Library to handle the details of writing daemons for UNIX
-Description:	Provides two functions that help writing better UNIX daemons,
-		daemonize and serviced: daemonize does what a daemon should do
-		(forking and closing descriptors), while serviced does that and
-		more (syslog interface, PID file writing, start-stop-restart
-		command line handling, dropping privileges).
+Description:	Provides functions that help writing better UNIX daemons,
+                daemonize and serviced/serviced': daemonize does what
+                a daemon should do (forking and closing descriptors),
+                while serviced does that and more (syslog interface,
+                PID file writing, start-stop-restart command line
+                handling, dropping privileges).
 Build-Type:	Simple
 Extra-Source-Files:	README.md
-Tested-With: GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2
+Tested-With: GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.4, GHC == 8.6.5
 
 Library
   Build-Depends:    base >= 4 && < 5
@@ -33,4 +34,4 @@
 
 source-repository head
   type:     git
-  location: https://github.com/greydot/hdaemonize.git
+  location: https://github.com/unprolix/hdaemonize.git
