Symfoware

Symfowareについての考察blog

Firebird embedded 2.5.2で接続した時のアクセス権メモ

Firebirdサーバーをインストールしたり、embedded版を触ってみたりしました。

FreeBSD 10.0にFirebird 2.5.2をインストールする(pkg install使用)
Firebird embeddedにJava1.7 + Jaybird + Ubuntuで接続する
WindowsでFirebird embeddedにJava1.7 + Jaybirdから接続する

良い機会なので、embedded版で接続した時のアクセス権について調べてみました。



環境



現在の手持ちの環境は、

FreeBSD + Firebird Server
Ubuntu + Firebird embedded
Windows + Firebird embedded

の3つです。

「FreeBSD」でデータベースファイルを作成して、そのファイルを他の環境で使ってみます。




データベースの作成(FreeBSD)



FreeBSDで、データベースファイルの作成を行います。
合わせて、「freebsd」というテーブルを作成してデータを入れておきました。

isql-fbで作業します。


# isql-fb
Use CONNECT or CREATE DATABASE to specify a database

SQL> create database '/usr/local/firebird/test.fdb'
CON> user 'sysdba'
CON> password 'masterkey'
CON> default character set utf8;
SQL> commit;

SQL> connect '/usr/local/firebird/test.fdb'
CON> user 'sysdba'
CON> password 'masterkey';
Database: '/usr/local/firebird/test.fdb', User: sysdba

SQL> create table freebsd (id int, name varchar(100));
SQL> commit;

SQL> insert into freebsd (id,name) values (1, 'freebsd');
SQL> commit;

SQL> quit;




出来上がったtest.fdbをUbuntuにコピーしました。






Ubuntu embeddedからの操作



Ubuntuにコピーしたtest.fdbに接続し、テーブルを検索してみます。


  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.ResultSet;
  4. import java.sql.Statement;
  5. public class FBEmbedded {
  6.     
  7.     public static void main(String[] args) throws Exception {
  8.         
  9.         String url = "jdbc:firebirdsql:embedded:/home/baranche/test.fdb?encoding=UTF8";
  10.         
  11.         try (Connection con = DriverManager.getConnection(url);
  12.                 Statement stmt = con.createStatement()) {
  13.                         
  14.             // データを検索
  15.             ResultSet rs = stmt.executeQuery("select * from freebsd");
  16.             
  17.             while(rs.next()) {
  18.                 System.out.println(rs.getString("name"));
  19.             }
  20.         }
  21.     }
  22. }





実行すると、こんなエラーが発生しました。


Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544352.
no permission for read/select access to TABLE FREEBSD
    at org.firebirdsql.jdbc.AbstractStatement.executeQuery(AbstractStatement.java:228)
    at sample.FBEmbedded.main(FBEmbedded.java:18)
Caused by: org.firebirdsql.gds.GDSException: no permission for read/select access to TABLE FREEBSD
    at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_dsql_prepare(Native Method)
    at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscDsqlPrepare(BaseGDSImpl.java:576)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.firebirdsql.gds.impl.jni.GDSSynchronizationPolicy$AbstractSynchronizationPolicy.invoke(GDSSynchronizationPolicy.java:119)
    at com.sun.proxy.$Proxy0.iscDsqlPrepare(Unknown Source)
    at org.firebirdsql.gds.impl.GDSHelper.prepareStatement(GDSHelper.java:190)
    at org.firebirdsql.jdbc.AbstractStatement.prepareFixedStatement(AbstractStatement.java:1441)
    at org.firebirdsql.jdbc.AbstractStatement.internalExecute(AbstractStatement.java:1423)
    at org.firebirdsql.jdbc.AbstractStatement.executeQuery(AbstractStatement.java:219)
    ... 1 more




embeddedで接続するときは、IDとパスワードは不要なはずです。
Serverで作成したデータベースに接続するときには必要なのかと思い、
ユーザー名:SYSDBA、パスワード:masterkeyを指定して接続しようとするとこんなエラー。


Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544653.
cannot attach to password database
    at org.firebirdsql.jdbc.FBDataSource.getConnection(FBDataSource.java:123)
    at org.firebirdsql.jdbc.AbstractDriver.connect(AbstractDriver.java:126)
    at java.sql.DriverManager.getConnection(DriverManager.java:579)
    at java.sql.DriverManager.getConnection(DriverManager.java:221)
    at sample.FBEmbedded.main(FBEmbedded.java:14)
