如何在Ubuntu18的OpenLDAP中通过Novell.Directory.Ldap实现userAccountControl相关功能?
替代OpenLDAP中userAccountControl的实现方案(基于Novell.Directory.Ldap C#库)
OpenLDAP原生不支持AD的userAccountControl属性,需通过其自带的密码策略相关属性实现对应的账户控制功能。以下是具体功能的代码实现:
前置准备:初始化LDAP连接
using Novell.Directory.Ldap; // 配置LDAP服务器信息 var ldapHost = "你的OpenLDAP服务器地址"; var ldapPort = 389; // 加密连接用636 var adminDn = "cn=admin,dc=example,dc=com"; var adminPassword = "管理员密码"; // 建立并绑定连接 using var connection = new LdapConnection(); connection.Connect(ldapHost, ldapPort); connection.Bind(adminDn, adminPassword);
1. 用户必须更改密码
通过pwdMustChange布尔属性控制,值为TRUE时用户下次登录必须修改密码。
设置属性
var userDn = "uid=jdoe,ou=users,dc=example,dc=com"; var modifyAttrs = new List<LdapModification>(); modifyAttrs.Add(new LdapModification(LdapModification.REPLACE, new LdapAttribute("pwdMustChange", "TRUE"))); connection.Modify(userDn, modifyAttrs.ToArray());
获取属性
var searchResults = connection.Search( userDn, LdapConnection.SCOPE_BASE, "(objectClass=*)", new[] { "pwdMustChange" }, false ); if (searchResults.HasMore()) { var entry = searchResults.Next(); var mustChange = entry.GetAttribute("pwdMustChange")?.StringValue == "TRUE"; Console.WriteLine($"用户必须更改密码: {mustChange}"); }
2. 无法更改密码
通过pwdAllowUserChange布尔属性控制,值为FALSE时禁止用户自行修改密码。
设置属性
var modifyAttrs = new List<LdapModification>(); modifyAttrs.Add(new LdapModification(LdapModification.REPLACE, new LdapAttribute("pwdAllowUserChange", "FALSE"))); connection.Modify(userDn, modifyAttrs.ToArray());
获取属性
var searchResults = connection.Search( userDn, LdapConnection.SCOPE_BASE, "(objectClass=*)", new[] { "pwdAllowUserChange" }, false ); if (searchResults.HasMore()) { var entry = searchResults.Next(); var allowChange = entry.GetAttribute("pwdAllowUserChange")?.StringValue != "FALSE"; Console.WriteLine($"用户可修改密码: {allowChange}"); }
3. 密码永不过期
通过pwdMaxAge属性控制(单位为秒),值为0表示密码永不过期。
设置属性(永不过期)
var modifyAttrs = new List<LdapModification>(); modifyAttrs.Add(new LdapModification(LdapModification.REPLACE, new LdapAttribute("pwdMaxAge", "0"))); connection.Modify(userDn, modifyAttrs.ToArray());
获取属性
var searchResults = connection.Search( userDn, LdapConnection.SCOPE_BASE, "(objectClass=*)", new[] { "pwdMaxAge" }, false ); if (searchResults.HasMore()) { var entry = searchResults.Next(); if (long.TryParse(entry.GetAttribute("pwdMaxAge")?.StringValue, out var maxAge)) { var neverExpire = maxAge == 0; Console.WriteLine($"密码永不过期: {neverExpire}"); if (!neverExpire) { Console.WriteLine($"密码有效期: {TimeSpan.FromSeconds(maxAge).TotalDays} 天"); } } }
4. 账户锁定/解锁
通过pwdAccountLockedTime属性控制,设置为UTC时间格式(如20240520120000Z)表示锁定账户,删除该属性则解锁。
设置锁定
var lockTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssZ"); var modifyAttrs = new List<LdapModification>(); modifyAttrs.Add(new LdapModification(LdapModification.REPLACE, new LdapAttribute("pwdAccountLockedTime", lockTime))); connection.Modify(userDn, modifyAttrs.ToArray());
设置解锁
var modifyAttrs = new List<LdapModification>(); modifyAttrs.Add(new LdapModification(LdapModification.DELETE, new LdapAttribute("pwdAccountLockedTime"))); connection.Modify(userDn, modifyAttrs.ToArray());
获取锁定状态
var searchResults = connection.Search( userDn, LdapConnection.SCOPE_BASE, "(objectClass=*)", new[] { "pwdAccountLockedTime" }, false ); if (searchResults.HasMore()) { var entry = searchResults.Next(); var lockTimeStr = entry.GetAttribute("pwdAccountLockedTime")?.StringValue; var isLocked = !string.IsNullOrEmpty(lockTimeStr); Console.WriteLine($"账户已锁定: {isLocked}"); if (isLocked) { var lockTime = DateTime.ParseExact(lockTimeStr, "yyyyMMddHHmmssZ", null, System.Globalization.DateTimeStyles.AdjustToUniversal); Console.WriteLine($"锁定时间: {lockTime}"); } }
注意事项
- 上述功能依赖OpenLDAP的
ppolicy(密码策略)模块,需确保已加载该模块并为用户配置对应的密码策略对象。 - 操作属性需具备足够的LDAP权限(如管理员权限)。
内容的提问来源于stack exchange,提问作者Varsh
相关产品推荐
相关产品推荐

