おれのIT日記

2025/11/05 (水)

Windows

Apache2.4のCGIでWin32::ODBCがネットワーク上のmdbにアクセスできずエラーになる


は? 平成時代の話題だぞ? と思った方、あなたの感覚は正しいです。読まないで飛ばしてください。
以下は、かつて2000年前後に、AN-httpdとActive PerlでAccessファイルの内容を検索表示するローカルWebアプリを知人のために作った男が、はるか未来の2025年で味わった後日譚です。

知人の方は、ご職業において数百以上の物件を管理しております。(もしかすると1000越えてるやも知れん。データ入力も手伝ったが、途中で投げ出して逃げ出した記憶がある……)
この方、仕事がら、来訪客や、電話問い合わせに、ぱぱっと調べて対応したり、マークをつけておいて後日、郵送をしたり、といったことが必要です。
同業の方も、同じことを考えたのでしょう、PCに慣れた同業の方、すごく凝ったAccessを作ってくださり、この知人の方は、Accessの詳細はわからないながらも、使っておられました。
おれもAccessは、自分で持っていないこともありますし、研究できていません。
特に、宛名ラベルやハガキの印刷、といった部分は、おれの手には余りますし、現状特に不便も無いので、ここはAccessをそのまま使い続けてもらいます。
ただ、検索その他がやりにくそうだったので、ブラウザから検索・一覧表示、追加・更新ができるようにしたわけです。

検索は、年に数回行う印刷と違い、毎日行います。かつ、パッと瞬時に結果を見たい場合が多い。
そこで、当時のおれは、ちゃちゃっと表記の仕組みを作ってあげたのでした。
ひらがなで検索したり、同姓の方をクリックで検索したり、姓でも名でも引けるようにしたり、業務特有の、「やりたいこと」を実現してあげました。
あまり詳しく書くと何のシステムかわかってしまうので避けますが、このあたり、システム技術には特に見るべきものはないものの、ユーザ目線でのアイデアの勝利、といったところです。
AccessからもWebアプリからもデータベースを更新するなんて、危ないぢゃないか!......と、思うかもしれませんが、そもそもこの方お一人以外にシステムを使う方はいませんので、排他制御の心配は無用であります。
パソコンを買い替えたり、一時的に2台使うことがあったりするので、Webアプリにしておけば、どのPCからもアクセスできますから、知人の方は、たいそう喜んでくださり、おれも、人の役に立って嬉しいなぁ、と感じ入ったのが、25年前であります。

それを、まだ使ってらっしゃる。
今度、Windows11の新PCを買ったので、移植してほしいと、お電話がありました。
システム屋冥利につきますなぁ。
NASの設置とか、アプリの導入とかは、おれのアドバイス通り、有料で業者に委託されているので、既に済んでおります。

■ 当時のシステム構成は、AN-httpd 1.42p + Active Perl(Win32::ODBC)

DBIにしろや!、と思ったあなた、いまどき珍しい絶滅危惧種のperl使いですね! 嬉しいです。おっしゃる通りです。
が、このシステム、スクリプトだけで20個以上あるので、書き換えるのが面倒であります。
今回はそのままにします。
書き換えるなら、かなり本腰入れてやらんとならんのですよ。
たとえば一例。ODBCでAccessを読み書きするこのシステムでは、渡すSQLクエリおよび、得られる結果やODBCエラー文言は、ぜんぶシフトJISでありますから、うっかり深く考えずに、

な~んて書き換え始めてしまうと、いたるところにdecode、encodeを仕込まねばならず、スクリプトが読みにくいったらありゃしません。
漢字をふんだんに使って作られたテーブルなので、クエリ自体が成立しなくなりますし、その結果のODBCエラー文字列自体も化けて読み取れなくなります。
この点に手を入れると大変な割に得るものが少ないので、それはまた今度にして、いったんスクリプトのエンコーディングも従来どおり、シフトJISのまま変えずに行きます。
この状態でDBI化だけしても、なんとも半端だ、というのがおれの判断です。で、今回は、とにかく現状維持で!という方針にしたわけです。

ところで以前、Windows7に移植した際、AN-httpdがUACがらみの警告をやたらと発するようになりました。
そこで、httpdだけは、Apache24にしようと思って準備しました。
 Apache Loungeで取得した、httpd-2.4.65-250724-Win64-VS17.zip。
 C:\Apache24に展開し、C:\Apache24\binにて、コマンドプロンプトで、httpd -k install でサービス登録する。

知人宅のAccessも、もしかしたら最新版になっておるやも知れず、その場合、32bit対応と64bit対応どちらでもいけるように準備して、訪問してきました。
最近はWindowsでは、Strawberry Perlしか使わないので、2つ準備してもっていきました。もちろん、それぞれに、Win32::ODBCモジュールをインストール済み。
 5.32.1.1-portable (32bit)
 5.40.2.1-portable (64bit)