Caused by: org.firebirdsql.gds.GDSException: cannot attach to password database
    at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_attach_database(Native Method)
    at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscAttachDatabase(BaseGDSImpl.java:160)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.firebirdsql.gds.impl.jni.GDSSynchronizationPolicy$AbstractSynchronizationPolicy.invoke(GDSSynchronizationPolicy.java:119)
    at com.sun.proxy.$Proxy0.iscAttachDatabase(Unknown Source)
    at org.firebirdsql.jca.FBManagedConnection.<init>(FBManagedConnection.java:105)
    at org.firebirdsql.jca.FBManagedConnectionFactory.createManagedConnection(FBManagedConnectionFactory.java:490)
    at org.firebirdsql.jca.FBStandAloneConnectionManager.allocateConnection(FBStandAloneConnectionManager.java:69)
    at org.firebirdsql.jdbc.FBDataSource.getConnection(FBDataSource.java:120)
    ... 4 more




パスワードデータベースに接続できないとのこと。

調べてみると、こんなページを見つけました。
no permission for read/select access to table RDB$XXXX by user SYSDBA

なるほど、作成したテーブルに権限をつければいいのか。

FreeBSDに戻って、作成したテーブルにPUBLICなアクセス権を付与します。


SQL> GRANT ALL ON freebsd TO PUBLIC;
SQL> commit;




test.fdbファイルをUbuntuに再度コピーして、以下のプログラムを実行します。


  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.ResultSet;
  4. import java.sql.Statement;
  5. public class FBEmbedded {
  6.     
  7.     public static void main(String[] args) throws Exception {
  8.         
  9.         String url = "jdbc:firebirdsql:embedded:/home/baranche/test.fdb?encoding=UTF8";
  10.         
  11.         try (Connection con = DriverManager.getConnection(url);
  12.                 Statement stmt = con.createStatement()) {
  13.             // データを登録
  14.             stmt.execute("insert into freebsd(id, name) values (2, 'from ubuntu')");
  15.             
  16.             // データを検索
  17.             ResultSet rs = stmt.executeQuery("select * from freebsd");
  18.             
  19.             while(rs.next()) {
  20.                 System.out.println(rs.getString("name"));
  21.             }
  22.             
  23.             // テーブルを作成
  24.             stmt.execute("create table ubuntu(id int, name varchar(100))");
  25.             
  26.             // 作成したテーブルにデータ登録
  27.             stmt.execute("insert into ubuntu(id, name) values (1, 'from ubuntu')");
  28.             
  29.             // データを検索
  30.             rs = stmt.executeQuery("select * from ubuntu");
  31.             
  32.             while(rs.next()) {
  33.                 System.out.println(rs.getString("name"));
  34.             }
  35.             
  36.         }
  37.     }
  38. }




ちゃんと登録、検索が行えました。
また、新規テーブルの作成が行えることも確認出来ました。






Windows embeddedからの操作



Ubuntuでデータの登録やテーブルの作成を行ったtest.fdbファイルを
Windowsにコピーします。

こんなプログラムを作成して実行してみました。



  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.ResultSet;
  4. import java.sql.Statement;
  5. public class Sample {
  6.     
  7.     public static void main(String... args) throws Exception {
  8.         String url = "jdbc:firebirdsql:embedded:C:\\Develop\\fbemb\\test.fdb?encoding=UTF8";
  9.         
  10.         try (Connection con = DriverManager.getConnection(url);
  11.                 Statement stmt = con.createStatement()) {
  12.             
  13.         
  14.         // FreeBSDで作成したテーブルにデータを登録
  15.         stmt.execute("insert into freebsd(id, name) values (3, 'from windows')");
  16.         
  17.         // FreeBSDで作成したテーブルのデータを検索
  18.         ResultSet rs = stmt.executeQuery("select * from freebsd");
  19.         
  20.         while(rs.next()) {
  21.             System.out.println(rs.getString("name"));
  22.         }
  23.         
  24.         
  25.         // Ubuntuで作成したテーブルにデータを登録
  26.         stmt.execute("insert into ubuntu(id, name) values (2, 'from windows')");
  27.         
  28.         // Ubuntuで作成したテーブルのデータを検索
  29.         rs = stmt.executeQuery("select * from ubuntu");
  30.         
  31.         while(rs.next()) {
  32.             System.out.println(rs.getString("name"));
  33.         }
  34.         
  35.         }
  36.     }
  37.     
  38. }





