2014年8月26日火曜日

vim で samba 上のファイルを編集すると,ファイルのパーミッションが samba の create mode に戻されてしまう問題

Linux の samba サーバで公開されているファイルを,windows の vim で編集すると,ファイルのパーミッションが smb.conf の create mask で設定されるモードに戻されてしまう.

たとえば,create mode = 0664 の場合.
$ touch hoge
$ ls -l
合計 0
-rw-rw-r-- 1 nishi nishi 0 8月 26 01:28 hoge
$ chmod 777 hoge
$ sudo chown root:root hoge
$ ls -l
合計 0
-rwxrwxrwx 1 root root 0 8月 26 01:28 hoge*
### ここで windows から vim で hoge を編集 ###
$ ls -l
合計 4
-rw-rw-r-- 1 nishi nishi 5 8月 26 01:29 hoge
となる.実行ビットが落ちてしまうので,スクリプトの編集中など非常に困る.
更に,編集したファイルがシンボリックリンクだったりした場合,リンクが消されて通常ファイルが作られるのでもっと困る.
vim の代わりに notepad を用いた場合は,編集の前後でパーミッションは保持される.
また,
std::ofstream ofp(argv[1]);
ofp << "abc" << endl;
ofp.close();
という c++ プログラムを VC でコンパイルした物で試した場合もパーミッションは保持された.

ファイルのパーミッションだけでなくオーナーもユーザの物に戻ってしまっていることから,
vim でのファイルの保存時には,編集前のファイルの削除→編集後のファイルのセーブが行われている様に見える.

しかし,上記の chown root:root の操作に加え,chmod 555 . として,
カレントディレクトリの書き込み権限を落とすと,vim での編集後に,元のパーミッションが保持されたファイルがセーブされた.
一度削除していたら,書き込みエラーになるはずなのだが...

原因の調査は手に余るので,場当たり的だが今考えつく対処法はふたつ.
  1. chmod -w . (新規ファイル作成不可)かつ,chown root:root *(パーミッション変更不可) とする.
  2. smb.conf で,force create mode = 775 にする.
1.は,他のディレクトリに影響が出ないが,explorer から新規ファイル,フォルダが作成できなくなる.
2.は,共有全体で,テキストファイルを編集したときにも実行ビットが立つようになってしまう.
どちらも一長一短だが1の方がsafeかなと思う.

解決編


:set backupcopy=yes
参考: :help bkc, :helpgrep samba\c など.
bkc が no だと,元のファイルをリネームして backupfile とし,編集後のテキストを新規ファイルに書き込む.まさに上の挙動.

ただし,この設定だけだと私の環境では期待通りに動作しなかった.
smb.conf で create mask や,force create mode などを設定しているとどうしても影響を受ける様子.

; create mask = 770
; force create mode = 770
  map archive = no
  map system = no
  map hidden = no
  nt acl support = no
これで大抵は良くなったのだが,なんかの拍子で group のパーミッションが変わる時がある.
どうやら ACL (Access control list) が書き加えられている様子だが,トリガーが分からない.