teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

SUIDを利用する方法を追記

2019/03/25 06:05

投稿

dodox86
dodox86

スコア9416

answer CHANGED
@@ -51,4 +51,58 @@
51
51
 
52
52
  `visudo` の使い方は検索すればいくらでも参考記事が見つかりますので割愛しますが、修正を間違えると`su`コマンドが使えなくなって致命的な状況になるのでご注意の上、使用してみてください。
53
53
 
54
- この内容で当方のラズパイ1 modelBにてご提示のスクリプトとほぼ同等のものを使用し、GPIOでのLED 点灯/消灯ができました。質問者さんがご使用のラズパイ本体やraspbianは恐らくもっと新しいと思うので、異なるところもあるかもしれません。
54
+ この内容で当方のラズパイ1 modelBにてご提示のスクリプトとほぼ同等のものを使用し、GPIOでのLED 点灯/消灯ができました。質問者さんがご使用のラズパイ本体やraspbianは恐らくもっと新しいと思うので、異なるところもあるかもしれません。
55
+
56
+ ---
57
+ **追記しました:2019-03-25 15:04 **
58
+
59
+ 質問者さんのケースでは(恐らく)sudoerの問題だと思い、`visudo`コマンドでwww-dataユーザーをsudoさせるようにする回答をしましたが、別案のひとつとして`sudo`コマンドを使用せず、`/etc/sudoers`の修正もせずにroot権限で実行する方法をご紹介します。
60
+
61
+ linuxにはSUID(Set User ID)と言う特殊なアクセス権があって、実行ファイルにこのアクセス権をセットすることでその実行ファイルのオーナー(所有者)の権限で実行することができます。
62
+
63
+ [UNIX処方箋:- SUIDとは](https://www.itmedia.co.jp/enterprise/articles/0804/08/news014.html)
64
+
65
+ これを利用して、`/usr/bin/python3 /var/www/html/ledStart,py`を実行するC言語で作成したプログラムをPHPスクリプトから実行するようにすれば、`sudo`を使用しなくてもrootで`/usr/bin/python3`を実行し、GPIOを操作してLEDのON/OFFをすることができるようになります。
66
+
67
+ 具体的には以下のような`system` でプログラム内からpython3スクリプトを実行するC言語のプログラムを用意します。
68
+ ```C
69
+ #include <stdlib.h>
70
+
71
+ int main(int argc, char *argv[])
72
+ {
73
+ system("/usr/bin/python3 /var/www/html/ledStart.py");
74
+
75
+ return 0;
76
+ }
77
+ ```
78
+ これをコンパイル(ビルド)して実行ファイルを作り、その実行ファイルのオーナーをrootにして`chmod u+s 実行ファイル名`としてSUIDをセットします。
79
+ ```bash
80
+
81
+ pi@raspberrypi ~ $ gcc -Wall led_start.c -o led_start
82
+ pi@raspberrypi ~ $ ls -l led_start
83
+ -rwxr-xr-x 1 pi pi 5478 Mar 25 14:34 led_start
84
+
85
+ pi@raspberrypi ~ $ sudo chown root:root led_start
86
+ pi@raspberrypi ~ $ ls -l led_start
87
+ -rwxr-xr-x 1 root root 5478 Mar 25 14:34 led_start
88
+
89
+ pi@raspberrypi ~ $ sudo chmod u+s led_start; ls -l led_start
90
+ -rwsr-xr-x 1 root root 5478 Mar 25 14:34 led_start
91
+ pi@raspberrypi ~ $
92
+ ```
93
+
94
+ この実行ファイルが`/home/pi/led_start`だとして、PHPスクリプトの中から以下のように実行するとLEDが点灯します。www-dataユーザーでPHPスクリプトが実行されますが、`sudo`を使用しなくてもGPIOを制御できます。
95
+ ```PHP
96
+ # ...抜粋
97
+ if(isset($_POST["start"])) {
98
+ echo "LED Light ON";
99
+ #$path ='sudo python /var/www/html/ledStart.py';
100
+ #$path ='sudo /usr/bin/python3 /var/www/html/ledStart.py';
101
+
102
+ # SUID な/home/pi/led_startを実行する
103
+ $path ='/home/pi/led_start';
104
+ exec($path);
105
+ }
106
+ ```
107
+
108
+ 実験レベルではこんな使い方も有りかと思い、技術的な観点からご紹介させていただきました。