LDAP报错:ldap_sasl_interactive_bind_s

如果报ldap_sasl_interactive_bind_s错误,且发现/etc/krb5.keytab不存在, 执行如下操作:

cp /etc/openldap/ldap.keytab /etc/krb5.keytab

chgrp ldap /etc/krb5.keytab && chmod 640 /etc/krb5.keytab

要以 root 用户身份运行 slapd


注明LDAP存在配置:

authz-regexp
   uid=(.*),cn=GSSAPI,cn=auth 
   uid=$1,ou=people,dc=example,dc=com

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ldap.h> #include <openssl/ssl.h> #define LDAP_SERVER_URI "ldaps://ldap.example.com:636" // 替换为你的LDAPS地址 #define BIND_DN "cn=admin,dc=example,dc=com" // 管理员DN #define BIND_PW "your_password" // 管理员密码 #define SEARCH_BASE "dc=example,dc=com" // 搜索基准DN #define SEARCH_FILTER "(objectClass=*)" // 搜索过滤器 // 安全释放LDAP连接 void safe_ldap_unbind(LDAP *ld) { if (ld) { ldap_unbind_ext_s(ld, NULL, NULL); } } int main() { LDAP *ld = NULL; int rc = 0; int ldap_version = LDAP_VERSION3; // ==================== 1. 初始化LDAP连接 ==================== rc = ldap_initialize(&ld, LDAP_SERVER_URI); if (rc != LDAP_SUCCESS) { fprintf(stderr, "初始化失败: %s\n", ldap_err2string(rc)); return EXIT_FAILURE; } // ==================== 2. 设置协议版本 ==================== rc = ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version); if (rc != LDAP_OPT_SUCCESS) { fprintf(stderr, "设置协议版本失败: %s\n", ldap_err2string(rc)); safe_ldap_unbind(ld); return EXIT_FAILURE; } // ==================== 3. 配置SSL/TLS选项 ==================== // 3.1 设置CA证书路径(需客户端信任的CA证书) const char *ca_cert = "/etc/ssl/certs/ldap-ca.crt"; rc = ldap_set_option(ld, LDAP_OPT_X_TLS_CACERTFILE, ca_cert); if (rc != LDAP_OPT_SUCCESS) { fprintf(stderr, "设置CA证书失败\n"); safe_ldap_unbind(ld); return EXIT_FAILURE; } // 3.2 强制验证服务器证书(生产环境推荐) int cert_check = LDAP_OPT_X_TLS_DEMAND; rc = ldap_set_option(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &cert_check); if (rc != LDAP_OPT_SUCCESS) { fprintf(stderr, "设置证书验证失败\n"); safe_ldap_unbind(ld); return EXIT_FAILURE; } // 3.3 初始化TLS上下文 rc = ldap_start_tls_s(ld, NULL, NULL); // 如果是StartTLS则需此步骤 if (rc != LDAP_SUCCESS) { fprintf(stderr, "启动TLS失败: %s\n", ldap_err2string(rc)); safe_ldap_unbind(ld); return EXIT_FAILURE; } // ==================== 4. 绑定到服务器 ==================== struct bval cred; cred.bv_val = (char *)BIND_PW; cred.bv_len = strlen(BIND_PW); rc = ldap_sasl_bind_s(ld, BIND_DN, LDAP_SASL_SIMPLE, &cred, NULL, NULL, NULL); if (rc != LDAP_SUCCESS) { fprintf(stderr, "绑定失败: %s\n", ldap_err2string(rc)); safe_ldap_unbind(ld); return EXIT_FAILURE; } // ==================== 5. 执行搜索操作 ==================== LDAPMessage *result = NULL; rc = ldap_search_ext_s(ld, SEARCH_BASE, LDAP_SCOPE_SUBTREE, SEARCH_FILTER, NULL, 0, NULL, NULL, NULL, 0, &result); if (rc != LDAP_SUCCESS) { fprintf(stderr, "搜索失败: %s\n", ldap_err2string(rc)); safe_ldap_unbind(ld); return EXIT_FAILURE; } // ==================== 6. 遍历结果 ==================== printf("===== 查询结果 =====\n"); LDAPMessage *entry; for (entry = ldap_first_entry(ld, result); entry != NULL; entry = ldap_next_entry(ld, entry)) { char *dn = ldap_get_dn(ld, entry); printf("DN: %s\n", dn); ldap_memfree(dn); BerElement *ber = NULL; char *attr; for (attr = ldap_first_attribute(ld, entry, &ber); attr != NULL; attr = ldap_next_attribute(ld, entry, ber)) { struct berval **vals = ldap_get_values_len(ld, entry, attr); if (vals != NULL) { for (int i = 0; vals[i] != NULL; i++) { printf(" %s: %s\n", attr, vals[i]->bv_val); } ldap_value_free_len(vals); } ldap_memfree(attr); } if (ber != NULL) ber_free(ber, 0); printf("--------------------\n"); } // ==================== 7. 清理资源 ==================== ldap_msgfree(result); safe_ldap_unbind(ld); return EXIT_SUCCESS; }
最新发布
05-16
### C语言通过LDAPS连接到LDAP服务器并执行搜索操作 要在C语言中实现通过LDAPS(安全的LDAP协议)连接到LDAP服务器并执行搜索操作,通常会依赖于`OpenLDAP`库中的函数来完成这一目标。以下是详细的说明以及示例代码。 #### 使用的库 为了实现此功能,需要链接以下库: - `libldap_r`: 提供LDAP客户端API的支持。 - `libsasl2`: 如果启用了SASL认证,则可能需要用到该库。 - `openssl/libssl_static` 和 `openssl/libcrypto_static`: 用于SSL/TLS加密通信[^1]。 这些库提供了必要的函数和数据结构来进行LDAP操作,包括建立TLS/SSL连接、绑定身份验证以及执行搜索请求等功能。 #### 示例代码 下面展示了一个完整的例子,演示如何使用C语言编写程序以通过LDAPS方式连接至远程LDAP服务端,并发起基本属性检索: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ldap.h> #define LDAP_SERVER "ldaps://yourserver.example.com" #define BIND_DN "cn=admin,dc=example,dc=com" #define PASSWORD "password" int main(void){ int rc; LDAP *ld; /* Step 1: Initialize the connection */ ld = ldap_init(LDAP_SERVER, LDAP_PORT); if (!ld) { fprintf(stderr,"Could not initialize LDAP.\n"); exit(EXIT_FAILURE); } /* Enable Start TLS extended operation request */ struct berval cred; cred.bv_len=strlen(PASSWORD); cred.bv_val=(char *)PASSWORD; rc = ldap_start_tls_s(ld,NULL,&cred); if (rc != LDAP_SUCCESS ){ printf("Error starting TLS:%s\n",ldap_err2string(rc)); goto cleanup; } /* Bind to server with simple authentication method*/ rc = ldap_simple_bind_s( ld ,BIND_DN,(const char *)&cred ); if (rc != LDAP_SUCCESS ) { printf("Bind failed :%d %s \n ",rc ,ldap_err2string(rc)); goto cleanup; } /* Perform search base object scope subtree filter "(objectclass=*)" attributes {"*"} */ const char *attrs[]={"*",NULL}; LDAPMessage *res,*entry; BerValue **vals; char dnbuf[BUFSIZ]; size_t i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; rc = ldap_search_ext_s( ld, "ou=users,dc=example,dc=com", LDAP_SCOPE_SUBTREE, "(uid=testuser)", attrs, 0,//attrsonly flag set false here means we want both attribute names and values returned. NULL/*ServerControls*/, NULL/*ClientControls*/, &timeout_struct_defined_elsewhere_or_NULL_if_no_timeout_required , sizelimit_value_as_integer_which_may_be_zero_for_unlimited_results_count , &res); if (rc != LDAP_SUCCESS ){ printf("Search failed :%d %s \n ",rc ,ldap_err2string(rc)); goto cleanup; } entry = ldap_first_entry(ld,res); while(entry!=NULL){ ber_strcpy(dnbuf,strlen((char*)ldap_get_dn(ld,entry))); printf("\nDN=%s\n",(dnbuf)); vals = ldap_get_values_len(ld,entry,"mail"); k=ber_bvecfree(vals); if(k>0){ for(i=0;i<k;i++)printf("%.*s\n",(int)(vals[i].bv_len),(vals[i].bv_val)); } entry = ldap_next_entry(ld,entry); } cleanup: ldap_msgfree(res); ldap_unbind_ext_s(ld,NULL,NULL); return EXIT_SUCCESS; } ``` 这段代码展示了几个重要部分的操作过程:初始化LDAP句柄;启动TLS保护通道;简单绑定用户凭证;最后执行针对特定用户的邮件字段查询返回结果集处理逻辑[^3]。 请注意,在实际部署之前还需要考虑更多细节问题比如错误检测增强机制、资源释放彻底性等方面优化改进措施。 #### 注意事项 - 需要确保编译环境已安装好所需的头文件(`<ldap.h>`等),并且正确设置了路径以便找到它们。 - 编译时记得加上相应的选项指定外部共享对象位置或者静态版本的位置信息给链接器知道去哪里寻找那些符号定义的实际内容所在之处。 - 对生产环境中使用的密码应当采取更加严格的安全策略而不是硬编码在源码里边暴露出来。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值