実行してみると、FreeBSDで作成したテーブルには
データの追加、検索が行えますが、
Ubuntuで作成したテーブルへのアクセスでエラーになります。


from freebsd
from windows
from ubuntu
Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544352.
no permission for insert/write access to TABLE UBUNTU
        at org.firebirdsql.jdbc.AbstractStatement.execute(AbstractStatement.java:869)
        at Sample.main(Sample.java:27)
Caused by: org.firebirdsql.gds.GDSException: no permission for insert/write access to TABLE UBUNTU
        at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_dsql_prepare(Native Method)
        at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscDsqlPrepare(BaseGDSImpl.java:576)
        at org.firebirdsql.gds.impl.GDSHelper.prepareStatement(GDSHelper.java:190)
        at org.firebirdsql.jdbc.AbstractStatement.prepareFixedStatement(Abstract
Statement.java:1441)
        at org.firebirdsql.jdbc.AbstractStatement.internalExecute(AbstractStatement.java:1423)
        at org.firebirdsql.jdbc.AbstractStatement.execute(AbstractStatement.java:867)
        ... 1 more





embeddedで接続して作成したテーブルは、他の端末のembedded接続でも
操作できるだろと思っていたのですが、そうではない様子。

Ubuntuで作成したテーブルにアクセス権を付与します。


  1. package sample;
  2. import java.sql.Connection;
  3. import java.sql.DriverManager;
  4. import java.sql.ResultSet;
  5. import java.sql.Statement;
  6. public class FBEmbedded {
  7.     
  8.     public static void main(String[] args) throws Exception {
  9.         
  10.         String url = "jdbc:firebirdsql:embedded:/home/baranche/test.fdb?encoding=UTF8";
  11.         
  12.         try (Connection con = DriverManager.getConnection(url);
  13.                 Statement stmt = con.createStatement()) {
  14.             
  15.             // アクセス権付与
  16.             stmt.execute("GRANT ALL ON ubuntu TO PUBLIC");
  17.             
  18.         }
  19.     }
  20. }




改めてWindowsで実行すると、ちゃんとubuntuテーブルに対しても
データの登録、検索が行えました。






スキーマの変更



再びUbuntuに戻ります。
今度はデータの登録、検索ではなくテーブルに対して列の追加を行なってみます。


  1. import java.sql.Connection;
  2. import java.sql.DriverManager;
  3. import java.sql.Statement;
  4. public class FBEmbedded {
  5.     
  6.     public static void main(String[] args) throws Exception {
  7.         
  8.         String url = "jdbc:firebirdsql:embedded:/home/baranche/test.fdb?encoding=UTF8";
  9.         
  10.         try (Connection con = DriverManager.getConnection(url);
  11.                 Statement stmt = con.createStatement()) {
  12.             
  13.             // FreeBSDで作成したテーブルに列追加
  14.             stmt.execute("ALTER TABLE freebsd ADD ubuntu_col VARCHAR(25)");
  15.         }
  16.     }
  17. }




こんなエラーが発生しました。


Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544351. unsuccessful metadata update
can't format message 8:29 -- message file /opt/firebird/firebird.msg not found
null
no permission for control access to TABLE FREEBSD
    at org.firebirdsql.jdbc.AbstractStatement.execute(AbstractStatement.java:869)
    at sample.FBEmbedded.main(FBEmbedded.java:17)
Caused by: org.firebirdsql.gds.GDSException: unsuccessful metadata update
can't format message 8:29 -- message file /opt/firebird/firebird.msg not found
null
no permission for control access to TABLE FREEBSD
    at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_dsql_execute2(Native Method)
    at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscDsqlExecute2(BaseGDSImpl.java:447)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.firebirdsql.gds.impl.jni.GDSSynchronizationPolicy$AbstractSynchronizationPolicy.invoke(GDSSynchronizationPolicy.java:119)
    at com.sun.proxy.$Proxy0.iscDsqlExecute2(Unknown Source)
    at org.firebirdsql.gds.impl.GDSHelper.executeStatement(GDSHelper.java:227)
    at org.firebirdsql.jdbc.AbstractStatement.internalExecute(AbstractStatement.java:1424)
    at org.firebirdsql.jdbc.AbstractStatement.execute(AbstractStatement.java:867)
    ... 1 more





ここがヒントになりました。
Alter Table Of Other User in Firebird


A table can be altered by its creator, the SYSDBA user,
and any users with operating system superuser privileges.




