2019-02-19 Fred Gleason <fredg@paravelsystems.com>

* Added 'RnRmlOwner=' and 'RnRmlGroup=' directives to rd.conf(5).
	* Refactored the implementation of the 'Run Shell Command' ['RN']
	RML to use runuser(1).
This commit is contained in:
Fred Gleason 2019-02-19 12:47:18 -05:00
parent 26c9ff87c0
commit 489db27fc9
10 changed files with 126 additions and 29 deletions

View File

@ -18480,3 +18480,7 @@
* Fixed a bug in the 'RDWaveFile' class that could prevent
reading of an 'rdxl' tag in an ID3 tag generated by a pre-v3.x
version of Rivendell.
2019-02-19 Fred Gleason <fredg@paravelsystems.com>
* Added 'RnRmlOwner=' and 'RnRmlGroup=' directives to rd.conf(5).
* Refactored the implementation of the 'Run Shell Command' ['RN']
RML to use runuser(1).

View File

@ -16,6 +16,11 @@ AudioGroup=rivendell
PypadOwner=pypad
PypadGroup=pypad
; These entries are used to define the system user and group that commands
; executed by the 'Run Shell Command' ['RN'] RML will run under.
RnRmlOwner=rivendell
RnRmlGroup=rivendell
; This password is used by the various Rivendell modules to log into
; Rivendell system services [caed(8), ripcd(8), rdcatchd(8)].
Password=letmein

View File

