Guile色々/ファイルやディレクトリの権限

変更履歴

概 要

目 次

参考資料

アクセス権限のテスト

(access? path how)

pathで指定されたファイルやディレクトリのアクセス権限(how)をテストします. 権限のテストは, この手続きを呼び出したプロセスの実ユーザーID・実グループIDに関して行います.

path は,絶対パスか, カレントディレクトリを起点とする相対パスを表す文字列です.

how は,確認したい権限を指定するフラグです. これは,以下に示す R_OK,W_OK,X_OK の組み合わせか, または F_OK のいずれかです. R_OK,W_OK,X_OK を組み合わせるときには,logior 手続きを使ってビットごとの論理和を求めます.

▹実行例:以下は /home/algo/tmp というディレクトリ上で作業しています. このディレクトリ上に somefile.txt というファイルはないので, 以下の3番目のテスト結果は #f になっています.
$ guile
GNU Guile 3.0.5
      ...... 起動メッセージ ......
guile> (access? "/home/algo/tmp" R_OK)
$1 = #t
guile> (access? "/home/algo/tmp" (logior R_OK W_OK X_OK))
$2 = #t
guile> (access? "./somefile.txt" (logior R_OK W_OK X_OK))
$3 = #f
guile> (access? "/home/algo/tmp" F_OK)
$4 = #t
guile> 

アクセス権限の変更

(chmod object mode)

object によって指定されたファイルやディレクトリのアクセス権限(permission)を変更します.

object は,ファイル名(文字列),ファイルポート,ファイルディスクリプタのいずれかを指定することができます. ただし,ポートやディスクリプタを使用する場合, ファイルはオープンしていなければいけません.

mode は,アクセス権限を表す整数を指定します.これは, ターミナル(シェル)上のchmodコマンドの引数として指定する整数と同じものです. 一般に,その整数は,以下に示すフラグ(8進数)を加算した値です.

例えば,#o0755 は, 所有者に読み取り/書き込み/実行/探索のすべての権限を与え, 所有グループと他ユーザーに読み取りと実行/探索の権限を与えることを示しています.

