3

Я пытаюсь заставить программу на С всегда запускаться от имени пользователя root, независимо от того, кто его вызывает. По сути, я хочу, чтобы он вызывал "mkdir /test" в качестве примера. Поэтому я создал программу на C следующим образом:

#include <stdio.h>

int main()
{
system("mkdir /test");
printf("bye...\n");
return 0;
}

Теперь я только что скомпилировал: gcc test.c -o test

И теперь я попытался установить разрешения:

chmod +s test

Однако, запустив его как обычный пользователь, я получаю ошибку «Отказано в доступе». Таким образом, он выполняет файл, но не с правами root. Я также попытался установить разрешения как:

chmod a+s test
chmod o+s test

Но у меня всегда одна и та же проблема.

Кто-нибудь может мне помочь с этим? Кстати, файл test.c создается пользователем root, а также компилируется как root.

bash-3.2# ls -al | grep test 
-rwxr-xr-x   1 root   staff       8796  5 Ago 19:07 test
bash-3.2# chmod +s test
bash-3.2# ls -al | grep test 
-rwsr-sr-x   1 root   staff       8796  5 Ago 19:07 test
bash-3.2# whoami
root
bash-3.2#

Заранее спасибо! Cheerz!

2 ответа2

6

Здесь нужно знать две вещи:

  • Липкий бит, который можно использовать для файлов и каталогов, но не будет делать то, что вы хотите. От sticky(8): бит закрепления не влияет на исполняемые файлы.

  • Флаг setuid, позволяющий запускать программу с разрешениями ее владельцев. То, что кажется ограничением в OS X и, по-видимому, не задокументировано, это то, что бит setuid на исполняемом файле имеет эффект, только если исполняемый файл находится в каталоге, который принадлежит root (и не открыт для записи другими), и т.д., вплоть до корневого каталога. В противном случае он игнорируется по соображениям безопасности.

В любом случае, вы можете изменить файл sudoers таким образом, чтобы он не требовал ввода пароля для одной команды. Помните, что вы должны использовать visudo для редактирования. Если вам не удастся получить неверный синтаксис при редактировании файла, вы больше не сможете запускать sudo .

sudo visudo

Затем нажмите I и внизу вставьте:

username    ALL= NOPASSWD: /path/to/command

Здесь вам, очевидно, нужно изменить username для пользователя, который должен запускать команду без необходимости ввода пароля. Также измените путь к вашему исполняемому файлу. Обратите внимание, что на этом этапе исполняемый файл может принадлежать пользователю root и иметь права на выполнение только для пользователя root .

Нажмите Esc, затем напишите :wq , затем Enter.

Теперь username может запускать команду с помощью команды sudo /path/to/command и для этого не нужно вводить пароль.

0

Я работаю под Linux, но поскольку OSX - это просто BSD, я предполагаю, что он следует тем же (общим) правилам, что и любой другой Unix.

Внутри вашей программы вам нужно вызвать setuid (UID), который возвращает 0 в случае успеха, чтобы заставить его работать как этот UID, и вы хотите запускать как root. UID рута, вероятно, равен 0, но если вы особенно параноик, используйте getpwnam (const char * szUserName), чтобы получить UID.

Итак, как то так:

#include <stdio.h> // needed for printf

#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>

void change_to_user (const char *szUserName)
{
  struct passwd *pw;

  pw = getpwnam(szUserName);
  if (pw != NULL)
  {
    uid_t uid = pw->pw_uid; // we now have the UID of the username

    printf ("UID of user %s is %d\n", szUserName, (int)uid);
    if (setuid (uid) != 0)
    {
      perror ("setuid");
    }
    else
    {
      // this will fail if you try to change to root without the SUID
      // bit set.  This executive needs to be owned by root (probably
      // group owned by root as well), and set the SUID bit with:
      //   suid a+s {executable}
      printf ("UID is now %d\n", (int)uid);
    }
  }
  else
  {
    perror ("getpwnam");
  }
}


int main (int argc, char **argv)
{
  int iIter;

  if (argc == 1)
  {
    printf ("Give me a user name\n");
    return 1;
  }

  for (iIter = 1 ; iIter < argc ; iIter++)
  {
    change_to_user (argv[iIter]);
  }
  return 0;
}

Вы можете установить ЛЮБОЕ имя пользователя, так что, возможно, вы запускаете скрипт cgi и хотите использовать его под своей учетной записью вместо «www-data» или чего-либо еще - вы можете использовать его там. Я делаю это, поэтому могу подробно ответить на ваш вопрос.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .