QProcess: run app via sudo
-
Hello!
I should execute several command which require privileged access from my app which run as non-privileged.
For this I was add command to/etc/sudoerc
and allow run it without password, command work if I run it at shell~ $ sudo ping -c 3 ya.ru PING ya.ru (87.250.250.242): 56 data bytes 64 bytes from 87.250.250.242: seq=0 ttl=249 time=9.118 ms 64 bytes from 87.250.250.242: seq=1 ttl=249 time=8.910 ms 64 bytes from 87.250.250.242: seq=2 ttl=249 time=8.949 ms --- ya.ru ping statistics --- 3 packets transmitted, 3 packets received, 0% packet loss round-trip min/avg/max = 8.910/8.992/9.118 ms
Now I add
QProcess
to my appQProcess pingProcess; pingProcess.start("/usr/bin/sudo",{"/bin/ping -c 5 ya.ru"});
Unfortunately this is not work, after run app I see
Password:
at console output, at app finish console output contain follow lines............... QProcess: Destroyed while process ("/usr/bin/sudo") is still running. error ping "sudo: unable to mkdir /run: Read-only file system\nsudo: a password is required\n" ................
and sudo log contain line
command not allowed
, look like what sudo can't found or can't read/etc/sudoerc
.
How should I correct useQProcess
for run externals app viasudo
?
Thank you. -
@debian said in QProcess: run app via sudo:
QProcess pingProcess; pingProcess.start("/usr/bin/sudo",{"/bin/ping -c 5 ya.ru"});
This is the wrong way to do, each parameter should be an entry in the QStringList.
This should work:QProcess pingProcess; pingProcess.start("/usr/bin/sudo", QStringList() << "/bin/ping" << "-c" << "5" << "ya.ru")
-
@debian said in QProcess: run app via sudo:
Can you provide more details?
More than what is documentation?
https://doc.qt.io/qt-5/qprocess.html#details -
@debian said in QProcess: run app via sudo:
Can you provide more details?
One more think to note, as
QProcess
instance is on stack, you should useQProcess::execute()
to wait until process is done:QProcess::execute("/usr/bin/sudo", QStringList() << "/bin/ping" << "-c" << "5" << "ya.ru")
or do it yourself with
waitForFinished()
, so you could add a timeout:QProcess pingProcess; pingProcess.start("/usr/bin/sudo", QStringList() << "/bin/ping" << "-c" << "5" << "ya.ru") if(!pingProcess.waitForStarted(1000)) qDebug() << "Could NOT start sudo!!"; else if(!pingProcess.waitForFinished(20000)) qDebug() << "Ping is not ending!!!"; else qDebug() << "Done.";
-
$ /usr/sbin/getcap /bin/ping /bin/ping cap_net_raw=ep
This work because
/bin/ping
have capabilites
https://man7.org/linux/man-pages/man7/capabilities.7.htmlCAP_NET_RAW
- Use RAW and PACKET sockets;
- bind to any address for transparent proxying.