使用 ESQL/C 的 PAM 認證方法(轉)

post0發表於2007-08-11
使用 ESQL/C 的 PAM 認證方法(轉)[@more@]

簡介

認證是當使用者或應用程式連線到資料庫時驗證其身份的過程。賦予使用者特權的資料庫和伺服器首先對每個使用者進行正確的認證,這很重要。傳統上,Informix® 伺服器和客戶機只支援簡單的認證機制,即使用可信的主機或基於密碼檔案的認證。現在您有了更廣泛的認證選擇 — 使用可插入的認證模組(PAM)機制。ESQL/C 的版本 9.53.xC2(與 CSDK 2.82.xC2 一起提供的)開始支援這種新的認證機制。

對於可信的主機,資料庫根據連線請求的來源來假定是否可信。如果傳送請求的機器是可信的,那麼該機器上的使用者也是可信的。對於基於密碼檔案的認證,認證是以安裝資料庫伺服器的機器上的密碼和影子(shadow)檔案或者與網路資訊系統(Network Information System,NIS)的互動為基礎的。現有的這些機制的缺陷在於無法使用作業系統可能提供的增強認證。

對於 IBM Informix Dynamic Server® 中的 PAM 實現,所有新舊 ESQL/C 應用程式(透過實現少量更改和重新編譯較老的應用程式)現在都可以利用這個新的認證模組,從而改進了客戶機與資料庫伺服器通訊和認證的方式。PAM 機制的實現使使用者可以在伺服器的 sqlhosts 檔案中設定額外的標誌,以便讓使用者隨心所欲地使用外部認證。需要圍繞該認證服務來構建 ESQL/C 應用程式,以處理所有的詢問(challenge),並對這些認證詢問做出響應。

框架和受支援的平臺

為了使用新的 PAM 機制進行認證,首要需求就是您必須擁有最新的 ESQL/C 版本 — 與連線到 Informix Dynamic Server V9.40.UC2 的 CSDK2.81.xC2 一起提供的 9.53.xC2。如果客戶機或伺服器的版本比這些版本老,則無法使用 PAM 機制。稍後我將在本文中談論各種客戶機-伺服器相容性。

支援 PAM 認證方式背後的主要思想就是能夠使用增強的 OS 級別的認證。由於認證是在伺服器上進行的,因此 IBM Informix Dynamic Server 應該位於某個支援 PAM 的平臺上,這一點很重要。目前,AIX® 32 位、AIX 64 位、HP 32 位、HP 64 位、Solaris 32 位、Solaris 64 位和 Linux 都支援 PAM。如果您正在連線的伺服器位於任何其它作業系統上,那麼應用程式使用傳統的認證方式連線到該伺服器。

當然,因為認證是在伺服器端進行的,所以客戶機(ESQL/C 應用程式)可位於任何平臺上。只要註冊並編寫一個回撥函式來處理由伺服器丟擲的詢問,客戶機應用程式就與平臺無關了。

編寫支援 PAM 的 ESQL/C 應用程式

透過編寫 ESQL/C 應用程式使使用者可以由使用 PAM 的伺服器認證,最新 IBM Informix ESQL/C 和 IBM Informix Dynamic Server 的新使用者可以快速地使用這個功能,並使認證過程具有更高的可信性。PAM 允許資料庫和系統管理員以更大的靈活性並採用可插的模組化體系結構來設定支援 PAM 的應用程式的認證策略。這種認證方式使人們可以對認證過程進行更多的控制。

對於需要使用 PAM 機制的所有應用程式而言,首先需要編寫一個認證模組,該模組將在認證過程中“丟擲詢問”並使響應與詢問匹配。例如,如果您登入到某個系統,它通常會要求您輸入‘使用者名稱’,如果有必要,它還會提示您輸入‘密碼’。使用者名稱和密碼是由系統丟擲的非常簡單的詢問示例。利用 PAM,您可以更進一步,讓您的應用程式成功地與由該模組(為這樣的資料庫認證而編寫的)丟擲的更多詢問進行通訊,並對其作出響應。通常,詢問是預先準備好的要向每個使用者提出的問題,您必須正確回答它才允許您訪問資料庫。這些詢問的性質因使用者而異,這取決於如何編寫 PAM 模組。

