现在的位置: 首页 > 综合 > 正文

用C语言操作LDAP服务器

2013年10月24日 ⁄ 综合 ⁄ 共 4310字 ⁄ 字号 评论关闭

毕竟用PHP操作LDAP有局限性,因为当我们用生成证书的函数生成证书以后不可能再用PHP去给LDAP增加条目,所以最近研究了一下C语言操作LDAP,希望能对大家有点借鉴意义,有错误的地方还请原谅。
  一 初始化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是过滤器。
  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)应该没问题拉。

抱歉!评论已关闭.