@ -252,6 +252,14 @@ AC_CHECK_HEADER(soundtouch/SoundTouch.h,[],[AC_MSG_ERROR([*** SoundTouch not fou
#
AM_PATH_PYTHON([3])
#
# Check for runuser(1)
#
AC_PATH_PROG(RUNUSER_PATH,runuser)
if test -z $RUNUSER_PATH ; then
AC_MSG_ERROR([*** runuser(1) not found ***])
fi
#
# Check for FLAC
#

View File

@ -1389,6 +1389,26 @@
<para>
Run the shell command <replaceable>cmd</replaceable>.
</para>
<note>
<para>
The command is actually executed as:
</para>
<para>
<code>
runuser -u <replaceable>user</replaceable>
-g <replaceable>group</replaceable> <replaceable>cmd</replaceable>
</code>
</para>
<para>
where <replaceable>user</replaceable> and
<replaceable>group</replaceable> are the values specified by the
&quot;RnRmlOwner=&quot; and &quot;RnRmlGroup=&quot; directives in
the &quot;[Identity]&quot; section of
<command>rd.conf</command><manvolnum>5</manvolnum>. See the
<command>runuser</command><manvolnum>1</manvolnum> man page for
details concerning handling of the process enironment.
</para>
</note>
</sect2>
<sect2 xml:id="sect.rml.select_widget__pw_">

View File

@ -222,10 +222,12 @@
/*
* Default System Identities
*/
#define RD_DEFAULT_AUDIO_OWNER "user"
#define RD_DEFAULT_AUDIO_GROUP "users"
#define RD_DEFAULT_AUDIO_OWNER "rivendell"
#define RD_DEFAULT_AUDIO_GROUP "rivendell"
#define RD_DEFAULT_PYPAD_OWNER "pypad"
#define RD_DEFAULT_PYPAD_GROUP "pypad"
#define RD_DEFAULT_RN_RML_OWNER "rivendell"
#define RD_DEFAULT_RN_RML_GROUP "rivendell"
#define RD_DEFAULT_LABEL "Default Configuration"
/*

View File

@ -392,6 +392,18 @@ QString RDConfig::pypadGroup() const
}
QString RDConfig::rnRmlOwner() const
{
return conf_rn_rml_owner;
}
QString RDConfig::rnRmlGroup() const
{
return conf_rn_rml_group;
}
QString RDConfig::ripcdLogname() const
{
return conf_ripcd_logname;
@ -470,6 +482,18 @@ gid_t RDConfig::pypadGid() const
}
uid_t RDConfig::rnRmlUid() const
{
return conf_rn_rml_uid;
}
gid_t RDConfig::rnRmlGid() const
{
return conf_rn_rml_gid;
}
QString RDConfig::caeLogfile() const
{
return conf_cae_logfile;
@ -565,6 +589,10 @@ bool RDConfig::load()
profile->stringValue("Identity","PypadOwner",RD_DEFAULT_PYPAD_OWNER);
conf_pypad_group=
profile->stringValue("Identity","PypadGroup",RD_DEFAULT_PYPAD_GROUP);
conf_rn_rml_owner=
profile->stringValue("Identity","RnRmlOwner",RD_DEFAULT_RN_RML_OWNER);
conf_rn_rml_group=
profile->stringValue("Identity","RnRmlGroup",RD_DEFAULT_RN_RML_GROUP);
conf_label=profile->stringValue("Identity","Label",RD_DEFAULT_LABEL);
conf_audio_store_mount_source=
@ -662,6 +690,16 @@ bool RDConfig::load()
RD_DEFAULT_PYPAD_GROUP)))!=NULL) {
conf_pypad_gid=groups->gr_gid;
}
if((user=getpwnam(profile->stringValue("Identity","RnRmlOwner",
RD_DEFAULT_RN_RML_OWNER)))!=NULL) {
conf_rn_rml_uid=user->pw_uid;
}
if((groups=getgrnam(profile->stringValue("Identity","RnRmlGroup",
RD_DEFAULT_RN_RML_GROUP)))!=NULL) {
conf_rn_rml_gid=groups->gr_gid;
}
conf_cae_logfile=profile->stringValue("Caed","Logfile","");
conf_enable_mixer_logging=profile->boolValue("Caed","EnableMixerLogging");
conf_use_realtime=profile->boolValue("Tuning","UseRealtime",false);
@ -743,6 +781,8 @@ void RDConfig::clear()
conf_audio_group="";
conf_pypad_owner="";
conf_pypad_group="";
conf_rn_rml_owner="";
conf_rn_rml_group="";
conf_audio_root=RD_AUDIO_ROOT;
conf_audio_extension=RD_AUDIO_EXTENSION;
conf_label=RD_DEFAULT_LABEL;
@ -764,6 +804,8 @@ void RDConfig::clear()
conf_gid=65535;
conf_pypad_uid=65535;
conf_pypad_gid=65535;
conf_rn_rml_uid=65535;
conf_rn_rml_gid=65535;
conf_cae_logfile="";
conf_enable_mixer_logging=false;
conf_use_realtime=false;

View File

@ -93,6 +93,8 @@ class RDConfig
QString audioGroup() const;
QString pypadOwner() const;
QString pypadGroup() const;
QString rnRmlOwner() const;
QString rnRmlGroup() const;
QString audioRoot() const;
QString audioExtension() const;
QString audioFileName (QString cutname);
@ -117,6 +119,8 @@ class RDConfig
gid_t gid() const;
uid_t pypadUid() const;
gid_t pypadGid() const;
uid_t rnRmlUid() const;
gid_t rnRmlGid() const;
bool useRealtime();
int realtimePriority();
int transcodingDelay() const;
@ -166,6 +170,8 @@ class RDConfig
QString conf_audio_group;
QString conf_pypad_owner;
QString conf_pypad_group;
QString conf_rn_rml_owner;
QString conf_rn_rml_group;
QString conf_audio_root;
QString conf_audio_extension;
QString conf_label;
@ -186,6 +192,8 @@ class RDConfig
gid_t conf_gid;
uid_t conf_pypad_uid;
gid_t conf_pypad_gid;
uid_t conf_rn_rml_uid;
gid_t conf_rn_rml_gid;
QString conf_cae_logfile;
bool conf_enable_mixer_logging;
bool conf_use_realtime;

View File

@ -50,5 +50,10 @@ extern "C" {
#define RD_PYPAD_PYTHON_PATH "@PYTHON@"
#define RD_PYPAD_SCRIPT_DIR "@libdir@/rivendell/pypad"
/*
* runuser(1)
*/
#define RD_RUNUSER "@RUNUSER_PATH@"
#endif // RDPATHS_H

View File

@ -18,6 +18,7 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
@ -27,6 +28,7 @@
#include <rdconf.h>
#include <rdescape_string.h>
#include <rdmatrix.h>
#include <rdpaths.h>
#include <rdtty.h>
#include "ripcd.h"
@ -147,6 +149,7 @@ void MainObject::LoadLocalMacros()
QString sql;
RDSqlQuery *q;
unsigned tty_port;
QString cmd;
for(int i=0;i<MAX_MATRICES;i++) {
ripcd_switcher_tty[i][0]=-1;
@ -560,34 +563,10 @@ void MainObject::RunLocalMacros(RDMacro *rml_in)
}
return;
}
if(fork()==0) {
QString cmd=rml->arg(0);
for(int i=1;i<=rml->argQuantity();i++) {
cmd+=" "+rml->arg(i);
}
if(getuid()==0) {
if(setgid(rda->config()->gid())<0) {
LogLine(RDConfig::LogWarning,QString().
sprintf("unable to set group id %d for RN",
rda->config()->gid()));
if(rml->echoRequested()) {
rml->acknowledge(false);
sendRml(rml);
}
}
if(setuid(rda->config()->uid())<0) {
LogLine(RDConfig::LogWarning,QString().
sprintf("unable to set user id %d for RN",
rda->config()->uid()));
if(rml->echoRequested()) {
rml->acknowledge(false);
sendRml(rml);
}
}
}
system((const char *)cmd);
exit(0);
for(int i=0;i<rml->argQuantity();i++) {
cmd+=rml->arg(i)+" ";
}
RunCommand(rda->config()->rnRmlOwner(),rda->config()->rnRmlGroup(),cmd.trimmed());
if(rml->echoRequested()) {
rml->acknowledge(true);
sendRml(rml);
@ -966,3 +945,25 @@ RDMacro MainObject::ForwardConvert(const RDMacro &rml) const
return ret;
}
void MainObject::RunCommand(const QString &user,const QString &group,
const QString &cmd) const
{
QStringList f0=cmd.split(" ",QString::SkipEmptyParts);
const char *args[f0.size()+6];
args[0]=RD_RUNUSER;
args[1]="-u";
args[2]=user.toUtf8();
args[3]="-g";
args[4]=group.toUtf8();
for(int i=0;i<f0.size();i++) {
args[5+i]=f0.at(i).toUtf8();
}
args[5+f0.size()]=(char *)NULL;
if(vfork()==0) {
execv(RD_RUNUSER,(char * const *)args);
exit(0);
}
}

View File

@ -102,6 +102,8 @@ class MainObject : public QObject
void SendGpoCart(int ch,int matrix);
RDMacro ForwardConvert(const RDMacro &rml) const;
bool LoadSwitchDriver(int matrix_num);
void RunCommand(const QString &user,const QString &group,
const QString &cmd) const;
QSqlDatabase *ripcd_db;
QString ripcd_host;
bool debug;