用C語言操作LDAP伺服器

來源:互聯網
上載者:User

   畢竟用PHP操作LDAP有局限性,因為當我們用產生認證的函數產生認證以後不可能再用PHP去給LDAP增加條目,所以最近研究了一下C語言操作LDAP,希望能對大家有點借鑒意義,有錯誤的地方還請原諒。至於如何安裝,運行和測試LDAP伺服器請看http://www.infosecurity.org.cn/forum/read.php?fid=12&tid=47&fpage=1
畢竟用PHP操作LDAP有局限性,因為當我們用產生認證的函數產生認證以後不可能再用PHP去給LDAP增加條目,所以最近研究了一下C語言操作LDAP,希望能對大家有點借鑒意義,有錯誤的地方還請原諒。至於如何安裝,運行和測試LDAP伺服器請看http://www.infosecurity.org.cn/forum/read.php?fid=12&tid=47&fpage=1

一 初始化LDAP庫
#include
#include
ld=ldap_init(ldap_host,LDAP_PORT)
假如沒有進行連接埠修改的話,用預設的LDAP_PORT就可以了,在ldap.h中定義為389

二 綁定LDAP伺服器
if(ldap_bind_s(ld,user_dn,user_pw,authmethod)!=LDAP_SUCCESS)
authmethod是使用的驗證方法,一般為LDAP_AUTH_SIMPLE,至於user_dn,user_pw就是使用者和密碼拉
可以使用ldap_unbind_s(LDAP *ld)來關閉綁定。

三 執行查詢
ldap_search_s(LDAP ld,char *base_dn,int scope ,char *filter ,char *attrs_reqired[],int attributesonly,LDAPMessage **result)
base_dn是指向查詢開始處對象的指標,它可以作為數的頂端,或者某一個低的點
scope有三個,為
LDAP_SCOPE_BASE,只對基點dn指定的對象進行搜尋
LDAP_SCOPE_ONELEVEL,可以搜尋處理基點DN指向對象以及樹中低於基點對象一級的所有對象
LDAP_SCOPE_SUBTREE,可以搜尋樹中該對象及以下的所有對象
Filter是過濾器,這裡有詳細的解釋http://www.infosecurity.org.cn/forum/read.php?fid=12&tid=49&fpage=1
Attrs_required是一個應該返回的NULL的屬性終止數組,可以只返回幾個屬性(如就DN和UID),指定NULL時將返回所有屬性
Attributesonly設定為1,只返回屬性的類型,通常設定為0,返回屬性類型和值。
成功返回LDAP_SUCCESS,否則返回出錯代碼。
例子:ldap_search_s(ld,base_dn,LDAP_SCOPE_SUBTREE,NULL,NULL,0,&ldap_message_set)
稍後必須釋放LDAPMessage **result,int ldap_msgfree(LDAPMessage *msg)
查詢過後,我們就需要得到我們具體的感興趣的東西
ldap_count_entries(ld,ldap_message_set)擷取搜尋得到的條目個數
ldap_first_entry(ld,ldap_message_set)擷取第一條
ldap_next_entry(ld,ldap_one_message);擷取下一條
ldap_first_attribute(ld,ldap_one_message,&ber_element_ptr);擷取第一條目的屬性
values= ldap_get_values(ld,ldap_one_message,attribute)擷取該屬性的值
ldap_value_free(values);
ldap_next_attribute(ld,ldap_one_message,ber_element_ptr);擷取下一屬性
可能看這麼多函數有點眼花,那我們來看個例子:
res=ldap_search_s(ld,base_dn,LDAP_SCOPE_SUBTREE,NULL,NULL,0,&ldap_message_set);
if(res!=LDAP_SUCCESS)
  {
  ldap_perror(ld,"Failure of ldap_search_s");
  exit(0);
  }

