Arsip Bulanan: September 2008

Tutorial Membuat Database MySQL dgn DBDesigner

Iklan

protect/un-protect data FB/IB dari “gangguan” SYSDBA ();

Ada kalanya kita sebagai developer suatu aplikasi database ingin data-nya relatif aman dari “gangguan luar”, supaya data tetap terpelihara utuh . Saya katakan relatif karena tentunya bila si “pengganggu” tsb punya akses ke physical db maka bisa saja dianya melakukan gangguan thp file tsb ( misalnya menghapus file). Cara yg umum dilakukan developer untuk memngontrol akses de db adalah dengan mengatur akses user ( yg user name-nya sdh diatur sebelumnya ) ke tabel-tabel tertentu , dengan menset akses baca/tulis/insert/modify dll. Cara ini bisa di-bypass dengan mudah bilamana ada user yg bisa login dengan SYSDBA password , bahkan bilamana password SYSDBA-nya dirubah, bisa saja user tsb menggantikan security.fdb ( tempat password SYSDBA diletakkan) dengan “fresh” security.fdb yg didapatkan dari instalasi baru Firebird ( atau membawa file FDB/GDB tsb ke server yg SYSDBA accountnya dikenal – dan mengopreknya disana).

cara lain yg sedikit lebih sulit ditembus adalah dengan meng-create ROLE SYSDBA di db file tsb , sehingga ketika user mencoba login dengan SYSDBA account, akan menimbulkan error krn SYSDBA-nya dupilkate ( sdh ada di role ). Contoh produk lokal yg menggunakan proteksi ini adalah ACCURATE ( applikasi accounting yg di-develop dgn Delphi) , versi trialnya.

Cara proteksi semacam ini disinggung pada artikel berikut :
http://ftp.ibphoenix.com/main.nfs?a=ibphoenix&s=1123605099:169734&page=ibp_file_meta_security
namun dlm artikel tsb tidak dibahas cara melakukannya.

meng-create ROLE SYSDBA pada firebird adalah dengan syntak:
‘create role SYSDBA’

namun bilamana ini dilakukan maka akan error sebab SYSDBA sdh terdaftar sebagai user, sehingga satu-satunya cara adalah dengan login di firebird yg super-usernya bukanlah SYSDBA.

Ada 2 cara melakukannya:
1. Membangun kembali firebird dari source ( bisa di-download dari sourceforge.net ) dimana

source-nya sdh dirubah dengan super-user name bukan lagi SYSDBA.
2. Login lewat standar Firebird installation ( super user=SYSDBA / password=masterkey ), dan dilakukan lewat kode Delphi.

cara yg no-2 yg akan ditunjukkan dalam artikel ini.

I. Memprotect data.

Triknya adalah dengan memanipulasi username SYSDBA di security.fdb ( isc.gdb pd interbase ) dan dengan username yg sdh dimanipulasi ini , konek ke target db.

Langkahnya secara garis besar sbb:
1. Penting : backup / copy dulu security.fdb , klo-klo ntar ada masalah.
3. Bikin koneksi ke security.fdb ( pake IBX : TIBDatabase & TIBTransaction)
2. Bikin SQL yg meng-update user name SYSDBA ke nama laen ( yg akan sbg owner dari role SYSDBA di target db); contoh “TEMP_DBA”
3. Open koneksi ke security.fdb tsb dan exec SQL query.
4. penting : biarkan koneksi ke security Db tetap open.
5. Commit transaction ( shg SYSDBA tdk akan dikenali lagi bilamana user laen akan login).
6. Bikin koneksi baru lagi khusus utk target db.
7. Untuk koneksi ini tentunya nama user = “TEMP_DBA” , password=masterkey
8. Open db ke target db ini
9. Bikin SQL utk membuat/create role SYSDBA di target db
10. Commit transaction – bikin permanen di DB
11. Close connection ke target db.
12. di security db , bikin SQL untuk mengembalikan user name dari TEMP_DBA ke SYSDBA.
13 EXec SQL tsb dan commit.
14. Close semua koneksi.

