web-dev-qa-db-ja.com

プログラムをOSXで常にrootとして実行する

誰が呼んでも、Cプログラムを常に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!

4
yaroze

ここで知っておくべきことが2つあります。

  • スティッキービット 、これはファイルやディレクトリで使用できますが、必要なことは実行されません。 From sticky(8)スティッキービットは実行可能ファイルに影響を与えません

  • setuid フラグ。これにより、所有者の権限でプログラムを実行できるようになります。 OS Xの制限と思われ、明らかに文書化されていないのは、実行可能ファイルのsetuidビットは、実行可能ファイルがルートによって所有されている(そして他の人が書き込むために開いていない)ディレクトリにある場合にのみ効果があるということです。など、ルートディレクトリまで。それ以外の場合は、セキュリティ上の理由から無視されます。

とにかく、1つのコマンドにパスワードを必要としないようにsudoersファイルを変更できます。 visudoを使用して編集する必要があることを忘れないでください。ファイルの編集中に構文を間違えると、Sudoを実行できなくなります。

Sudo visudo

次に、を押します I、および下部の挿入:

username    ALL= NOPASSWD: /path/to/command

ここでは、パスワードを入力せずにコマンドを実行することになっているユーザーのusernameを変更する必要があることは明らかです。また、実行可能ファイルへのパスを変更します。この時点で、実行可能ファイルはrootが所有でき、rootに対してのみ実行権限を持つことができることに注意してください。

押す Esc、次に:wqと記述し、次に Enter

これで、ユーザーusernameSudo /path/to/commandを使用してコマンドを実行でき、そのためにパスワードを入力する必要はありません。

10
slhck

私はLinuxで作業していますが、OSXはBSDであるため、他のUnixと同じ(一般的な)ルールに従っていると思います。

プログラム内で、成功すると0を返すsetuid(UID)を呼び出して、その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;
}

任意のユーザー名にsetuidできるので、cgiスクリプトを実行していて、「www-data」などではなく、自分のアカウントでユーザー名として実行したい場合は、そこで使用できます。私はこれを行います。それがあなたの質問に詳細に答えることができる理由です。

0
Richard Wicks