У меня есть программа на C ++, работающая во встроенной системе linux.
программа запускается пользователем myuser и использует uid для управления привилегиями.
ls -l /bin/myprog
-rwsr-sr-x 1 root root 757328 May 7 12:55 myprog
Я написал небольшой класс для обработки идентификаторов. Он считывает все идентификаторы при запуске программы и изменяет euid и egid во время выполнения в зависимости от необходимого повышения привилегий.
/*************************************************************
* HEADER FILE
*************************************************************/
#ifndef _PRIVILEGE_H
#define _PRIVILEGE_H
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
class CPrivilege
{
private:
uid_t _ruid;
uid_t _euid;
uid_t _suid;
gid_t _rgid;
gid_t _egid;
gid_t _sgid;
int _status;
int getPrivilege(uid_t&,uid_t&,uid_t&,gid_t&,gid_t&,gid_t&);
public :
CPrivilege();
int elevate();
int down();
int print();
int status();
};
#endif
/*************************************************************
* CPP FILE
*************************************************************/
#include "_privilege.h"
CPrivilege::CPrivilege()
{
_status = getPrivilege(_ruid,_euid,_suid,_rgid,_egid,_sgid);
}
int CPrivilege::status()
{
return _status;
}
int CPrivilege::getPrivilege(uid_t& ruid, uid_t& euid, uid_t& suid, gid_t& rgid, gid_t& egid, gid_t& sgid)
{
if (getresuid(&ruid, &euid, &suid) == -1) {
printf("getresuid error\n");
return EXIT_FAILURE;
}
if (getresgid(&rgid, &egid, &sgid) == -1) {
printf("getresgid error\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int CPrivilege::elevate()
{
/* Switch to target user. effective uid gets the saved uid. */
if (seteuid((uid_t)_suid) == -1) {
printf("seteuid error\n");
return (_status = EXIT_FAILURE);
}
/* Switch to target group. effective gid gets the saved gid. */
if (setegid((gid_t)_sgid) == -1) {
printf("setegid error\n");
return (_status = EXIT_FAILURE);
}
return (_status = EXIT_SUCCESS);
}
int CPrivilege::down()
{
/* Switch to target user. effective uid gets the real uid. */
if (seteuid((uid_t)_ruid) == -1) {
printf("seteuid error\n");
return (_status = EXIT_FAILURE);
}
/* Switch to target group. effective gid gets the real gid. */
if (setegid((gid_t)_rgid) == -1) {
printf("setegid error\n");
return (_status = EXIT_FAILURE);
}
return (_status = EXIT_SUCCESS);
}
int CPrivilege::print()
{
uid_t ruid;
uid_t euid;
uid_t suid;
gid_t rgid;
gid_t egid;
gid_t sgid;
printf("status = %d\n", _status);
getPrivilege(ruid,euid,suid,rgid,egid,sgid);
printf("ruid = %d, euid = %d, suid = %d\n", ruid, euid, suid);
printf("rgid = %d, egid = %d, sgid = %d\n", rgid, egid, sgid);
}
Кроме того, вот основная программа, которая открывает сценарий оболочки, а затем запускает его. 1010 *
Когда я запускаю свою программу в «root», запускается сценарий, и мои выходные данные выглядят следующим образом:
status = 0
ruid = 0, euid = 0, suid = 0
rgid = 0, egid = 0, sgid = 0
status = 0
ruid = 0, euid = 0, suid = 0
rgid = 0, egid = 0, sgid = 0
Root privilege
HELLO WORLD !
status = 0
ruid = 0, euid = 0, suid = 0
rgid = 0, egid = 0, sgid = 0
Когда я запускаю свою программу с помощью myuser, я могу открыть сценарий файл, даже если он находится в папке '/ root'. Но я не могу запустить скрипт и получаю ответ «Permission denied»:
status = 0
ruid = 1009, euid = 1009, suid = 0
rgid = 1013, egid = 1013, sgid = 0
status = 0
ruid = 1009, euid = 0, suid = 0
rgid = 1013, egid = 0, sgid = 0
Root privilege
sh: /root/test_script: Permission denied
status = 0
ruid = 1009, euid = 1009, suid = 0
rgid = 1013, egid = 1013, sgid = 0
Что мне делать, чтобы вызвать скрипт с привилегией root?