contoh potongan kodenya sbb:
( contoh ini menggunakan lokal server – server dan prog dlm kompie yg sama)

uses IBSQL, IBDatabase,IBQuery;

function  BikinRole_SYSDBA(namafile,RoleOwner:string):Boolean;
var
IBDb: TIBDatabase;
IBTrans: TIBTransaction;
IBSQL: TIBSQL;
begin
Result:=False;
IBTrans:=TIBTransaction.Create(nil);
IBDb:= TIBDatabase.Create(nil);
with IBDb do
begin
DefaultTransaction:=IBTrans;
DatabaseName:=namafile;
LoginPrompt:=False;
Params.Clear;
Params.Add(‘user_name=’+RoleOwner);  // modified admin name
Params.Add(‘password=masterkey’); // password
end;
IBSQL:= TIBSQL.Create(nil);
with IBSQL do
begin
Transaction:=IBTrans;
Database:=IBDb;
SQL.Clear;
SQL.Add(‘create ROLE SYSDBA’);
end;

try  // buka security db dengan modified admin account
IBDb.Open;
except
ShowMessage(‘Error login ke target DB’);
IBTrans.Free;
IBDb.Free;
exit;
end;

// create role SYSDBA di target DB
try
IBTrans.StartTransaction;
IBSQL.ExecQuery;
IBTrans.Commit;
except
IBTrans.Rollback;
ShowMessage(‘role SYSDBA sdh ada di target DB’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

// release resources
IBDb.Close;
IBSQL.Free;
IBDb.Free;
IBTrans.Free;
Result:=True;
end;

procedure ProtectDatabase(namafile,RoleOwner:string);
var
IBDb: TIBDatabase;
IBTrans: TIBTransaction;
IBSQL: TIBSQL;
begin
IBTrans:=TIBTransaction.Create(nil);
IBDb:= TIBDatabase.Create(nil);
with IBDb do
begin
DefaultTransaction:=IBTrans;
DatabaseName:=’C:\\Program Files\\Firebird\\Firebird_1_5\\security.fdb’;
LoginPrompt:=False;
Params.Clear;
Params.Add(‘user_name=SYSDBA’);  // default admin name
Params.Add(‘password=masterkey’); // password
end;
IBSQL:= TIBSQL.Create(nil);
with IBSQL do
begin
Transaction:=IBTrans;
Database:=IBDb;
SQL.Clear;
// ganti admin ke RoleOwner
SQL.Add(‘update USERS set USER_NAME = ‘+QuotedStr(RoleOwner)
+ ‘ where USER_NAME = ‘+ QuotedStr(‘SYSDBA’));
end;

try  // buka security db dengan default admin/SYSDBA data
IBDb.Open;
except
ShowMessage(‘Nama Admin/password telah berubah dari default SYSDBA’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

// ExecSQL : ganti nama admin dari SYSDBA menjadi newAdminName
try
IBTrans.StartTransaction;
IBSQL.ExecQuery;
IBTrans.Commit;
except
ShowMessage(‘Ada error…. quiting’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

if BikinRole_SYSDBA(namafile,RoleOwner) then
ShowMessage(‘Berhasil : target DB bakalan tdk dpt lagi dibuka dengan SYSDBA’)
else
ShowMessage(‘Ada error….’);

IBSQL.SQL.Clear;
// kembalikan lagi admin ke SYSDBA
IBSQL.SQL.Add(‘update USERS set USER_NAME = ‘+QuotedStr(‘SYSDBA’)
+ ‘ where USER_NAME = ‘+ QuotedStr(RoleOwner));
try
IBTrans.StartTransaction;
IBSQL.ExecQuery;
IBTrans.Commit;
except
ShowMessage(‘Ada error…. quiting’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

//release resources
IBDb.Close;
IBSQL.Free;
IBDb.Free;
IBTrans.Free;
end;

contoh penggunaan:

procedure TForm1.Button2Click(Sender: TObject);
begin
ProtectDatabase(‘C:\\SAMPLE.GDB’,’TEMP_DBA’);
end;

II. Unlock db yg terproteksi

Caranya mirip dengan langkah nge-proteknya yakni:
1. Backup security.fdb
2. Bikin koneksi ke security.fdb
3. bikin SQL utk ngeganti SYSDBA ke nama laen ( mis TEMP_DBA ).
4. Exec SQL ini dan commit shg user berikutnya kan melihat new name ini.
5. Biarkan koneksi ke security.fdb ini tetap open.
5. Dengan new name ini ( TEMP_DBA ) , bikin koneksi baru ke target db.
6. setelah terkonek , query data system table tentang role ( tabel RDB$ROLES ), dan cari Owner dari role SYSDBA.
7. Setelah mendapatkan nama owner tsb , di security.fdb , ganti lagi nama user TEMP_DBA ke nama Owner tsb dan commit.
8. Konek lagi ke target db dengan nama user = nama owner dari role.
9. di koneksi baru ini, drop role SYSDBA dan commit.
10.kembali di koneksi security.fdb , bikin SQL baru yg mengganti nama user dari Owner tadi ke original (=SYSDBA).
11. Exec query dan commit, dan close.

contoh potongan kodenya sbb:
( make local connection ).

uses IBSQL, IBDatabase,IBQuery;

function  DropRole_SYSDBA(namafile,RoleOwner:string):Boolean;
var
IBDb: TIBDatabase;
IBTrans: TIBTransaction;
IBSQL: TIBSQL;
begin
Result:=False;
IBTrans:=TIBTransaction.Create(nil);
IBDb:= TIBDatabase.Create(nil);
with IBDb do
begin
DefaultTransaction:=IBTrans;
DatabaseName:=namafile;
LoginPrompt:=False;
Params.Clear;
Params.Add(‘user_name=’+RoleOwner);  // modified admin name ( Owner of SYSDBA role)
Params.Add(‘password=masterkey’); // password
end;
IBSQL:= TIBSQL.Create(nil);
with IBSQL do
begin
Transaction:=IBTrans;
Database:=IBDb;
SQL.Clear;
SQL.Add(‘drop ROLE SYSDBA’); // buang role ini
end;

try  // buka target db dengan admin = RoleOwner
IBDb.Open;
except
ShowMessage(‘Error login ke target DB’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

// execute SQL : buang role SYSDBA dari target DB
try
IBTrans.StartTransaction;
IBSQL.ExecQuery;
IBTrans.Commit;
except
ShowMessage(‘Ada error…. quiting’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

// release resources
IBDb.Close;
IBSQL.Free;
IBDb.Free;
IBTrans.Free;
Result:=True;
end;

function  Get_SYSDBA_RoleOwner(namafile,TempAdminName:string):string;
var
IBDb: TIBDatabase;
IBTrans: TIBTransaction;
IBQuery: TIBQuery;
begin
Result:=”;
IBTrans:=TIBTransaction.Create(nil);
IBDb:= TIBDatabase.Create(nil);
with IBDb do
begin
DefaultTransaction:=IBTrans;
DatabaseName:=namafile;
LoginPrompt:=False;
Params.Clear;
Params.Add(‘user_name=’+TempAdminName);  // modified admin name
Params.Add(‘password=masterkey’); // password
end;
IBQuery:= TIBQuery.Create(nil);
with IBQuery do
begin
Transaction:=IBTrans;
Database:=IBDb;
SQL.Clear;
// temukan Owner dari role ini
SQL.Add(‘select RDB$OWNER_NAME from RDB$ROLES where RDB$ROLE_NAME=’
+QuotedStr(‘SYSDBA’));
end;

try  // buka target db dengan temporary admin account
IBDb.Open;
except
ShowMessage(‘Error login ke target DB’);
IBTrans.Free;
IBDb.Free;
exit;
end;

try
IBTrans.StartTransaction;
IBQuery.Open ;
if IBQuery.Eof and IBQuery.Bof then
Result:=”
else
// nama dari Owner si role SYSDBA
Result:= Trim(IBQuery.Fields[0].AsString);
IBTrans.Commit;
except
ShowMessage(‘Ada error…. quiting’);
IBQuery.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

// release resources
IBDb.Close;
IBQuery.Free;
IBDb.Free;
IBTrans.Free;
end;

procedure UnProtectDatabase(namafile:string);
var
IBDb: TIBDatabase;
IBTrans: TIBTransaction;
IBSQL: TIBSQL;
RoleOwner,LastAdmin:string;
begin
IBTrans:=TIBTransaction.Create(nil);
IBDb:= TIBDatabase.Create(nil);
with IBDb do
begin
DefaultTransaction:=IBTrans;
DatabaseName:=’C:\\Program Files\\Firebird\\Firebird_1_5\\security.fdb’;
LoginPrompt:=False;
Params.Clear;
Params.Add(‘user_name=SYSDBA’);  // default admin name
Params.Add(‘password=masterkey’); // password
end;
IBSQL:= TIBSQL.Create(nil);
with IBSQL do
begin
Transaction:=IBTrans;
Database:=IBDb;
SQL.Clear;
SQL.Add(‘update USERS set USER_NAME = ‘
+ QuotedStr(‘TEMP_DBA’)+ ‘ where USER_NAME = ‘
+ QuotedStr(‘SYSDBA’));
end;

try  // buka security db dengan default admin/SYSDBA data
IBDb.Open;
except
ShowMessage(‘Nama Admin/password telah berubah dari default SYSDBA’);
IBTrans.Free;
IBDb.Free;
IBSQL.Free;
exit;
end;

// coba ganti nama admin dari SYSDBA menjadi newAdminName
try
IBTrans.StartTransaction;
IBSQL.ExecQuery;
IBTrans.Commit;
LastAdmin:=’TEMP_DBA’;
except
ShowMessage(‘Ada error…. quiting’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

// temukan nama owner role SYSDBA di target DB – login ke target DB dgn temporer account
RoleOwner:=Get_SYSDBA_RoleOwner(namafile,’TEMP_DBA’);
if RoleOwner<>” then
begin
ShowMessage(‘Owner dari SYSDBA role adalah :’+RoleOwner);
IBSQL.SQL.Clear;
// rubah security db admin ke RoleOwner spy role tsb bisa di-drop
IBSQL.SQL.Add(‘update USERS set USER_NAME = ‘
+ QuotedStr(RoleOwner)+ ‘ where USER_NAME = ‘
+ QuotedStr(‘TEMP_DBA’));
try
IBTrans.StartTransaction;
IBSQL.ExecQuery;
IBTrans.Commit;
LastAdmin:=RoleOwner;
except
ShowMessage(‘Ada error…. quiting’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

if DropRole_SYSDBA(namafile,RoleOwner)then
ShowMessage(‘Target DB bakalan bisa dibuka dgn admin SYSDBA’)
else
ShowMessage(‘Ada error’);
end
else
ShowMessage(‘Tdk ditemukan role SYSDBA di target DB’);

IBSQL.SQL.Clear;
IBSQL.SQL.Add(‘update USERS set USER_NAME = ‘
+ QuotedStr(‘SYSDBA’)+ ‘ where USER_NAME = ‘
+ QuotedStr(LastAdmin));
try  // kembalikan lagi admin ke SYSDBA
IBTrans.StartTransaction;
IBSQL.ExecQuery;
IBTrans.Commit;
except
ShowMessage(‘Ada error…. quiting’);
IBSQL.Free;
IBTrans.Free;
IBDb.Free;
exit;
end;

//release resources
IBDb.Close;
IBSQL.Free;
IBDb.Free;
IBTrans.Free;

end;

contoh pemakaian:

procedure TForm1.Button1Click(Sender: TObject);
begin
UnProtectDatabase(‘C:\\SAMPLE.GDB’);
end;

Merubah backgroung pada Form MDI Parent

Caranya yaitu dengan menggunakan intersepsi dari messages WM_ERASEBKGND, WM_VSCROLL dan
WM_HSCROLL dan dibawa pada penggambaran area oleh prosedur DrawImage atau procedure InValidateRect.
Pada procedure CreateWnd digunakan prosedur SetWindowLong untuk instalasi prosedur baru pada window.
Jangan lupa untuk menghilangkan baris :

Application.CreateForm(TForm2, Form2)

dari file proyek dan baris :

var Form2: TForm2

dari file unit2.pas

type
TForm1 = class(TForm)
//  …
private
{ Private declarations }
public
procedure ClientWndProc(var Message: TMessage);
procedure DrawImage;
{ Public declarations }
protected
procedure CreateWnd; override;
end;

var
Form1: TForm1;
NewClient, OldClient: TFarProc;
MyDC: hDC;

implementation

uses unit2;

{$R *.DFM}

procedure TForm1.CreateWnd;
begin
inherited CreateWnd;
NewClient:=MakeObjectInstance(ClientWndProc);
OldClient:=Pointer(GetWindowLong(ClientHandle, GWL_WNDPROC));
SetWindowLong(ClientHandle, GWL_WNDPROC, LongInt(NewClient));
end;

procedure TForm1.DrawImage;
{ Membuat tile image pada daerah form client }
var
i, j: Integer;
WndRect, ImageRect: TRect;
Rows, Cols: Integer;
begin
GetWindowRect(ClientHandle, WndRect);
ImageRect:=Image1.ClientRect;
Rows:=WndRect.Bottom div ImageRect.Bottom;
Cols:=WndRect.Right div ImageRect.Right;
with Image1 do
for i:=0 to Rows+1 do
for j:=0 to Cols+1  do
BitBlt(MyDC,j*Picture.Width,i*Picture.Height,Picture.Width,
Picture.Height,Picture.Bitmap.Canvas.Handle,0,0,SRCCOPY);
end;

procedure TForm1.ClientWndProc(var Message: TMessage);
begin
case Message.Msg of
WM_ERASEBKGND:
begin
CallWindowProc(
OldClient,
ClientHandle,
Message.Msg,
Message.wParam,
Message.lParam);
MyDC:=TWMEraseBkGnd(Message).DC;
DrawImage;
Message.Result:=1;
end;
WM_VSCROLL,WM_HSCROLL:
begin
Message.Result:=
CallWindowProc(
OldClient,
ClientHandle,
Message.Msg,
Message.wParam,
Message.lParam);
InvalidateRect(ClientHandle,nil,True);
end;
else
Message.Result:=
CallWindowProc(
OldClient,
ClientHandle,
Message.Msg,
Message.wParam,
Message.lParam);
end;
end;

Add animated cursors to your program

Animated cursors have become so popular since the good old days of Windows 3.0, now they are a built-in part of the Windows 95 and Windows NT operating systems. Here’s how you can use them in your Delphi program:

const
cnCursorID1 = 1;
begin
Screen.Cursors[ cnCursorID1 ] :=
LoadCursorFromFile(
‘c:\winnt\cursors\piano.ani’ );
Cursor := cnCursorID1;
end;

“c:\winnt\cursors\piano.ani” is of course the name of the animated cursor file and cnCursorID1 (defined as 1) is the index of your newly defined cursor. If you wanted to use more than one animated cursor, simply use a different index number — cnCursorID2 (or 2) for example.