2020-10-27 Fred Gleason <fredg@paravelsystems.com>

* Refactored the 'Run Script' ['RN'] RML to invoke scripts via
	the system shell.

Signed-off-by: Fred Gleason <fredg@paravelsystems.com>
This commit is contained in:
Fred Gleason 2020-10-27 14:04:38 -04:00
parent 8ef2debbd2
commit 6b976459ec
3 changed files with 51 additions and 52 deletions

View File

@ -20507,3 +20507,6 @@
'Edit Service dialog in rdadmin(1). 'Edit Service dialog in rdadmin(1).
* Renamed the 'Note Cart String' controls to 'Insert Marker String' * Renamed the 'Note Cart String' controls to 'Insert Marker String'
in the 'Edit Service dialog in rdadmin(1). in the 'Edit Service dialog in rdadmin(1).
2020-10-27 Fred Gleason <fredg@paravelsystems.com>
* Refactored the 'Run Script' ['RN'] RML to invoke scripts via
the system shell.

View File

@ -19,6 +19,8 @@
// //
#include <errno.h> #include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdlib.h> #include <stdlib.h>
#include <syslog.h> #include <syslog.h>
#include <sys/types.h> #include <sys/types.h>
@ -680,7 +682,8 @@ void MainObject::RunLocalMacros(RDMacro *rml_in)
for(int i=0;i<rml->argQuantity();i++) { for(int i=0;i<rml->argQuantity();i++) {
cmd+=rml->arg(i)+" "; cmd+=rml->arg(i)+" ";
} }
RunCommand(rda->config()->rnRmlOwner(),rda->config()->rnRmlGroup(),cmd.trimmed()); RunCommand(rda->config()->rnRmlUid(),rda->config()->rnRmlGid(),
cmd.trimmed());
if(rml->echoRequested()) { if(rml->echoRequested()) {
rml->acknowledge(true); rml->acknowledge(true);
sendRml(rml); sendRml(rml);
@ -1063,60 +1066,54 @@ RDMacro MainObject::ForwardConvert(const RDMacro &rml) const
} }
void MainObject::RunCommand(const QString &user,const QString &group, void MainObject::RunCommand(uid_t uid,gid_t gid,const QString &cmd) const
const QString &cmd) const
{ {
// //
// Maintainer's Note: Everything passed to execv() must be either in // Maintainer's Note: Everything passed to execl() *must* be either in
// local or heap storage. *Don't* pass (const char *) // local or heap storage. *Don't* pass (const char *)
// references from Qt directly! // references from Qt directly, as they will fall
// out of scope!
// //
// struct passwd *pwd=NULL;
// Build the command struct group *grp=NULL;
// QString username="[unknown]";
QStringList f0=cmd.split(" ",QString::SkipEmptyParts); QString groupname="[unknown]";
char userarg[256];
strncpy(userarg,user.toUtf8().constData(),255);
char grouparg[256];
strncpy(grouparg,group.toUtf8().constData(),255);
const char *args[f0.size()+6];
args[0]=RD_RUNUSER;
args[1]="-u";
args[2]=userarg;
args[3]="-g";
args[4]=grouparg;
QList<char *> rargs;
for(int i=0;i<f0.size();i++) {
rargs.push_back((char *)malloc(f0.at(i).toUtf8().length()+1));
strcpy(rargs.back(),f0.at(i).toUtf8());
args[5+i]=rargs.back();
}
args[5+f0.size()]=(char *)NULL;
// if(fork()==0) {
// Run it if(getuid()==0) {
// if(setgid(gid)!=0) {
rda->syslog(LOG_WARNING,"unable to set effective GID=%d [%s]",uid,
//Can only change user/group if we are running as root strerror(errno));
if(getuid()==0) { return;
if(vfork()==0) { }
execv(RD_RUNUSER,(char * const *)args); if(setuid(uid)!=0) {
exit(0); // Just in case... rda->syslog(LOG_WARNING,"unable to set effective UID=%d [%s]",uid,
} strerror(errno));
} return;
else { }
if(fork()==0) { if(setuid(uid)!=0) {
system((const char *)cmd); rda->syslog(LOG_WARNING,"unable to set real UID=%d [%s]",uid,
exit(0); strerror(errno));
} return;
} }
}
// if((pwd=getpwuid(getuid()))!=NULL) {
// Free the heap storage username=QString::fromUtf8(pwd->pw_name);
// }
for(int i=0;i<rargs.size();i++) { if((grp=getgrgid(getgid()))!=NULL) {
free(rargs.at(i)); groupname=QString::fromUtf8(grp->gr_name);
}
rda->syslog(LOG_DEBUG,"executing script \"%s\" as %s:%s",
cmd.toUtf8().constData(),username.toUtf8().constData(),
groupname.toUtf8().constData());
int cmdlen=cmd.toUtf8().size()+4;
char cmdstr[cmdlen];
memset(cmdstr,0,cmdlen); // These function take bytes, not characters!
memcpy(cmdstr,cmd.toUtf8().constData(),cmd.toUtf8().size());
execl("/bin/sh","/bin/sh","-c",cmdstr,(char *)NULL);
rda->syslog(LOG_WARNING,"execution of \"%s\" failed [%s]",
cmd.toUtf8().constData(),strerror(errno));
exit(0);
} }
} }

View File

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