對於要訪問這類支援 PAM 的 Informix Dynamic Server 的 ESQL/C 應用程式而言,應用程式對這類訪問的支援至關重要(正如我們將在下面的示例中所展示的那樣)。這稱為 PAM 服務。對於大多數平臺而言,PAM 服務模組駐留在 /usr/lib/security 目錄中。開發人員將需要編寫一個 PAM 服務模組,並將它放入 IBM Informix Dynamic Server 所在機器的 /usr/lib/security 目錄中。IBM Informix Dynamic Server 將裝入該庫(服務),並使用它來認證客戶機。

pam.conf 檔案建立服務、庫和模組之間的對映。典型的項看起來將如下面這樣:

login auth required /usr/lib/security/pam_unix.so.1

pam.conf 檔案中的這個項意味著對於“login”服務而言,PAM 庫“/usr/lib/libpam”需要使用 pam_unix.so 模組。

類似地,對於 IBM Informix Dynamic Server,要理解用於認證每個連線的 PAM 服務,必須在伺服器的 SQLHOSTS 檔案中新增一項。對於可以處理這種新認證模組的伺服器,其典型的 SQLHOSTS 檔案如下所示:

清單 1. 支援 PAM 的伺服器的 sqlhosts 樣本檔案

s=4,pam_serv=, pamauth=(challenge).

* — IBM Informix Server 的名稱(和 onconfig 檔案中出現的一樣)

* — 使用哪種服務:ontlitcp、onsoctcp 和 onipcshm 等

* — 伺服器所在機器的名稱

* — 客戶機和伺服器之間通訊所用的埠號

* pam_serv= — PAM 服務模組的名稱,該模組是由使用者編寫的,並放在 IBM Informix Dynamic Server 所在機器的 /usr/lib/security 目錄中。這是一個服務,編寫後放在 /usr/lib/security 中,它會丟擲詢問以對使用者進行認證。

* pamauth=(challenge) — 指定伺服器將使用詢問-響應機制來認證連線到該伺服器的所有客戶機。

一旦編寫 PAM 服務模組並將其儲存在 /usr/lib/security 目錄中,伺服器的 sqlhosts 檔案中就會設定一個標誌(pamauth=challenge),以表明伺服器要使用外部認證,並且伺服器將引入“challenge”方式,現在我們可以繼續編寫能夠處理伺服器所需外部認證的 ESQL/C 應用程式。典型的 PAM 服務模組由幾個拋向使用者的詢問構成,對使用者的認證是以對這些詢問的響應為基礎的。因此,我們需要擁有一個能夠處理這些詢問,並拋迴響應的 ESQL/C 應用程式。

我已經編寫了一個典型的樣本程式(pamdemo.ec),它是與最新的 ESQL/C 產品一起提供的。它說明了如何編寫 ESQL/C 應用程式以使用 PAM 服務。

樣本演示程式如下所示,其中帶底色的框中包含的幾行註釋是對程式的說明。該程式說明如何使用 ESQL/C 來與使用 PAM 的 IBM IDS 進行認證。

清單 2. pamdemo.ec

#include

#define PAM_PROMPT_ECHO_OFF 1 /*Echo off when getting response*/

#define PAM_PROMPT_ECHO_ON 2 /*Echo on when getting response*/

#define PAM_ERROR_MSG 3 /* Error Message */

#define PAM_TEXT_INFO 4 /* Textual Information */

#define PAM_MAX_MSG_SIZE 12 /* max size of each message */

