winbind でユーザ情報テンプレートとして SFU のスキーマを使う

昨日の続きです。

2007/12/05 追記

下記の設定のままでは Samba 3.0.25 の場合にうまく動きません。詳しくはSamba-3.0.25 と SFU スキーマでハマった - daily dayflower 参照

一行まとめ

ads で winbind 使うなら DC に SFU をインストールしなくてもいいから AD のスキーマを拡張しておくとよい

※今日は ActiveDirectory 環境限定のお話です;NT ドメインモデルには適用できないと思います

sudoers の編集

前回積み残し課題だった /etc/sudoers の設定ですが,素直に設定すればいけました。visudo すると RedHat 系の場合

## Allows people in group wheel to run all commands
# %wheel        ALL=(ALL)       ALL

みたいにサンプルが書いてあるのでそれに習って

%Domain\ Admins ALL=(ALL)       ALL

のように書くと,ドメインの管理者は sudo できるようになります。グループ名にスペースが含まれているので,\ でエスケープする必要があります。

最初 % の代わりに + を使っていてうまくいかなかったんですが,素直に % にしてうまくいきました。昔の sudo だと nsswitch.conf で group の設定を「group: winbind files」みたく winbind を頭にもってこないといけなかったらしいんですが,今の sudo なら大丈夫。

ログインシェルをユーザ毎に指定したい

ActiveDirectory のユーザを UNIX のユーザ情報(/etc/passwd)にマッピングする際,必要な情報として以下のものがあります。

  • uid / gid
  • Gecos (名前)
  • Home Directory
  • Login Shell

昨日の設定では,uid / gid については rid idmap backend を使うことで AD の RID から一意に算出をしていました。Gecos は,たぶん AD のユーザの CN (Common Name) から引いてくれるんだと思います。で,残りの Home Directory と Login Shell については,smb.conf の template homedir / shell というパラメータで設定していました。

しかしこのままだと Login Shell が,AD の全ユーザで共通のものを使わなくてはいけません。このユーザにはシェルを遣わせたくない,とか,俺は zsh 命なんだ,というニーズにこたえられないのです。

そこで用意されているのが昨日もちらりと触れましたが,smb.conf の winbind nss info というパラメータです(参考→【Samba 3.0.20のwinbind nss infoパラメータ】)。昨日はなんとなく idmap backend に ad を指定したときにあわせて設定すると便利かな,くらいの理解だったんですが,このたかはしもとのぶさんの日記を読んで「そっか,idmap (uid / gid) と nss (user information) は独立して与えられるんだ!」と目から鱗でした。

私個人はどうしても zsh を使いたいのでがんばってみますよ!

Step 1: ActiveDirectory のスキーマSFU 用に拡張する

ディレクトリコントローラに SFU をまるっと入れてもいいんですが,NFS だの NIS だの Interix だのがインストールされるのがうっとおしいですよね。管理の手間も増えるし。

スキーマ拡張だけであれば、NISモジュールをインストールしなくても、sfusch.exe を実行すればOKっぽいです。ただし、その場合は管理GUIがインストールされないので、データの入力とかが若干面倒になりそう(未検証)。詳細は企業ユーザーのためのSFU 3.5活用ガイダンス 第2回 NISサーバとパスワード同期機能(前編)とかをみてくださいませ。

だめだめ日記(2005-09-21)

ディレクトリから Login Shell(や Home Directory)がとれるだけで十分だと思うのです。なので,SFU 全体はインストールせずに sfusch で AD を SFU 用に拡張するところだけやります。手順は上記で引用している @IT のサイトを見ればわかります*1

と,ここですんごくはまったところをお教えしておきます。最初 SFUアーカイブを My Documents 以下に展開して sfusch を実行してたんですが,「スキーマ管理者グループに所属してません」と怒られてしまいます(Administrator でやってるのに!)。解決策は,SFU を LFN じゃないところに展開してから sfusch を実行する,というものです。

