From 25d993b8b37ffa95a6bdfa13e2e75ce1cce7cd15 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 4 May 2016 20:06:15 +0100 Subject: [PATCH 1/7] added setuid and setgid code, tidied up logging --- MMDVMHost.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 20bebfd..948ad13 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #endif #if defined(_WIN32) || defined(_WIN64) @@ -134,22 +135,61 @@ int CMMDVMHost::run() if (m_daemon) { // Create new process pid_t pid = ::fork(); - if (pid == -1) - return -1; + if (pid == -1) { + ::LogMessage("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){ + ::LogMessage("Couldn't setsid(), exiting"); + return -1; + } // Set the working directory to the root directory - if (::chdir("/") == -1) - return -1; + if (::chdir("/") == -1){ + ::LogMessage("Couldn't cd /, exiting"); + return -1; + } ::close(STDIN_FILENO); ::close(STDOUT_FILENO); ::close(STDERR_FILENO); + + //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) { + ::LogMessage("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) { + ::LogMessage("Could not get mmdvm GID, exiting"); + return -1; + } + + //Set user and group ID's to mmdvm:mmdvm + if (setgid(mmdvm_gid) != 0) { + ::LogMessage("Could not set mmdvm GID, exiting"); + return -1; + } + if (setuid(mmdvm_uid) != 0) { + ::LogMessage("Could not set mmdvm UID, exiting"); + return -1; + } + + //Double check it worked (AKA Paranoia) + if (setuid(0) != -1){ + ::LogMessage("It's possible to regain root - something is wrong!, exiting"); + return -1; + } + + } } #endif From 14a5698132872e9ba5a5c8dd26882b74521b4d38 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 4 May 2016 21:11:37 +0100 Subject: [PATCH 2/7] Added readme file for Daemon --- README.daemon | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 README.daemon diff --git a/README.daemon b/README.daemon new file mode 100644 index 0000000..794c4dc --- /dev/null +++ b/README.daemon @@ -0,0 +1,21 @@ +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 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. + + +Simon - G7RZU \ No newline at end of file From 3617199399e14916bb473b5b759da3a90b1c8807 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 5 May 2016 09:47:54 +0100 Subject: [PATCH 3/7] Added check to see if HD44780 is enabled and disable setuid() if it is --- MMDVMHost.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 03db52a..4a15ec9 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -157,7 +157,7 @@ int CMMDVMHost::run() ::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 @@ -191,6 +191,10 @@ int CMMDVMHost::run() } } +#else + ::LogMessage("Warning: dropping root permissions in daemon mode is disabled with HD44780 display"); + } +#endif #endif LogInfo(HEADER1); From 436922481b874806bc3846b4038794c7d1b5ebe0 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 5 May 2016 09:48:34 +0100 Subject: [PATCH 4/7] Added explaination of why setuid() is disabled when using HD44780 --- README.daemon | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/README.daemon b/README.daemon index 794c4dc..e4c3509 100644 --- a/README.daemon +++ b/README.daemon @@ -1,7 +1,8 @@ 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 on your system, an error will occur 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: @@ -12,10 +13,13 @@ 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. +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. + +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 From a2ec5763f9e1348b8d93b5ee09b7dd0d0d46f0e1 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 5 May 2016 10:52:58 +0100 Subject: [PATCH 5/7] Added reference to full path for DMRIds.dat --- README.daemon | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.daemon b/README.daemon index e4c3509..d68fb5f 100644 --- a/README.daemon +++ b/README.daemon @@ -15,11 +15,12 @@ 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. +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. +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 From 8195ee9f34578f0cd55833744225df74bd613fef Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 5 May 2016 10:53:19 +0100 Subject: [PATCH 6/7] Changed LogMessage() to LogWarning when we can't setuid() in daemon mode --- MMDVMHost.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 4a15ec9..4a4dbcb 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -192,7 +192,7 @@ int CMMDVMHost::run() } } #else - ::LogMessage("Warning: dropping root permissions in daemon mode is disabled with HD44780 display"); + ::LogWarning("Dropping root permissions in daemon mode is disabled with HD44780 display"); } #endif #endif From 2d366a624e92d0766ab44c17c0ae1c0b2fc8e15c Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 5 May 2016 11:11:44 +0100 Subject: [PATCH 7/7] Changed all daemon logs to LogWarning() for consistency. --- MMDVMHost.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 4a4dbcb..fe315a7 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -136,7 +136,7 @@ int CMMDVMHost::run() // Create new process pid_t pid = ::fork(); if (pid == -1) { - ::LogMessage("Couldn't fork() , exiting"); + ::LogWarning("Couldn't fork() , exiting"); return -1; } else if (pid != 0) @@ -144,13 +144,13 @@ int CMMDVMHost::run() // Create new session and process group if (::setsid() == -1){ - ::LogMessage("Couldn't setsid(), exiting"); + ::LogWarning("Couldn't setsid(), exiting"); return -1; } // Set the working directory to the root directory if (::chdir("/") == -1){ - ::LogMessage("Couldn't cd /, exiting"); + ::LogWarning("Couldn't cd /, exiting"); return -1; } @@ -163,29 +163,29 @@ int CMMDVMHost::run() //get UID for mmdvm user uid_t mmdvm_uid = getpwnam("mmdvm")->pw_uid; if (mmdvm_uid == NULL) { - ::LogMessage("Could not get mmdvm UID, exiting"); + ::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) { - ::LogMessage("Could not get mmdvm GID, exiting"); + ::LogWarning("Could not get mmdvm GID, exiting"); return -1; } //Set user and group ID's to mmdvm:mmdvm if (setgid(mmdvm_gid) != 0) { - ::LogMessage("Could not set mmdvm GID, exiting"); + ::LogWarning("Could not set mmdvm GID, exiting"); return -1; } if (setuid(mmdvm_uid) != 0) { - ::LogMessage("Could not set mmdvm UID, exiting"); + ::LogWarning("Could not set mmdvm UID, exiting"); return -1; } //Double check it worked (AKA Paranoia) if (setuid(0) != -1){ - ::LogMessage("It's possible to regain root - something is wrong!, exiting"); + ::LogWarning("It's possible to regain root - something is wrong!, exiting"); return -1; }