いずれも、インストーラやネットワークアクセスなしに、ファイルコピーだけで動くように準備。
もちろん、我が家では、ちゃんと動いていたのですが……

■ mdbをNASに置くとどうしても、ApacheのCGIでだけ、ODBCがコケる

知人宅では、Access2003のまま当時のmdbが使われていたので、64bit対応は不要でした。
今までどおり新PCに、32bitODBCのシステムDSNを登録し、用意してきたApache2.4をコピーして動かして、簡単に移植が終わりました。

が、知人の方がおっしゃるには、古いPCとも共有したいと。
つまり、mdbを、新PCのローカルドライブに置かず、NASに置くと良さそうです。

で、置きなおしたわけですよ。
そしたら、これが、ドハマりになって、とうとう解決できませんでした。

とは言え、使えないと困るので、今までどおり、AN-httpdを使うようにしました、不本意ながら。
気づけば、太古のソフトAN-httpdでも、以前のようなじゃまなUACダイアログも出ないので、これで、実用上問題はないし、知人の方にとっては、何の問題もなし、オールOKなんです。

ただ……おれ個人がヒジョーに不本意でした。
いったいこれはなんなのでしょうか?

■ どうして思い通りにならんかったのかを調べてみる

ローカルとNASつまりネットワークドライブに、mdbをそれぞれ置いて、ODBCアクセスして挙動を比べます。
我が家はNASといっても自作のLinux sambaサーバがいっぱいありますんで、試してみたところ、一発で再現しました。
知人宅ではODBCエラー文言が英語で、我が家では日本語と言う違いはありましたが。事前準備したときは、ローカルファイルでしか、試してなかったですね。

Apache24で、該当のPerl(ODBCアクセス)を動かすと、ファイルが見つけられずODBC接続エラーで終わるんです。
AN-httpdだと問題ありません。ニクいことに、うまく行くんでゲスよ。
また、CGIといっても単純な検索ものもありますから、コマンドラインで動かせるんですが、ニクいことに(以下同)

Apache24のCGIで動かしたときだけ、ダメなんです。

■ これは実行時権限の問題だろうと最初は楽観していた

I:\など、mdbの置かれたネットワークドライブに、ドライブレターを設定して、ODBCにシステムDSNを登録して、ApacheでCGI実行します。

次に、念のため、ネットワークドライブ(I:\xxx.mdbとか)ではなく、UNC形式での指定も試しました。
Windows付属のODBC設定ツールでは、UNCで登録することができません。形式的なものかもしれませんが、いったん、任意のドライブレターを登録し、ドライブ指定で登録する必要があります。
おれもさっき知ったんですが、ODBCのDSNは登録しておかなくても、perlからの接続時にファイル名を指定してODBCアクセスできるんですね。
この方法は、DBI/DBDはもちろん、Win32::ODBCでも使えます。これなら、UNC形式でmdbファイル指定ができます。
知った時は、「おお、これが原因だ」と喜び、そのまま寝るほど嬉しかったですね。
そして次の日やりましたらですね、期待に反して、あいかわらず同じエラーなんでゲスよ。
もちろん言うまでもなく、単体実行、AN-httpdでの実行、まったく問題ありません。
Apache24だけです。

微妙にエラー文言が変わりましたね。

ユーザでも管理者でもない権限で動いているのか?
サービスだとそういうミスをしやすいので、わざと、ユーザ権限のcmd.exeで、

と動かして確認しています。
これで、ユーザ権限で動いてることにならんのですかな?
CGIだけ、apache本体のプロセスと権限が違う、のかもしれませんね。

切り分けのため、CGIのなかで、ネットワークドライブを見てみればいいんじゃないかと思いました。
単純なApache24にオマケでついてくるサンプル printenv.pl と同じ要領で、CGI実行時に net useで、問題のネットワークドライブが見えているか調べました。
これがねぇ、バッチリ! 見えてるんでゲスよ。

ただしApache24のCGIでは、環境変数USERNAMEが空になっていることも、同時に確認しました。
USERNAMEが空だとアクセスできない、ということがあるのかも知れません。が、対処方法がわからんのです。
ODBC接続時に渡せるユーザIDとパスワードは、そーゆー意味のものじゃないでしょ?
そもそも、ユーザーhotsumaが設定したネットワークドライブは、hotsumaのものであって、他のユーザーには見えない気がするんだが……見えているじゃん。hotsuma権限じゃん? でもアクセスできない、って何の罠よ?

もしかして、httpd.confに、CGI実行時のユーザ名を設定できるのかな? 方法ないのか?? と、ChatGPTにもさんざん尋ねたんですがね、どうも、歯切れ悪く変化球的な答えばかりなんでゲスよ。

そんなことは、とうにやっておるわけです。
木で鼻をくくったような、という形容をしたくなる答えですな。

もし解決したら続きを書きますが……なんか、権限ではなく、セキュリティ関連とか、別の要因の気がしてならないので、ご存じの方、トップページ右上のボタンから投稿いただけると、おれが喜びます。