ちなみに私の環境ではドメインサーバは Windows 2000 Server(古っ)です。2003 Server R2 だとひょっとすると AD のスキーマは拡張されているかもしれませんRFC2307 に準拠したスキーマとなりました。Samba 3.0.23 以降?で使えます(参考→【http://www.exconn.net/Blogs/windows/archive/2006/03/02/7360.aspx*2)。

Step 2: winbind の設定を代える

私の場合,uid / gid についてはいちいち AD に設定したくないので idmap backend は rid のままでいきます。ということで,昨日から winbind nss info だけ書き換えます。

monyo さんのように,smb.conf を以下のように書き換えます。

[global]
    ...
    winbind nss info = sfu template
    ...

smb.conf のマニュアルを読みつつ,なんとなく fallback として template も指定しておきました。SFU 用エントリが存在しない場合,template homedir / shell を使ってくれます。

で winbind を再起動。

Step 3: ユーザの Login Shell を設定する

設定する前に,とりあえず現状の mapping を確認してみます。

# getent passwd dayflower
dayflower:*:11190:10513:Dayly Dayflower:/home/dayflower:/bin/bash

「/home/ユーザ名」というのと「/bin/bash」というのは template homedir / shell で指定したものです。

さて,SFU をきちんとインストールしないとユーザ管理用の GUI がなくて困ります。適当な LDAP ディレクトリエディタを使うことになります。

今回は後者でいきます。英語版でよければ【http://www.microsoft.com/windows2000/downloads/servicepacks/sp4/supporttools.mspx】からダウンロードできます。

  1. ADSI Edit を開く
  2. Domain NC を開く
  3. 下位ツリー(今回の例だと DC=hoge,DC=example,DC=com)を開く
  4. CN=Users を開く
  5. ターゲットユーザの CN(例では DC=Dayly Dayflower)を選択,右クリックしてプロパティを開く
  6. Attributes タブを選択
  7. 「Select which properties to view」は Optional か Both を選択
  8. 「Select a property to view」で「msSFU30LoginShell」を選択(この選択肢がない場合,スキーマの拡張がうまくいっていない)
  9. 「Edit Attribute」欄に,(今回の例では)「/bin/zsh」を入力
  10. 「Set」ボタンを押す

以上の手順でこのユーザの Login Shell が変更できました。もし Home Directory を変更したい場合は「msSFU30HomeDirectory」を変更します。私はホームディレクトリについては template homedir におまかせしてます。


さて,新しい mapping を確認してみましょう。

# getent passwd dayflower
dayflower:*:11190:10513:Dayly Dayflower:/home/dayflower:/bin/zsh

おお,でけたでけた。

雑感

NT ドメインモデルではできない,と書きましたけど,Samba (LDAP) PDC だったら LDAP サーバに SFU30 のスキーマを定義してやればいけるんじゃないかなぁとなんとなく思いました。

*1:@IT のサイトでは,『フォレスト内のドメイン・コントローラが1台の場合以外は』と書いてありますが,SFU 全体をインストールしたくないなら,ドメインコントローラが1台の場合でも sfusch を使ってください

*2:でもたぶんこの SUA って Interix の POSIX サブシステム部分だと思うです;だからやはりスキーマの拡張は必要なんじゃないかなぁ

winbind で Linux の認証を ActiveDirectory にまかせる

一行まとめ

  • 複数ドメインの信頼関係を構築していない場合,winbind の idmap backend として rid を使うと便利

前フリ

サーバを立てるたびにユーザアカウントをメンテナンスするのが面倒だ,ということでようやく腰を据えて winbind について勉強しました。ネット上に有用な文書が多くて助かりました。

  • CentOS 5.0
  • samba-3.0.23c-2.el5.2.0.2

という環境で,以下のような名称を例として使います。

基礎知識

ユーザが *nix を利用しようとすると,

  • 認証
  • ユーザ情報,ホスト情報等の管理情報へのアクセス

が必要になります。

古典的な *nix ではこれらをすべて /etc/passwd, /etc/groups, /etc/shadow, /etc/hosts 等のローカルファイルとせいぜい DNS を使って行ってきました。んが,そういった認証システム・情報システムの設定が各マシンで分散することになり面倒です。

で,それらのシステムをプラガブルにして外部に委託したりできるようにしたのが,認証については PAM,管理情報についてが NSS という仕組みです*1(参照→【パスワードの管理と運用を考える (1/2):Linux管理者への道(1) - @IT】の前半)。

さて,winbind というのは Samba に付属するデーモンで,認証や管理情報をドメインコントローラから取得し,UNIX 上のユーザ ID 等とのマッピングを保持してくれるものです(参照→【Samba が動作する Linux マシンを Windows ドメインに参加させる方法 ― MIRACLE LINUX V2.1 における Samba Winbind 利用方法 ―:ミラクル・リナックス】)。

今回のお話は,PAM と NSS に winbind を登録することによって,認証等を ActiveDirectory に任せる,ということになります。

winbind の設定

らんすの本棚】さんの【ActiveDirectory+Linux‚É‚æ‚é•”“àƒT[ƒo\’z】記事内の【4.“‡”FØ‚̐ݒèiWinbind+Kerberosj】に従ってやってみました。できた!おしまい。

というくらい素晴らしい記事です。

個人的にはまったところ。ActiveDirectory に join しようとして

# net ads join
Using short domain name -- HOGE
Failed to set servicePrincipalNames. Please ensure that
the DNS domain of this server matches the AD domain,
Or rejoin with using Domain Admin credentials.
Disabled account for 'PENGUIN' in realm 'HOGE.EXAMPLE.COM'

のように怒られる場合,127.0.0.1 でいいので,ADS 名に対応する名前を /etc/hosts で解決するようにすればいけるようです。騙されたと思って

# /etc/hosts
127.0.0.1 penguin.hoge.example.com penguin localhost.localdomain localhost

みたいにすると幸せになれるかも。

いろんな紆余曲折をへて,

# wbinfo -u
Administrator
...

# wbinfo -g
NetShow Administrators
...

# wbinfo -t
checking the trust secret via RPC calls succeeded

# id dayflower
uid=10000(dayflower) gid=10000(Domain Users) groups=10000(Domain Users),10001(Domain Admins)

みたく,無事に ActiveDirectory のユーザを UNIXマッピングできるようになりました。

ssh 等でログインできるようにしたい

上記手順までで行ったことは,管理情報の取得経路(NSS)として winbind を使えるようになったことだけです。このままでも samba サーバ(NAS)として使えるのですが,認証システム(PAM)の設定をしていないので ssh 等でログインできません。ですので,PAM 用の設定をします。

といっても RedHat 系なら authconfig を使うと楽に設定できます。TUI の場合,authconfig-tui を使うとインタラクティブに設定できます。GUI の場合,system-config-authentication で「Authentication」タブの「Enable Winbind Support」をチェックすると /etc/pam.d/system-auth-ac ファイルが適宜書き換えられ,winbind を認証に利用するようになります。smb.conf が適切に設定されている場合,「Configure Winbind ...」ボタンの先も適切な内容になっているはずです。

あとは sshd の設定ですが,CentOS だと一応そのままで大丈夫でしたが,/etc/ssh/sshd_config の内容が

UsePAM yes

# 下記のいずれかの認証を yes にする必要あり
#PasswordAuthentication yes
#ChallengeResponseAuthentication yes

のようになっている必要があります。もちろんセキュリティ上の懸念がありますが詳しくは説明しません。

また,smb.conf の内容に

winbind use default domain = yes

が入っていることを確認しておきます。no の場合,認証を行う際に,ユーザ名にドメイン名をいちいちつけなくてはいけなくなってしまうので(たとえば winbind separator = _ の場合,「ssh -l HOGE_dayflower localhost」のように)。

ホームディレクトリを自動的に作成されるようにしたい

いざ,ssh でログインしてみようと思ったら…

# ssh -l dayflower localhost
password: ********
Could not chdir to home directory /home/dayflower: No such file or directory
$ 

ディレクトリがないって怒られます。自動的に作成されるわけではないんですね。と思って調べたところ,Samba-ML へのたかはしもとのぶさんの投稿が目に止まりました。(2008-11-13 追記: コメント欄の情報により引用元を改変して引用しています)

自動でホームディレクトリを作成するには、大きく

の設定を連携して行う必要があります。Sambaのすべてをお持ちであれば、
P.401 も参照してみてください。

[samba-jp:19138] Re: ホームディレクトリを作成できない

なるほど。「obey pam restrictions = yes」については,もともと上記の手順の設定に含まれていました。CentOS の場合,pam_mkhomedir.so を設定するだけでよいようです。

/etc/pam.d/system-auth(-ac) は先ほどの例のように authconfig によって書き換えられてしまうので直接いじるのには抵抗感があるのですが,しかたなく書き換えることにします。

具体的には session 項の末尾「session required pam_unix.so」の下に,

session required pam_mkhomedir.so skel=/etc/skel umask=0022

のように書き加えます。

# ssh -l dayflower localhost
Password: ********
Creating directory '/home/dayflower'.

[dayflower@penguin ~]$ 

無事,ホームディレクトリが自動生成されるようになりました。

なお sshd の場合,サーバ自体が root 権限で動作しているので pam_mkhomedir でうまくディレクトリが自動生成されましたが,実行時に権限を落とすアプリケーションの場合うまく働かない可能性があります。そのようなときは,oddjob と pam_oddjob_mkhomedir が使えるかもしれません(参照→【http://www.redhat.com/magazine/024oct06/features/tips_tricks/】)。検証してないですケド。

winbind の問題点と解決

先ほどの例からですが,

# id dayflower
uid=10000(dayflower) gid=10000(Domain Users) groups=10000(Domain Users),10001(Domain Admins)

winbind は idmap uid /gid に指定された番号から取得順に割り振っていきます。ですから,このような winbind を立ち上げたサーバが複数台あると,サーバ間で UNIX uid / gid の整合性をとることが難しくなります。

Samba 3 から,idmap のバックエンドとして LDAP サーバを指定できるようになりました(→【Active Directory参加機能とセキュリティ拡張 (2/3):Samba 3.0の全貌 改訂版(2) - @IT】)。でも LDAP サーバ立ち上げるの面倒だし…とドキュメントを読んでいたら,「rid」なるバックエンドもあるではないですか。

RID とは何か,の前に SID とは何か,というのを説明しなくてはいけませんね。SID というのは,Windows Server でリソースを示す Unique ID です。ユーザ,グループ,コンピュータ名,等々あらゆるリソースに ID が割り振られています。dayflower の SID を確認してみます。

# wbinfo -n dayflower
S-1-5-21-299502267-436374069-1708537768-1190 User (1)

このような文字列全体が SID です。で,前半の「S-1-〜」というとことはドメイン(or ローカルコンピュータ)で(たぶん)共通しているのですが,太字で示した「1190」という数値が,リソースごとに異なる ID であり,これを RID と呼ぶらしい。

ということで,さっそく backend として rid を指定してみます。詳しい設定については,なぜか日本語ドキュメントの充実している HP の文書【http://docs.hp.com/ja/B8725-90121/ch07s07.html】も参照してみてください。

# smb.conf(抜粋)
[global]
allow trusted domains = No

idmap backend = rid:HOGE=10000-19999
idmap uid = 10000-19999
idmap gid = 10000-19999

smb.conf のマニュアルにあるとおりに BUILTIN というドメインを含めておくとなぜかうまくいかなかったので,利用するドメインのみ指定してあります。また,ドキュメントにあるとおり,信頼関係のあるドメインをサポートするのはよくないらしいので(そりゃ RID 部分が衝突しそうですもんね),disable してあります*2

idmap 等の情報については CentOS の場合,/var/cache/samba 以下に格納されているので,一度 winbind を止めて削除します。

# service winbind stop

# cd /var/cache/samba

# rm -f *.tdb

# service winbind start

winbindd_idmap.tdb だけで十分だと思いますが,念のためにごっそり全部消しました。また,先ほど自動生成されたホームディレクトリも削除することをお忘れなく。

さて,backend として rid を使うとどうなるか…

# id dayflower
uid=11190(dayflower) gid=10513(Domain Users) groups=10513(Domain Users),10512(Domain Admins)

先ほどの RID=1190 に,ベースとなる 10000 を加えた 11190 が UNIX user ID として割り振られました。これでドメイン内の UNIX uid /gid を簡単に整合性をとることができます。スバラスイ。


ちなみに,SFU をインストールしたドメインコントローラの場合,idmap backend として「ad」を指定して,マッピングディレクトリサーバに投げることもできます。この場合,「winbind nss info」は「template」ではなく「sfu」としておくとさらに便利かと思います。

積み残し

触れませんでしたが,AD サーバが落ちてしまった場合に備える「winbind offline logon」というオプションもあります。詳しくは【[Sambaウォッチ]第6回 オフラインログオンの大幅改善など,Samba 3.0.25のさまざまな新機能 | 日経 xTECH(クロステック)】を参照してください。

今回の設定では sshd の設定を甘めにしてあるのでお気をつけください。イントラ用途ということでご容赦を。

あとは /etc/sudoers の設定についても積み残し。

*1:厳密には NSS だけでも認証をインプリメントすることは可能でしょうが,話を簡単にするためにあえて分業させました

*2:ドメイン毎に idmap の範囲を指定できるので trusted domains が on でもうまくいきそうな気がするのですが……未検証です。

続きを読む

Express 5800 110Gd で 4GB メモリが使えた on IA-32

NEC Express 5800 110Gd(チップセット 3000)に,あえてメモリ空間食いな NVIDIA PCX 6600 を載せて調査。

CentOS 5.0 i386 で,non-PAE kernel の場合,

Linux version 2.6.18-8.el5 (mockbuild@builder4.centos.org) (gcc version 4.1.1 20
070105 (Red Hat 4.1.1-52)) #1 SMP Thu Mar 15 19:57:35 EDT 2007
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009dc00 (usable)
 BIOS-e820: 000000000009dc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000e4000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000c7e70000 (usable)
 BIOS-e820: 00000000c7e70000 - 00000000c7e7a000 (ACPI data)
 BIOS-e820: 00000000c7e7a000 - 00000000c7e7b000 (ACPI NVS)
 BIOS-e820: 00000000c7e7b000 - 00000000c8000000 (reserved)
 BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
 BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)
 BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
 BIOS-e820: 00000000ff000000 - 0000000100000000 (reserved)
 BIOS-e820: 0000000100000000 - 0000000138000000 (usable)
Warning only 4GB will be used.
Use a PAE enabled kernel.
3200MB HIGHMEM available.
896MB LOWMEM available.

... snip ...

Memory: 3234772k/4194304k available (2043k kernel code, 39088k reserved, 846k data, 232k init, 2357696k highmem)

のように 3.2GB のメモリが使用可とのことですが,

 BIOS-e820: 0000000100000000 - 0000000138000000 (usable)

という部分に一筋の光明が。

ということで PAE kernel でブートしてみる。と,

Linux version 2.6.18-8.1.6.el5PAE (mockbuild@builder4.centos.org) (gcc version 4
.1.1 20070105 (Red Hat 4.1.1-52)) #1 SMP Thu Jun 14 19:10:16 EDT 2007
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009dc00 (usable)
 BIOS-e820: 000000000009dc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000e4000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000c7e70000 (usable)
 BIOS-e820: 00000000c7e70000 - 00000000c7e7a000 (ACPI data)
 BIOS-e820: 00000000c7e7a000 - 00000000c7e7b000 (ACPI NVS)
 BIOS-e820: 00000000c7e7b000 - 00000000c8000000 (reserved)
 BIOS-e820: 00000000e0000000 - 00000000f0000000 (reserved)
 BIOS-e820: 00000000fec00000 - 00000000fec10000 (reserved)
 BIOS-e820: 00000000fee00000 - 00000000fee01000 (reserved)
 BIOS-e820: 00000000ff000000 - 0000000100000000 (reserved)
 BIOS-e820: 0000000100000000 - 0000000138000000 (usable)
4096MB HIGHMEM available.
896MB LOWMEM available.

... snip ...

Memory: 4145100k/5111808k available (2040k kernel code, 46236k reserved, 841k data, 232k init, 3275200k highmem)

おお,4GB使用可になりましたよ。

% free

            total       used       free     shared    buffers     cached
Mem:       4147812     404944    3742868          0      81964     208564
-/+ buffers/cache:     114416    4033396
Swap:      1044216          0    1044216

X もきちんとあがりますし(nvidia ドライバじゃなくて nv ドライバでしかテストしていませんが)。

ということで,IA-32 でも PAE on でうまく PCI memory remapping をハンドリングできる OS を使えば,無駄なくメモリを使用することができる環境はある,と。

本筋とは関係ないですが,このマシン,PCI Express にグラボ刺しててもオンボードな Volari が切り離されないのはちっと悲しいです。

2007/06/26 追記

Windows XP 32bit をインストールしてみましたが,やっぱり天使の取り分が発生し,有効メモリは 3GB になってしまいました。システム情報リソースでメモリを見たところ,32 bit な表記だったんで,やっぱり物理アドレス 32bit が限界みたいですね。

Linux から nmb な名前解決をしたい → libnss_wins

最近,メインの作業環境を Windows から Linux に変えました。で困ってたのは,Linux*1 から Windows のマシン名でアクセスできないことです。

どういうことかというと,今までの作業環境だと,

  1. Linux サーバを立てる
  2. Samba を動かす
  3. Windows ドメインに参加させる*2
  4. Apache を動かす
  5. Windows クライアントのブラウザから Linux サーバにアクセス→ウマー

というステップでしたが,ここでたとえば Samba サーバ名を hogehoge にしとけば,ブラウザから ttp://hogehoge/ でアクセスできたわけです。

ところが,いまのクライアント環境は Linux なので,ttp://hogehoge/ でうまくアクセスできません。困ったーでも host.conf とか nsswitch.conf とかあるし,なんとかうまくできるはずだーと,いろんなキーワードでググってみたら,やっぱりちゃんとありました。

/etc/nsswitch.conf に,以下のように wins を追加するだけで,Windows とほぼ同様の名前解決ができる。

hosts:          files dns wins
ねぎ式 - Windows ばかりの LAN の名前解決は libnss_wins がヨサゲ

んーでもうち WINS サーバあげてないしーと思ったんですが,上記サイトさんの解説や,Miracle Linux のドキュメント を見ると,wins を特に指定してないと port 137 ブロードキャストできちんと解決してくれるらしいです。

てなわけで,とりあえず samba(-common) をインストールして,/etc/nsswitch.conf を

hosts:          files wins dns

のように書き換えて(私的環境では dns より wins を前に持ってきました),無事 Linux 上のブラウザから ttp://hogehoge/ でアクセスできるようになりました*3

いやー危うく winbind について勉強するとこでした*4

*1:もうすぐ Fedora 7 がリリースされるのに Fedora core 6 っす;やっと Fedora 7 の GA が 2007-05-31 に決まりました

*2:厳密には ActiveDirectory 運用してるんですが,あるときを境に ADS でうまくいかなくなったんで server = DOMAIN で運用してます

*3:もちろん ping hogehoge も OK

*4:もちろんいつかきちんと勉強します;そろそろ各所で設定をしてくのめんどいし

それ Font::TTF でできたよ

TTF フォントから EBDT / EBLC を削除するプログラムを昨日作成しましたが,CPAN をみたら,Font::TTF なるモジュールがありました。うんうん,FreeType じゃなくてこういうコンセプトのものがほしかったんです。

とりあえず,そのまま読んで書いてみると,

use Font::TTF::Font;

my $font = Font::TTF::Font->open($ARGV[0]);
$font->out($ARGV[1]);

なぜかファイルサイズが半分以下に。もしや?と思って開いてみたら,見事に EBDT 等が削除されてました。

これはこれで目的達成できたんだけど,EBDT 等を温存したい場合は?

my $font = Font::TTF::Font->open($ARGV[0]);
$font->{$_}->read
    for (qw( EBDT EBLC ));
$font->out($ARGV[1]);

こんな感じですかね?と,出力してみたら延々時間がかかった上に,ファイルサイズが増えてしまいました。たぶん EBDT の再利用に対応してないんだろうな。

で出力結果をみてみたら,超汚いビットマップになってしまいました。たとえて言うと Java コンパネのフォントのような昔の XTF のような… Font::TTF が gasp に対応してないのが理由なのかしらん。でもビットマップでヒンティングとか関係ないですよねたぶん…

ちなみに,サンプル通りに

$font->tables_do(sub { $_[0]->read; });

で全テーブル強制読み込みしても同じ結果でした。よろしくない。

日本語フォントだと読み込みにすごく時間がかかりますし,まだ有用じゃないかなと思います。

MS Office のファイルフォーマット(OLE2)

Microsoft Excel のファイルフォーマットについてあれこれ調べてました。昔の MSDN に書いてあった気がするんですが,見つかりませんでした。

そのかわり,といってはなんですが,OpenOffice.org Calc のデベロッパーサイト http://sc.openoffice.org/ の中に結構詳しい解説書がありました。ポインタとして示すのが難しいんで,直リンクしときます。

今時は XML で吐いたりできるみたいなんですが,昔の OLE2 ドキュメントというのが,FAT のようなファイルシステムを内包していて正直うざいです。

この OLE2 ドキュメントのヘッダは,

D0 CF 11 E0 A1 B1 1A E1

という8バイトで始まるんですが,どういう意味があるんだろうと x86 で逆アセしたりしたりしたんですがよくわからず…と,ぼーっとみてたら,

DO CF Il E...

になってて,なるほど!と思いました*1。後半4バイトについてはわかりませんでしたが。

DOCFILE に内包された Excel ワークブックファイルのフォーマットは,

が日本語で書いてあってわかりやすいです。

Word についてだと,

がやはり日本語のリソースで詳しいです。

*1:ググってみたらこちらのサイトにも書いてありました