▹実行例:/home/algo/tmp/somfile.txt というファイルに対して, まず当初のアクセス権限(#o0644)を確認します. 次に,アクセス権限を #o0755 に変更して, 変更後のアクセス権限を確認します. さらに,setuid,setgid,sticky bit をすべて設定したあと, 設定後のアクセス権限を確認します.
$ guile
GNU Guile 3.0.5
guile> (system "ls -l /home/algo/tmp/somefile.txt")
-rw-r--r-- 1 algo algo 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$1 = 0
guile> (chmod "/home/algo/tmp/somefile.txt" #o0755)
guile> (system "ls -l /home/algo/tmp/somefile.txt")
-rwxr-xr-x 1 algo algo 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$2 = 0
guile> (chmod "/home/algo/tmp/somefile.txt" #o7755)
guile> (system "ls -l /home/algo/tmp/somefile.txt")
-rwsr-sr-t 1 algo algo 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$3 = 0
guile> 
なお,sticky bit はディレクトリに設定して, そのディレクトリ内のファイルの削除や移動を制限するためのものです. 上の実行例が示すように,通常のファイルにも設定できますが意味をなしません.

所有権の変更

(chown object owner gourp)

object によって指定されたファイルやディレクトリの所有者とグループを変更します.object が指定するファイルがシンボリックリンクだったとき, シンボリックリンクを辿った先のファイルの所有権を変更します. 残念ながら,現時点では,シンボリックリンクの所有権だけを変更する機能(システムコールのlchown関数の機能)はサポートされていません.

object は,ファイル名を表す文字列です. 実行環境が fchown 関数をサポートしているならば, ファイルポートやファイルディスクリプタも指定できます. ただし,ポートやディスクリプタを指定する場合, そのファイルがオープンしていなければいけません. 筆者の環境(Debian 11)では, ポートやディスクリプタが使えるようです(下記の実行例を参照).

ownergroup は,それぞれ, ユーザーID(整数)とグループID(整数)です. ただし,-1 を指定したときには現在のIDを維持します(つまり,変更しません).

▹実行例:/home/algo/tmp/somefile.txt というファイルを対象に, その所有権を色々な方法で変更してみます. 所有権が変更されたことは system 手続きに ls コマンドを渡して確認します.system 手続きは,引数として渡されたコマンドをシェルの上で実行します(注:system 手続きの返り値は無視して下さい). それから.一般ユーザーは所有権の変更ができないので, スーパーユーザー権限でREPLを起動します.
$ sudo guile
[sudo] algo のパスワード:*************************** ↵
GNU Guile 3.0.5
      ...... 起動メッセージ ......
guile@root> 
まず,/home/algo/tmp/somefile.txt の現在の所有権(algo:algo)を確認します.
guile@root> (system "ls -l /home/algo/tmp/somefile.txt")
-rw-r--r-- 1 algo algo 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$1 = 0
所有権をrootユーザー(root:root)に変更して,その結果を確認します.
guile@root> (chown "/home/algo/tmp/somefile.txt" 0 0)
guile@root> (system "ls -l /home/algo/tmp/somefile.txt")
-rw-r--r-- 1 root root 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$2 = 0
somefile.txt をオープンしてファイルポートを作り, そのポートを使って所有権を元の状態(algo:algo)に戻します. 以下の 1000 はalgoのユーザーIDとグループIDです.
guile@root> (define port (open-input-file "/home/algo/tmp/somefile.txt"))
guile@root> (chown port 1000 1000)
guile@root> (system "ls -l /home/algo/tmp/somefile.txt")
-rw-r--r-- 1 algo algo 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$3 = 0
さらに,ファイルポートからファイルディスクリプタを作って, ディスクリプタを使って所有権をrootユーザーに変更します. 以下の fileno は,ファイルポートからファイルディスクリプタを作るための手続きです.
guile@root> (define fd (fileno port))
guile@root> (chown fd 0 0)
guile@root> (system "ls -l /home/algo/tmp/somefile.txt")
-rw-r--r-- 1 root root 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$4 = 0
最後に,所有者は変えずに,所有グループをalgo(IDは1000)に変更したあと, その結果を確認します. そのあとさらに,所有グループは変えずに, 所有者をalgo(IDは1000)に変更して,今回の実行例を終了します.
guile@root> (chown "/home/algo/tmp/somefile.txt" -1 1000)
guile@root> (system "ls -l /home/algo/tmp/somefile.txt")
-rw-r--r-- 1 root algo 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$5 = 0
guile@root> (chown "/home/algo/tmp/somefile.txt" 1000 -1)
guile@root> (system "ls -l /home/algo/tmp/somefile.txt")
-rw-r--r-- 1 algo algo 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$6 = 0

▹実行例:シンボリックリンクに対して所有権を変更したときに何が起こるかを観察してみます.まず,somefile.txt と同じディレクトリ上に somefile.lnk というシンボリックリンクを作って,シンボリックリンクとファイルの所有権を確認します.
$ cd /home/algo/tmp
$ ln -s somefile.txt somefile.lnk
$ ls -l somefile.*
lrwxrwxrwx 1 algo algo 12  2月  3 21:58 somefile.lnk -> somefile.txt
-rw-r--r-- 1 algo algo 22  2月  3 21:02 somefile.txt
次に, REPLの中でシンボリックリンク somefile.lnk の所有権をrootユーザーに変更したあと,リンクと元のファイルの所有権を確認してみます.
$ sudo guile
[sudo] algo のパスワード: ********************************* ↵
GNU Guile 3.0.5
      ...... 起動メッセージ ...... 
guile@root> (chown "/home/algo/tmp/somefile.lnk" 0 0)
guile@root> (system "ls -l /home/algo/tmp/somefile.*")
lrwxrwxrwx 1 algo algo 12  2月  3 21:58 /home/algo/tmp/somefile.lnk -> somefile.txt
-rw-r--r-- 1 root root 22  2月  3 21:02 /home/algo/tmp/somefile.txt
$1 = 0
この結果を見ると,シンボリックリンクの所有権は変化せず, リンク先のファイルの所有権が変化しています.
(おしまい)