商标查询网站建设,网络营销推广方法结论,网站建设需要提供那些资料,太原网站优化教程一.前言 记录自己在实现这个流程遇到的各种问题#xff0c;因为我也是看了许多优质的文章以及组内大佬的帮助下才弄成的#xff0c;这里推荐一个大佬的文章#xff0c;写的非常优秀#xff0c;比我这篇文章写得好得很多#xff0c;最后我也是看这个大佬的代码最终才实现的…一.前言 记录自己在实现这个流程遇到的各种问题因为我也是看了许多优质的文章以及组内大佬的帮助下才弄成的这里推荐一个大佬的文章写的非常优秀比我这篇文章写得好得很多最后我也是看这个大佬的代码最终才实现的特别鸣谢。看这篇文章前提你得足够的了解ADkerberosldap等CSDN这类文章就很多我就不献丑了。 LDAP/SASL/GSSAPI/Kerberos编程API(2)--krb5客户端 LDAP/SASL/GSSAPI/Kerberos编程API(3)--LDAP/SASL 不止这两篇大佬很详细可自行查看 二环境支持 AD服务器Windows server 2022 中文版 Linuxubuntu 20 openldapsudo apt-get install libldap-dev //代码所需要的ldap.h GSSAPI支持sudo apt-get install libsasl2-modules-gssapi-mit //使LDAP支持GSSAPI认证kerberos属于GSSAPI认证方式之一否则运行时会出现下面报错。 Error: Unknown authentication method
Additional info: SASL(-4): no mechanism available: No worthy mechs found krb5环境支持sudo apt-get install krb5-user //krb5API的调用因为kerberos认证过程中产生的TGT票据是我们手动调用API实现的 而并非使用kinit生成。 三API详解 1.生成TGT票据 因为我写的是公司项目代码不可以拿出来我就直接引用前言大佬的代码了冒犯还请联系我删除。各个API的功能和参数作用我都写在代码块中了注释是我加的代码是大佬的。
大致流程1.初始化安全的上下文-2.使用用户名密码换区TGT-3.通过TGT换区票据
#include ldap.h
#include stdio.h
#include stdlib.h
#include krb5.h//krb5_get_init_creds_password函数所使用的回调函数这个函数必须返回成功值 LDAP_SUCCESS,否则基本都失败因为我通过循环试了1000值。不需要了解他的功能我猜测的是这个函数能够在我们进行最后的bind之前进行其他的判断如果失败不返回LDAP_SUCCESS,作为最后一道屏障
static int _ldap_sasl_interact( )
{ return LDAP_SUCCESS;
}int main()
{ krb5_context context NULL; krb5_error_code krberr;krb5_principal kprincpw NULL;krb5_creds * my_creds_ptr NULL;krb5_creds my_creds;const char * errmsg;//初始化一个安全的上下文后续的操作都是基于context可以把他看成是基石krberr krb5_init_context(context);if (krberr) {//这个API能够解析错误码分析出特定的错误信息将其存储在errmsg中然后打印到终端查看errmsg krb5_get_error_message(NULL, krberr);printf(Err: Kerberos context initialization failed - %s\n, errmsg);goto cleanup;}//这个API是你用户的信息第二个参数转化成krb中的格式存储在kprincpw中用户信息的组成认证的用户名AD服务器的域名krberr krb5_parse_name(context, krblinlinCTP.NET, kprincpw); if (krberr) {errmsg krb5_get_error_message(context, krberr);printf(Err: Failed to parse princpal %s - %s\n, errmsg);goto cleanup;}//用户的密码哈哈这个谁都看得出来吧const char *passwordlinlin; printf(begin get init creds password\n);//使用用户的信息密码换取TGT票据并且拿到将凭证放my_creds中但是这个凭证不是TGT而是最后一次认证使用的krberr krb5_get_init_creds_password(context, my_creds,kprincpw, (char *)password,NULL,NULL,0,NULL,NULL);if (krberr) {errmsg krb5_get_error_message(context, krberr);printf(Err: Failed to get init creds password - %s\n, errmsg);goto cleanup;} // my_creds_ptr my_creds;printf(get init creds password OK\n);//--vkrb5_ccache ccache NULL;//从内存中获取TGT票据将其放入到ccache的变量中便于后面换取TGS票据就是服务器的最终通行证krberr krb5_cc_resolve(context, MEMORY:dhcp_ld_krb5_cc, ccache);//从/tmp/krb5cc_1000中获取TGT票据这个文件是自动生成的将其存储到ccache中便于后面换取TGS票据安全性上看来确实没有从内存中获取TGT票据更安全因为这个是可视化的你甚至可以自己打开查看//krberr krb5_cc_resolve(context, FILE:/tmp/krb5cc_1000, ccache);if (krberr) {errmsg krb5_get_error_message(context, krberr);printf(Err: Couldnt resolve ccache - %s\n, errmsg);goto cleanup;} //初始化ccache相当于清空但是你的ccache却不能是空的我怀疑这个函数内存做的处理是先是利用ccache中存储的TGT票据生成TGS服务票据然后再清空。这里也能看见API还指定了用户名说明生成的TGS是有对应关系的。krberr krb5_cc_initialize(context, ccache, kprincpw);if (krberr) {errmsg krb5_get_error_message(context, krberr);printf(Err: Failed to init ccache - %s\n, errmsg);goto cleanup;} //这个函数的作用我是有点迷的这里又将my_creds的凭据放到ccache中又进行了一次认证因为kerberos的认证是繁琐的多次认证我暂且这样理解吧因为通过抓包发现也是进行了多次responsekrberr krb5_cc_store_cred(context, ccache, my_creds);if (krberr) {errmsg krb5_get_error_message(context, krberr);printf(Err: Failed to store credentials - %s\n, errmsg);goto cleanup;}printf(Successfully store creds\n);
2.将LDAP句柄指针和用户信息绑定 因为后续需要使用LDAP协议去管理AD服务器例如增删改查用户的信息例如我就进行了搜索用户邮箱的操作这里没看大佬代码因为我觉得我的更利于直观理解。
LDAP *ld;int rc;unsigned long version LDAP_VERSION3; //使用LDAP的v3版本//初始化一个LDAP句柄指针ld后面的操作全是基于LDAP句柄指针和上分的context差不多if (( rc ldap_initialize(ld,ldap://192.168.1.11/)) ! LDAP_SUCCESS) //#12//if (( rc ldap_initialize(ld,ldap://127.0.0.1/)) ! LDAP_SUCCESS){return(1);}//与服务器协商使用V3版本吗rc ldap_set_option(ld,LDAP_OPT_PROTOCOL_VERSION,(void*)version);//除了第6个参数其他都可以默认第六个参数就是上分提到返回LDAP_SUCCESS的回调函数这里大佬的代码是有一点问题的因为它回调函数是返回int类型的然而这里的参数的数据类型是一个宏定义我这里看不了下次补充进来最后解决办法是将回调函数的返回类型换成这个宏定义最后转换一下就行了。到这里就bind成功了完成第四步的配置文件后可以进行增删改查了if ((rcldap_sasl_interactive_bind_s(ld,NULL,GSSAPI,NULL,NULL,LDAP_SASL_AUTOMATIC, _ldap_sasl_interact,NULL) ) ! LDAP_SUCCESS){ printf (Error: %s\n,ldap_err2string (rc));char *msgNULL;ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, (void*)msg);printf (Additional info: %s\n, msg);ldap_memfree(msg);return(1);}LDAPMessage *res;if ((rcldap_search_ext_s(ld,,LDAP_SCOPE_ONELEVEL,NULL,NULL,0,NULL,NULL,NULL,0,res)!LDAP_SUCCESS)){ printf(ldap_search failed with 0x%x.\n,rc); return(1);}printf(Success!\n);LDAPMessage *entry ldap_first_entry( ld, res );int entry_count ldap_count_entries(ld, res);for (int i 0 ; i entry_count; i){ printf(dn: %s\n,ldap_get_dn(ld, entry));BerElement * ber;char * attribute ldap_first_attribute(ld,entry, ber);while(attribute){ printf (attribute %s\n,attribute);attribute ldap_next_attribute(ld,entry, ber);}ber_free(ber,0);entry ldap_next_entry(ld, entry); }
//--^--cleanup:if (ccache) krb5_cc_close(context, ccache); //#13if (kprincpw) krb5_free_principal(context, kprincpw);if (my_creds_ptr) krb5_free_cred_contents(context, my_creds);if (context) krb5_free_context(context);return 0;
}四环境的配置
第1步.在/etc/krb5.conf中添加服务器对应的信息(ubuntu)
[libdefaults]default_realm TEST.ORG //TEST.ORG 你的服务器域名大写dns_lookup_realm falsedns_lookup_kdc falseticket_lifetime 24hrenew_lifetime 7dforwardable true
[realms]TEST.ORG { //填充你TEST.ORG的模块信息kdc 192.168.45.141 //kdc的IP在AD中是集成在一块填AD的IP即可admin_server 192.168.45.141 //与kdc同理default_domainTEST.ORG //可填可不填}[domain_realm] //这个模块的信息可填可不填.test.org TEST.ORGtest.org TEST.ORG
第2步.在/etc/hosts文件中添加KDC主机名和KDC所在域名(ubuntu) 27.0.0.1 localhost 127.0.1.1 ubuntu.test.org ubuntu 192.168.45.xxx DC.TEST.ORG #红色为添加信息前面填充kdc IP 后面填写 服务器主机名.域名 例如我的主机名为DC域名为TEST.ORG # The following lines are desirable for IPv6 capable hosts ::1 ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 如果第1步不配置会找不到服务器
如果第2步不配置会出现下列错误SASL(-1): generic failure: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (Server not found in Kerberos database)
同时你也可以在AD中添加DNS反向查询解决这个错误而不修改/etc/hosts当然这是用在用户基数很大的情况下改变AD服务器可以一劳永逸详情查看第3步。
第3步 为AD服务器添加DNS反向查询解决这个错误
3.1进入服务管理器找到DNS右击右侧服务器进入DNS管理器 3.2 右击反向查找区域点击新建区域 3.3 一直点击下一步直到输入IP的页面输入AD 服务器IP的前3个字段 例如我的IP为192.168.45.141那么输入192.168.45再一直点击下一步直到结束。 3.4 右击新生成的区域点击新建指针 3.5 填写AD服务的IP地址先关闭 3.6 找到正向查找区域-域名-打开dc(你的是你自己的域名我的是dc) 3.7 找到FQDN将其复制到2.3.5主机名的地方即可。 3.8 ubuntu打开/etc/reslov.conf,修改nameserver的地址 为你AD的地址再将你ubuntu的DNS设置为AD的IP否则这个文件的值会一直变动 4.结言 直到这里整个流程吗包括配置文件全部结束加油 。