diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index b93ff18..fe315a7 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #endif #if defined(_WIN32) || defined(_WIN64) @@ -134,23 +135,66 @@ int CMMDVMHost::run() if (m_daemon) { // Create new process pid_t pid = ::fork(); - if (pid == -1) - return -1; + if (pid == -1) { + ::LogWarning("Couldn't fork() , exiting"); + return -1; + } else if (pid != 0) exit(EXIT_SUCCESS); // Create new session and process group - if (::setsid() == -1) - return -1; + if (::setsid() == -1){ + ::LogWarning("Couldn't setsid(), exiting"); + return -1; + } // Set the working directory to the root directory - if (::chdir("/") == -1) - return -1; + if (::chdir("/") == -1){ + ::LogWarning("Couldn't cd /, exiting"); + return -1; + } ::close(STDIN_FILENO); ::close(STDOUT_FILENO); ::close(STDERR_FILENO); +#if !defined(HD44780) + //If we are currently root... + if (getuid() == 0) { + //get UID for mmdvm user + uid_t mmdvm_uid = getpwnam("mmdvm")->pw_uid; + if (mmdvm_uid == NULL) { + ::LogWarning("Could not get mmdvm UID, exiting"); + return -1; + } + //get GID for mmdvm user + gid_t mmdvm_gid = getpwnam("mmdvm")->pw_gid; + if (mmdvm_gid == NULL) { + ::LogWarning("Could not get mmdvm GID, exiting"); + return -1; + } + + //Set user and group ID's to mmdvm:mmdvm + if (setgid(mmdvm_gid) != 0) { + ::LogWarning("Could not set mmdvm GID, exiting"); + return -1; + } + if (setuid(mmdvm_uid) != 0) { + ::LogWarning("Could not set mmdvm UID, exiting"); + return -1; + } + + //Double check it worked (AKA Paranoia) + if (setuid(0) != -1){ + ::LogWarning("It's possible to regain root - something is wrong!, exiting"); + return -1; + } + + } } +#else + ::LogWarning("Dropping root permissions in daemon mode is disabled with HD44780 display"); + } +#endif #endif LogInfo(HEADER1); diff --git a/README.daemon b/README.daemon new file mode 100644 index 0000000..d68fb5f --- /dev/null +++ b/README.daemon @@ -0,0 +1,26 @@ +On Linux, to run MMDVMHost as a daemon, set "Daemon=1" in the ini file. + +When this is set, MMDVMHost will attempt to drop privileges to user "mmdvm" and +group "mmdvm". If this user and group do not exist on your system, an error +will occur and +MMDVMHost will not start. + +To add these users, please do the following from the Linux command line: + +groupadd mmdvm +useradd mmdvm -g mmdvm -s /sbin/nologin +usermod mmdvm -G dialout + +Note, without the last line, MMDVMHost will not be able to open the modem. + +Also note, when running as a daemon, STDIN, STDOUT and STDERR are closed, so +you must use a logfile to capture logging and the logfile entry in the ini file +must be given a full path as MMDVMHost calls "cd /" when daemonising. The same +applies to the DMRIds.dat file. + +Also, please note that the code to drop privileges is currently disabled when +MMDVMHost is compiled with the HD44780 display as it's currently not possible +to use this display as a non-root user. + + +Simon - G7RZU \ No newline at end of file