# 機能設計書 69-パイプ権限変更

## 概要

本ドキュメントは、パイプの権限を変更する機能（`uv_pipe_chmod()`）の設計を記述する。

### 本機能の処理概要

バインド済みのパイプに対して、読み取り/書き込み権限を設定する。Unixではソケットファイルのパーミッションをchmodで変更し、WindowsではNamed PipeのDACL（Discretionary Access Control List）を変更する。

**業務上の目的・背景**：デフォルトのパイプ権限では、他のユーザーやグループからのアクセスが制限される場合がある。別ユーザーが実行するクライアントプロセスからの接続を許可するため、パイプの権限を明示的に設定する必要がある。

**機能の利用シーン**：異なるユーザー権限で動作するプロセス間のIPC通信、サービスデーモンが提供するパイプへのクライアントアクセス許可など。

**主要な処理内容**：
1. パラメータのバリデーション
2. Unix: fchmod()でFD権限変更を試行、失敗時はchmod()にフォールバック
3. Windows: DACL操作でEveryoneグループの権限を設定

**関連システム・外部連携**：Unix fchmod()/chmod()、Windows GetSecurityInfo()/SetSecurityInfo() API。

**権限による制御**：パイプファイルの所有者またはroot権限が必要（Unix）。適切なWRITE_DAC権限が必要（Windows）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 19 | パイプ | 主機能 | uv_pipe_chmod()によるパイプ権限変更のAPI定義 |

## 機能種別

設定処理（アクセス権限の変更）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| handle | uv_pipe_t* | Yes | 権限を変更するパイプハンドル | NULLでなく、有効なFD/ハンドルを持つこと |
| mode | int | Yes | 設定する権限（UV_READABLE/UV_WRITABLE/両方のOR） | UV_READABLE, UV_WRITABLE, またはその組み合わせ |

### 入力データソース

呼び出し元アプリケーションから直接提供される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | 成功時は0、失敗時は負のエラーコード |

### 出力先

OSレベルでのファイル/パイプ権限の変更。

## 処理フロー

### 処理シーケンス

```
[Unix]
1. パラメータバリデーション
   └─ handle==NULL、FD==-1、mode不正をチェック
2. 権限マスクの構築
   └─ UV_READABLE → S_IRUSR|S_IRGRP|S_IROTH
   └─ UV_WRITABLE → S_IWUSR|S_IWGRP|S_IWOTH
3. fchmod()試行
   └─ 失敗時（EINVAL/EOPNOTSUPP以外）はエラー返却
4. chmod()フォールバック
   └─ uv_pipe_getsockname()でパス取得
   └─ パス名が空でpipe_fnameがあればそちらを使用
   └─ chmod(name, desired_mode)

[Windows]
1. パラメータバリデーション
2. Everyone SIDの作成
3. 現在のDACL取得
4. 新しいACLエントリ構築
5. DACLの更新
```

### フローチャート