這些定義通常位於支援 PAM 的系統的 /usr/include/security/pam_appl.h 檔案中。目前,只有 AIX 32/64 位、HP 32/64 位、Solaris 32/64 位和 Linux 支援這種 PAM 認證。如果伺服器打算使用 PAM 認證,那麼它必須安裝這其中的某個平臺上,這一點很重要。而客戶機(ESQL/C 應用程式)可以位於任何平臺/OS 上。當 PAM 服務返回每個訊息時,還會返回訊息型別。對於位於非 PAM 系統上的客戶機應用程式而言,必須象上面那樣顯式地定義這些定義。在確定應用程式所要採取的進一步行動時,這些返回型別訊息很重要。如果 ESQL/C 應用程式位於支援 PAM 的系統上(AIX 32/64 位、HP 32/64 位、Solaris 32/64 位和 Linux),透過包含如下所示的 /usr/lib/security/pam_appl.h 檔案,就可以定義這四個定義了:#define

EXEC SQL define FNAME_LEN 15;

EXEC SQL define LNAME_LEN 15;

int callback(char *challenge, char *response, int msg_style);

對於要使用 PAM 的任何 ESQL/C 應用程式而言,它必須包含回撥函式。首先必須註冊該回撥函式。下面,我們定義了這個回撥函式。我將更詳細地談論下面這個回撥函式。

int main()

{

EXEC SQL BEGIN DECLARE SECTION;

char fname[ FNAME_LEN + 1 ];

char lname[ LNAME_LEN + 1 ];

EXEC SQL END DECLARE SECTION;

int retval = 0;

/* First register the callback. This needs

* to be done before establishing the

* connection as done here.

*/

就象註釋說明的,必須註冊回撥函式。回撥函式的主要目的是在應用程式連線到支援 PAM 的 IBM IDS 伺服器時能夠處理由 PAM 服務丟擲的所有詢問。回撥函式必須能夠接受這些來自伺服器的詢問,並將它們傳送給使用者(可能是另一個應用程式或使用者介面),然後取回對那些詢問的響應,並將它們依次傳回伺服器以用 PAM 服務進行認證。

在首次建立與伺服器的連線之前必須註冊該函式。每當伺服器根據編寫的 PAM 模組丟擲詢問以便應用程式相應地作出響應時,ESQL/C 庫都會呼叫該回撥函式。

即使您正在透過單個應用程式連線幾個伺服器,其中一些能夠理解 PAM 模組而另外一些卻不能,您仍然需要向那些能夠理解 PAM 服務的伺服器註冊回撥函式。連線到非 PAM 伺服器時不會有任何問題,即使註冊了應用程式也是如此,因為在那些情形中決不會呼叫回撥函式。

printf("Starting PAM demo ");

EXEC SQL WHENEVER ERROR STOP;

retval = ifx_pam_callback(callback);

上面就是我們註冊回撥函式的地方。回撥函式的名稱是‘callback’。為了在每次 sqli 庫接收到來自伺服器的詢問時能夠呼叫該函式,註冊回撥函式是很重要的。以下是註冊回撥函式的出錯檢查:

if (retval == -1)

{

printf("Error in registering callback ");

return (-1);

}

else

{

printf( "Callback function registered. ");

EXEC SQL database stores_demo;

printf ("SQLCODE ON CONNECT = %d ", SQLCODE);

現在,當客戶機建立與伺服器的連線時,sqli 庫將呼叫已註冊的回撥函式。僅當正確註冊了回撥函式,並且當使用者能夠對 PAM 服務丟擲的詢問提供正確響應時,程式才會繼續。

程式的餘下部分是簡單的演示程式(與前面的 ESQL/C 一起提供的 demo1.ec 原本),這段程式的後面是回撥函式‘callback’。

EXEC SQL declare pamcursor cursor for

select fname, lname

into :fname, :lname

from customer

where lname < "C";

EXEC SQL open pamcursor;

for (;;)

{

EXEC SQL fetch pamcursor;

if (strncmp(SQLSTATE, "00", 2) != 0)

break;

printf("%s %s ",fname, lname);

}

if (strncmp(SQLSTATE, "02", 2) != 0)

printf("SQLSTATE after fetch is %s ", SQLSTATE);

EXEC SQL close pamcursor;

EXEC SQL free pamcursor;

EXEC SQL disconnect current;

printf(" PAM DEMO run completed successfully ");

}

}

