diff --git a/ChangeLog b/ChangeLog index 4fc16c1f..04936671 100644 --- a/ChangeLog +++ b/ChangeLog @@ -20507,3 +20507,6 @@ 'Edit Service dialog in rdadmin(1). * Renamed the 'Note Cart String' controls to 'Insert Marker String' in the 'Edit Service dialog in rdadmin(1). +2020-10-27 Fred Gleason + * Refactored the 'Run Script' ['RN'] RML to invoke scripts via + the system shell. diff --git a/ripcd/local_macros.cpp b/ripcd/local_macros.cpp index a1ce2b4d..63c49d97 100644 --- a/ripcd/local_macros.cpp +++ b/ripcd/local_macros.cpp @@ -19,6 +19,8 @@ // #include +#include +#include #include #include #include @@ -680,7 +682,8 @@ void MainObject::RunLocalMacros(RDMacro *rml_in) for(int i=0;iargQuantity();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()) { rml->acknowledge(true); sendRml(rml); @@ -1063,60 +1066,54 @@ RDMacro MainObject::ForwardConvert(const RDMacro &rml) const } -void MainObject::RunCommand(const QString &user,const QString &group, - const QString &cmd) const +void MainObject::RunCommand(uid_t uid,gid_t gid,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 *) - // references from Qt directly! + // references from Qt directly, as they will fall + // out of scope! // - // - // Build the command - // - QStringList f0=cmd.split(" ",QString::SkipEmptyParts); - 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 rargs; - for(int i=0;isyslog(LOG_WARNING,"unable to set effective GID=%d [%s]",uid, + strerror(errno)); + return; + } + if(setuid(uid)!=0) { + rda->syslog(LOG_WARNING,"unable to set effective UID=%d [%s]",uid, + strerror(errno)); + return; + } + if(setuid(uid)!=0) { + rda->syslog(LOG_WARNING,"unable to set real UID=%d [%s]",uid, + strerror(errno)); + return; + } + } + if((pwd=getpwuid(getuid()))!=NULL) { + username=QString::fromUtf8(pwd->pw_name); + } + if((grp=getgrgid(getgid()))!=NULL) { + 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); } } - diff --git a/ripcd/ripcd.h b/ripcd/ripcd.h index a79cd1db..aad8dc01 100644 --- a/ripcd/ripcd.h +++ b/ripcd/ripcd.h @@ -105,8 +105,7 @@ 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; + void RunCommand(uid_t uid,gid_t gid,const QString &cmd) const; QSqlDatabase *ripcd_db; QString ripcd_host; bool debug;