ひょっとして、rootになって実行すればいいのでは?
こんなコマンドで試してみました。


$ sudo -s
# cd workspace/fbsample/
# export LD_LIBRARY_PATH=/home/baranche/workspace/fbsample/embed
# java -cp .:./bin:./lib/jaybird-full-2.2.4.jar -Djava.library.path=/home/baranche/workspace/fbsample/lib sample.FBEmbedded




エラー無しで処理終了。
これでFreeBSDで作成したテーブルにUbuntu + embeddedな接続から
カラムの追加が行えました。



でも、rootでfdbファイルに接続した後、通常ユーザーで接続しようとすると、
こんなエラーになります。


Exception in thread "main" org.firebirdsql.jdbc.FBSQLException: GDS Exception. 335544373.
operating system directive open failed
null
    at org.firebirdsql.jdbc.FBDataSource.getConnection(FBDataSource.java:123)
    at org.firebirdsql.jdbc.AbstractDriver.connect(AbstractDriver.java:126)
    at java.sql.DriverManager.getConnection(DriverManager.java:579)
    at java.sql.DriverManager.getConnection(DriverManager.java:243)
    at sample.FBEmbedded.main(FBEmbedded.java:14)
Caused by: org.firebirdsql.gds.GDSException: operating system directive open failed
null
    at org.firebirdsql.gds.impl.jni.JniGDSImpl.native_isc_attach_database(Native Method)
    at org.firebirdsql.gds.impl.jni.BaseGDSImpl.iscAttachDatabase(BaseGDSImpl.java:160)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.firebirdsql.gds.impl.jni.GDSSynchronizationPolicy$AbstractSynchronizationPolicy.invoke(GDSSynchronizationPolicy.java:119)
    at com.sun.proxy.$Proxy0.iscAttachDatabase(Unknown Source)
    at org.firebirdsql.jca.FBManagedConnection.<init>(FBManagedConnection.java:105)
    at org.firebirdsql.jca.FBManagedConnectionFactory.createManagedConnection(FBManagedConnectionFactory.java:490)
    at org.firebirdsql.jca.FBStandAloneConnectionManager.allocateConnection(FBStandAloneConnectionManager.java:69)
    at org.firebirdsql.jdbc.FBDataSource.getConnection(FBDataSource.java:120)
    ... 4 more





test.fdbファイルのアクセス権が変わった?と思ったのですが変化なし。

随分ハマったのですが、embeddedで接続した時どうやら、ロックファイルが作成されるようです。
Operating System Directive Open failed -- Permission denied

調べてみると、
「/tmp/firebird/fb_init」
というそれらしいファイルがありました。


$ sudo rm -fr /tmp/firebird/fb_init



としてファイルを削除すると、再び通常ユーザーでのアクセスが可能になりました。






Windowsでの動作



WindowsではAdministrator権限で実行すればOKと思ったのですがエラーになります。


no permission for control access to TABLE FREEBSD




改めてこちらを見てみます。
Alter Table Of Other User in Firebird

「RDB$ADMIN」というキーワードーが出てきました。


Security Hardening

No SYSDBA Auto-mapping (Windows)の項目を見てみると、


ALTER ROLE RDB$ADMIN SET AUTO ADMIN MAPPING



を実行すれば良さそうです。


FreeBSDに戻り、クエリを実行します。


SQL> ALTER ROLE RDB$ADMIN DROP AUTO ADMIN MAPPING;
SQL> commit;




FreeBSDにあるtest.fdbファイルをWindowsにコピーしてプログラムを
再度実行してみたのですがやはりエラーになります。

なにかオペレーションが足りないんだと思いますが、解決できませんでした。






まとめ



Firebird Serverで作成したテーブルをEmbeddedで読み書きしたい時は、


GRANT ALL ON [テーブル名] TO PUBLIC



を作成元で忘れず実行しておく。


スキーマの変更はrootユーザーで実行する。
その時、tmpにロックファイルがroot権限で作成されるので
rootユーザーでアクセス後は忘れず権限を戻すかロックファイル自体を削除する。
関連記事

テーマ:データベース - ジャンル:コンピュータ

  1. 2014/03/06(木) 23:18:04|
  2. Firebird
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<Firebird 2.5.2にPythonから接続する(fdb使用) | ホーム | WindowsでFirebird embeddedにJava1.7 + Jaybirdから接続する>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1314-43d1fc26
この記事にトラックバックする(FC2ブログユーザー)