printf("There were %d objects found/n",ldap_count_entries(ld,ldap_message_set));
//擷取第一個條目
ldap_one_message=ldap_first_entry(ld,ldap_message_set);
while(ldap_one_message)
  {
  char *dn_str;
  //擷取條目的DN
  dn_str=ldap_get_dn(ld,ldap_one_message);
  printf("Found dn %s/n",dn_str);
  free(dn_str);
  //擷取條目的屬性
  attribute=ldap_first_attribute(ld,ldap_one_message,&ber_element_ptr);
  //擷取每個屬性的具體值
  while(attribute!=NULL)
    {
    if((values=ldap_get_values(ld,ldap_one_message,attribute))!=NULL)
    {
    for(i=0;values!=NULL;i++)
      {
        printf("%s:%s/n",attribute,values);
      }
    ldap_value_free(values);
    }
    //繼續下一屬性
    attribute=ldap_next_attribute(ld,ldap_one_message,ber_element_ptr);
    }
  //繼續下一條目
  ldap_one_message=ldap_next_entry(ld,ldap_one_message);
  printf("/n");
  }
  //釋放查詢資訊
(void)ldap_msgfree(ldap_message_set);
由上面的例子可以清楚的看出,可以查詢出所有的搜尋搜尋結果的屬性以及屬性值

四:增加條目
增加條目需要乾的事情就是構造一個LDAPMod結構,它包括對象單個屬性的構造塊
typedef struct ldapmod
{
int mod_op;
char *mod_type;
union
{
  char **modv_strvals;
  struct berval **modv_bvals;
}mod_vals;
struct ldapmod *mod_next;
}LDAPMod;
#define mod_values mod_vals,modv_strvals
#define mod_bvalues mod_vals.modv_bvals
可能你看起來很複雜,那我給你看個例子你就能找到中間的規律拉。
1,   添加一個國家的條目LDAPMod
char *c_vals[]={"cn",NULL};
LDAPMod c_attribute;
c_attribute.mod_op=LDAP_MOD_ADD;
c_attribute.mod_type="c";
c_attribute.mod_values=c_vals;

2,   你是不是覺得太簡單,那我們來個麻煩點的,認證的LDAPMod
struct berval cert_berval;
struct berval *cert_values[2];
char *cert_data;
FILE *fp;
struct stat st;
LDAPMod cert_attribute;
if ( stat( "guest.der", &st ) != 0 ) {
perror( "stat" );
return( 1 );
}
if ( ( fp = fopen( "guest.der", "rb" ) ) == NULL ) {
  perror( "fopen" );
  return( 1 );
}
if ( ( ( cert_data = ( char * )malloc( st.st_size ) ) == NULL ) ││
  ( fread ( cert_data, st.st_size, 1, fp ) != 1 ) ) {
  perror( cert_data ? "fread" : "malloc" );
  return( 1 );
}
fclose( fp );
cert_attribute.mod_op = LDAP_MOD_BVALUES;
cert_attribute.mod_type = "userCertificate;binary";
cert_berval.bv_len = st.st_size;
cert_berval.bv_val = cert_data;
cert_values[0] = &cert_berval;
cert_values[1] = NULL;
cert_attribute.mod_values =cert_values;
我們看完這兩個例子那你看出規律了吧,為非是把LDAPMod中的幾個變數賦值而已
下面我們把這些值給LDAP添加進去
char *objectClass_vals[]={"guestcertificate",NULL}; guestcertificate是我定義的objectClass
objectClass_attribute.mod_op=LDAP_MOD_ADD;
objectClass_attribute.mod_type="objectClass";
objectClass_attribute.mod_values=objectClass_vals;
new_dn="c=cn,dc=sage,dc=com";
LDAPMod *modst[4];
modst[0]=&c_attribute;
modst[1]=&objectClass_attribute;
modst[2]=NULL;
if(ldap_add_s(ld,new_dn,modst)!=LDAP_SUCCESS)
現在new_dn就添加好了,呵呵,是不是很簡單。

至於修改條目ldap_mod_s(LDAP *ld,char *new_dn,LDAPMOD *mods[])
刪除條目 ldap_delete_s(LDAP *ld,char *dn_to_delete)應該沒問題拉。

附件裡有我寫的一個往LDAP伺服器中添加認證的函數,寫的很亂,不太好意思。用C語言來操作LDAP最好就是添加條目了,可以從CISOCA中提煉一下,編寫一個只需要使用者輸入資訊就可以產生認證的函數,然後將產生的認證直接發往LDAP伺服器就可以了。我建議其實查詢的話就用PHP去查詢LDAP,因為查詢出來要顯示在瀏覽器上的,並且需要提供給使用者下載,用CGI去編介面那就太。。。。PHP還方便點。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.