```mermaid
flowchart TD
    A[開始: uv_pipe_chmod] --> B{バリデーション}
    B -->|不正| C[return UV_EBADF/UV_EINVAL]
    B -->|OK| D{Unix or Windows?}
    D -->|Unix| E[権限マスク構築]
    E --> F[fchmod 試行]
    F --> G{成功?}
    G -->|Yes| H[return 0]
    G -->|No| I[getsockname でパス取得]
    I --> J[chmod フォールバック]
    J --> H
    D -->|Windows| K[Everyone SID作成]
    K --> L[DACL取得・更新]
    L --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 権限マッピング（Unix） | UV_READABLE → 全ユーザー読み取り(S_IRUSR\|S_IRGRP\|S_IROTH)、UV_WRITABLE → 全ユーザー書き込み(S_IWUSR\|S_IWGRP\|S_IWOTH) | Unix環境 |
| BR-02 | fchmodフォールバック | macOSとBSD系ではfchmod()がUNIXソケットに対応しないため、chmod()にフォールバックする | macOS/BSD環境 |
| BR-03 | Everyone権限（Windows） | WindowsではEveryoneグループ（SECURITY_WORLD_RID）に対して権限を設定する | Windows環境 |
| BR-04 | modeの有効値 | UV_READABLE、UV_WRITABLE、またはその両方のOR値のみ有効 | 常に適用 |

### 計算ロジック

```c
// Unix権限マスクの構築
desired_mode = 0;
if (mode & UV_READABLE) desired_mode |= S_IRUSR | S_IRGRP | S_IROTH;
if (mode & UV_WRITABLE) desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
```

## データベース操作仕様

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UV_EBADF | 不正なハンドル | handle==NULLまたはFD/HANDLEが無効 | 有効なハンドルを指定 |
| UV_EINVAL | パラメータ不正 | modeの値が不正 | UV_READABLE/UV_WRITABLEの組み合わせを指定 |
| UV_EPERM | 権限不足 | chmod()/DACL変更の権限がない | 適切な権限で実行 |

### リトライ仕様

リトライ不要。

## トランザクション仕様

該当なし。

## パフォーマンス要件

chmod()/DACL操作を含むが、通常は数ミリ秒以内に完了する。

## セキュリティ考慮事項

- 過度に緩い権限設定はセキュリティリスクとなる。最小権限の原則に基づき、必要な権限のみを設定すべきである。
- WindowsではEveryoneグループに対して権限が設定されるため、同一マシン上の全ユーザーからアクセス可能になる点に注意。

## 備考

- macOS/BSDではfchmod()がUNIXソケットに対してEINVALまたはEOPNOTSUPPを返すため、chmod()へのフォールバックが実装されている
- Unix版ではuv_pipe_getsockname()で名前を取得できない場合、handle->pipe_fnameをフォールバックとして使用する
- Windows版ではSETEntriesInAcl()/SetSecurityInfo()でDACLを操作する

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | uv.h | `include/uv.h` | L901: uv_pipe_chmod()の関数宣言 |
| 1-2 | pipe.c (Unix) | `src/unix/pipe.c` | L448-494: Unix版実装 |
| 1-3 | pipe.c (Win) | `src/win/pipe.c` | L2651-2710+: Windows版実装 |

**主要処理フロー（Unix版 L448-494）**:
1. **456-461行目**: ハンドルとFDのバリデーション
2. **463-466行目**: mode値のバリデーション
3. **468-472行目**: desired_modeの構築
4. **475-477行目**: fchmod()試行。EINVAL/EOPNOTSUPP以外のエラーは返却
5. **480-483行目**: uv_pipe_getsockname()でパス取得
6. **487-488行目**: 名前が空の場合pipe_fnameをフォールバック
7. **490-491行目**: chmod(name, desired_mode)

**主要処理フロー（Windows版 L2651-2710+）**:
1. **2659-2665行目**: バリデーション
2. **2667-2674行目**: AllocateAndInitializeSid()でEveryone SIDを作成
3. **2676-2686行目**: GetSecurityInfo()で現在のDACLを取得
4. **2688-2698行目**: EXPLICIT_ACCESS構造体を構築
5. **2700-2710行目**: SetEntriesInAcl()とSetSecurityInfo()でDACLを更新

### プログラム呼び出し階層図

```
uv_pipe_chmod(handle, mode)
    |
    +-- [Unix]
    |   +-- fchmod(fd, desired_mode)        [試行]
    |   +-- uv_pipe_getsockname()           [パス取得]
    |   +-- chmod(name, desired_mode)       [フォールバック]
    |
    +-- [Windows]
        +-- AllocateAndInitializeSid()      [Everyone SID]
        +-- GetSecurityInfo()               [現在のDACL]
        +-- SetEntriesInAcl()               [新ACL構築]
        +-- SetSecurityInfo()               [DACL更新]
```

### データフロー図

```
[入力]                    [処理]                               [出力]

uv_pipe_t* handle ------> uv_pipe_chmod() -------> OS権限変更
int mode (UV_READABLE      |                        (ファイルパーミッション / DACL)
    | UV_WRITABLE)         +-- 権限マスク構築
                           +-- fchmod/chmod [Unix]
                           +-- DACL操作 [Windows]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| uv.h | `include/uv.h` | ヘッダー | API宣言（L901） |
| pipe.c (Unix) | `src/unix/pipe.c` | ソース | Unix版実装（L448-494） |
| pipe.c (Win) | `src/win/pipe.c` | ソース | Windows版実装（L2651-2710+） |