/* The callback function which will

* provide responses to the challenges. */

這個回撥函式就是先前註冊的那個,它是在首次建立與支援 PAM 的 IBM Informix Dynamic Server 的連線之前註冊的。編寫該函式的方法有多種,這取決於使用者希望如何處理由支援 PAM 的伺服器丟擲的詢問。下面的程式碼顯示了一種非常簡單的方法。其中的回撥函式帶有三個引數,返回一個整數。根據訊息型別(msg_style),該函式(接著還有 ESQL/C 應用程式)確定需要提供給伺服器的響應種類。所有詢問都希望有響應。如果有出錯訊息,或者只是一個不需要響應的訊息,那麼就在提示符後顯示該訊息。

詢問被拋向使用者,並且期望獲得對詢問的響應,然後將其提供給使用者。

非詢問響應可以是幾種情形之一,例如“authentication successful”,這取決於 PAM 模組(服務)的編寫方式。

重申一次,每當建立與資料庫伺服器的新連線時,就呼叫該回撥函式,並且伺服器拋回一個要求更多資訊的詢問,而不是使用簡單的使用者名稱和密碼機制進行認證。

int callback(char *challenge, char *response,

int msg_style)

{

switch (msg_style){

case PAM_PROMPT_ECHO_OFF:

case PAM_PROMPT_ECHO_ON :

printf("%s: %d:",challenge, msg_style);

scanf("%s:",response);

break;

case PAM_ERROR_MSG:

case PAM_TEXT_INFO:

default:

printf("%s: %d ",challenge, msg_style);

}

return 0;

}

上述程式可在任何作業系統上編譯和執行,既可以與非 PAM 伺服器通訊,也可以與 PAM 伺服器通訊。僅當客戶機連線到支援 PAM 的伺服器時,回撥函式才開始起作用,並要求使用者輸入對由其正在連線的伺服器丟擲詢問的響應。

使用 PAM 模組的客戶機-伺服器相容性

PAM 認證功能的開發人員小心地避開了客戶機-伺服器相容性問題。使用者可以轉移到最新的 ESQL/C 客戶機(庫),而無需過分擔心 PAM,即使他們正在連線到最新的 IBM Informix Dynamic Server。遷移或升級到最新的 ESQL/C 版本並不意味著必須提供回撥函式,以及必須使用 PAM 功能來連線到伺服器。該功能是可選的,而且僅當應用程式連線的伺服器處於 PAM 方式時它才起作用。

此外,當您編寫新的應用程式時,使用者可以繼續使用較舊的伺服器認證方法。是否使用 PAM 認證方式完全由您自己選擇。請記住,同一個應用程式既可以與不具備 PAM 功能的伺服器通訊,也可以與具備 PAM 功能的伺服器通訊。要連線到這兩種伺服器,無需編寫不同的應用程式。

到目前為止,在客戶機-伺服器通訊方面尚未發現不相容性問題。

結束語

可插入的認證模組為資料庫管理員提供了更大的靈活性,並使他們能夠更好地控制用於 Informix Dynamic Server 資料庫的認證策略。為其它應用程式編寫的現有 PAM 模組可用於客戶機-伺服器認證,因而可以將一個公共認證用於各種應用程式,從而降低了維護成本。

過去,您可能需要為每類使用者提供單獨的認證方案,並且需要為每類使用者編寫一個程式。現在,PAM 允許 ESQL/C 應用程式開發人員專注於核心程式本身的功能,同時讓資料庫管理員以及先前編寫的 PAM 模組控制認證過程。這種可插入的靈活性確實是客戶機-伺服器認證的未來,而且事實上,也是需要認證的每個程式的未來。

相關資訊

可透過網際網路在幾個網站上獲得有關 PAM 的更多讀物和文件。其中值得一讀的幾篇文章有:

* http://java.sun.com/security/jaas/doc/pam.html/

*

*

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8225414/viewspace-945670/,如需轉載,請註明出處,否則將追究法律責任。

相關文章