ldapmodify -v -x -ZZ -H ldap://<ldap> -D "cn=fi_user,cn=users,dc=qa01,dc=eng,dc=user,dc=com" -w oldpassword -f ~/old_to_new.ldif
ldap_initialize( ldap://<ldap>/??base )
ldap_bind: Invalid credentials (49)
additional info: 80090308: LdapErr: DSID-0C09042F, comment: AcceptSecurityContext error, data 773, v2580
是否可以在Linux中使用C语言中的ldap协议重置此Active directory用户的密码(下一次登录时重置密码已设置)?
vector<string> Split(string& s, string delim) {
vector<string> ret;
auto start = 0U;
auto end = s.find(delim);
while (end != std::string::npos) {
ret.push_back(s.substr(start, end - start));
start = end + delim.length();
end = s.find(delim, start);
}
ret.push_back(s.substr(start));
return ret;
}
void SetLDAPModPassword(LDAPMod* ldap_mod, string& password) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::u16string utf16_curr_pass = convert.from_bytes("\"" + password + "\"");
struct berval** ber_arr = new struct berval*[2];
ber_arr[1] = NULL;
ber_arr[0] = new struct berval;
ber_arr[0]->bv_val = new char[utf16_curr_pass.size() * 2];
memcpy(ber_arr[0]->bv_val,
utf16_curr_pass.data(),
utf16_curr_pass.size() * 2);
ber_arr[0]->bv_len = utf16_curr_pass.size() * 2;
ldap_mod->mod_vals.modv_bvals = ber_arr;
}
string SetLdapOptions(LDAP* ldap_handle) {
stringstream ss;
int ret = ldap_set_option(ldap_handle, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
if (ret != LDAP_OPT_SUCCESS) {
ss << "ldap_set_option LDAP_OPT_REFERRALS to LDAP_OPT_OFF failed: "
<< ldap_err2string(ret);
return ss.str();
}
const int ldap_version = LDAP_VERSION3;
ret = ldap_set_option(ldap_handle, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
if (ret != LDAP_OPT_SUCCESS) {
ss << "ldap_set_option LDAP_OPT_PROTOCOL_VERSION to " << ldap_version
<< " failed: " << ldap_err2string(ret);
return ss.str();
}
const int cert_flag = LDAP_OPT_X_TLS_NEVER;
ret = ldap_set_option(nullptr, LDAP_OPT_X_TLS_REQUIRE_CERT, &cert_flag);
if (ret != LDAP_OPT_SUCCESS) {
ss << "ldap_set_option LDAP_OPT_X_TLS_REQUIRE_CERT to "
"LDAP_OPT_X_TLS_NEVER failed: "
<< ldap_err2string(ret);
return ss.str();
}
ret = ldap_start_tls_s(ldap_handle, NULL, NULL );
if (ret != LDAP_SUCCESS) {
ss << "ldap_start_tls_s failed: " << ldap_err2string(ret);
return ss.str();
}
int timelimit = 15;
struct timeval timeout = {.tv_sec = timelimit, .tv_usec = 0};
ret = ldap_set_option(ldap_handle, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
if (ret != LDAP_OPT_SUCCESS) {
ss << "ldap_set_option LDAP_OPT_NETWORK_TIMEOUT to "
"LDAP_OPT_X_TLS_NEVER failed: "
<< ldap_err2string(ret);
return ss.str();
}
ret = ldap_set_option(ldap_handle, LDAP_OPT_TIMELIMIT, &timelimit);
if (ret != LDAP_OPT_SUCCESS) {
ss << "ldap_set_option LDAP_OPT_TIMELIMIT to " << timelimit
<< " failed: " << ldap_err2string(ret);
return ss.str();
}
ret = ldap_set_option(ldap_handle, LDAP_OPT_TIMEOUT, &timeout);
if (ret != LDAP_OPT_SUCCESS) {
ss << "ldap_set_option LDAP_OPT_TIMEOUT to "
<< timeout.tv_sec << " failed: " << ldap_err2string(ret);
}
return ss.str();
}
string ChangeActiveDirectoryPassword(string domain_controller,
string domain,
string username,
string curr_password,
string new_password) {
int ret;
LDAP* ldap_handle = nullptr;
char passwd_attr[16] = "unicodePwd";
std::stringstream ss;
ss << "ldap://" << domain_controller << ":389";
LOG(INFO) << ss.str();
ret = ldap_initialize(&ldap_handle, ss.str().c_str());
ss.str(std::string());
if (ret != LDAP_SUCCESS) {
ss << "ldap_initialize failed: " << ldap_err2string(ret);
return ss.str();
}
string ret_err = SetLdapOptions(ldap_handle);
if (!ret_err.empty()) {
return ret_err;
}
stringstream domain_stream;
domain_stream << "CN=" << FLAGS_username << ",CN=Users,";
vector<string> split_string_vec = Split(domain, ".");
int ii = 0;
for (auto subdomain : split_string_vec) {
if (ii != 0) {
domain_stream << ",";
}
domain_stream << string("DC=") << subdomain;
ii++;
}
string domain_string = domain_stream.str();
struct berval passwd_berval;
passwd_berval.bv_len = curr_password.size();
passwd_berval.bv_val = new char[curr_password.size() + 1];
strcpy(passwd_berval.bv_val, curr_password.c_str());
LOG(INFO) << domain_string;
struct berval* servercredp;
ret = ldap_sasl_bind_s(ldap_handle,
domain_string.c_str(),
LDAP_SASL_SIMPLE,
&passwd_berval,
NULL,
NULL,
&servercredp);
delete[] passwd_berval.bv_val;
if (ret != LDAP_SUCCESS) {
ss << "ldap_sasl_bind_s failed: " << ldap_err2string(ret);
//return ss.str();
}
LDAPMod delete_old_pass;
memset(&delete_old_pass, 0, sizeof(LDAPMod));
char unicode_str[16] = "unicodePwd";;
delete_old_pass.mod_op = LDAP_MOD_DELETE | LDAP_MOD_BVALUES;
delete_old_pass.mod_type = unicode_str;
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::u16string utf16_curr_pass =
convert.from_bytes("\"" + FLAGS_curr_passwd + "\"");
struct berval** del_ber_arr = new struct berval*[2];
del_ber_arr[1] = NULL;
del_ber_arr[0] = new struct berval;
del_ber_arr[0]->bv_val = new char[utf16_curr_pass.size() * 2];
memcpy(del_ber_arr[0]->bv_val,
utf16_curr_pass.data(),
utf16_curr_pass.size() * 2);
del_ber_arr[0]->bv_len = utf16_curr_pass.size() * 2;
delete_old_pass.mod_vals.modv_bvals = del_ber_arr;
LDAPMod add_new_pass;
LDAPMod *add_new_pass_pointer = &add_new_pass;
memset(&add_new_pass, 0, sizeof(LDAPMod));
add_new_pass.mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
add_new_pass.mod_type = unicode_str;
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert1;
std::u16string utf16_new_pass =
convert1.from_bytes("\"" + FLAGS_new_passwd + "\"");
struct berval** add_ber_arr = new struct berval*[2];
add_ber_arr[1] = NULL;
add_ber_arr[0] = new struct berval;
add_ber_arr[0]->bv_val = new char[utf16_new_pass.size() * 2];
memcpy(add_ber_arr[0]->bv_val,
utf16_new_pass.data(),
utf16_new_pass.size() * 2);
add_ber_arr[0]->bv_len = utf16_new_pass.size() * 2;
add_new_pass.mod_vals.modv_bvals = add_ber_arr;
LDAPMod *mods[3];
mods[0] = &delete_old_pass;
mods[1] = &add_new_pass;
mods[2] = NULL;
ret = ldap_modify_ext_s(
ldap_handle,
domain.c_str(),
mods,
NULL,
NULL);
CHECK_EQ(ret, LDAP_SUCCESS)
<< "ldap_modify_ext_s() failed." << ldap_err2string(ret) << " dn "
<< domain << " pass " << curr_passwd.bv_val;
ldap_destroy(ldap_handle);
LOG(INFO) << "LDAP password changed.";
}
请注意,“更改”密码和“重置”密码被认为是两件不同的事情。
在UnicodePwd
属性的文档中描述了这两种方法的过程。
因此您需要为unicodePwd
属性发送LDAP替换操作,并使用所需格式的新密码。所需格式为:
DC要求在UTF-16编码的Unicode字符串中指定密码值,该字符串包含由引号包围的密码,该字符串已按照对象(副本链接)语法被BER编码为二进制八位数字符串。
更改密码
如果Modify请求包含包含unicodePwd值Vdel的delete操作和包含unicodePwd值Vadd的add操作,则服务器将该请求视为更改密码的请求。服务器使用本节后面介绍的密码解码过程对Vadd和Vdel进行解码。Vdel是旧密码,而Vadd是新密码。
为了澄清,您需要发送一个LDAP请求来修改UnicodePwd
属性,该属性在同一请求中包含两个操作:
我正在尝试通过使用LDAP以编程方式更改用户密码。用户在Active Directory中具有标志“用户必须在下一次登录时更改密码”。但无法通过此用户对Active Directory进行身份验证。我使用了两种LDAP身份验证类型--simple和GSSAPI(Kerberos)。有人能解释一下,当检查“用户必须更改密码”时,Windows自己是如何更改密码的吗?在身份验证时,Kerberos落在
唯一的区别是异常消息中word数据的值。我不想依赖这个消息。如何区分“用户下次登录时必须更改密码”和“密码错误”用例?
本文向大家介绍Linux下SSH免密码登录配置详解,包括了Linux下SSH免密码登录配置详解的使用技巧和注意事项,需要的朋友参考一下 假设有 A、 B 两台 Linux 服务器,我们希望能够从其中一台服务器通过 SSH 免密码登录到另一台服务器。 两台服务器的信息如下: 主机名 IP地址 免密码登录用户名 server1 192.168.12.11 guest1 server2 192.168
本文向大家介绍Linux中禁止用户修改/重置密码,包括了Linux中禁止用户修改/重置密码的使用技巧和注意事项,需要的朋友参考一下 前言 Linux用户的用户名保存在/etc/passwd文件中,密码保存在/etc/shadow中。要禁止用户修改/重置密码,将这两个文件设置为只读即可。 方法如下 要允许修改密码,取消文件上的只读标记: 注意 将这两个文件设置为只读后,附加效果是无法新建新用户。例如
本文向大家介绍Linux配置远程SSH无密码登录,包括了Linux配置远程SSH无密码登录的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了jaLinux配置远程SSH无密码登录的方法,供大家参考,具体内容如下 系统:CentOS 6.8 主机1:192.168.0.177 主机2:192.168.0.178 工具介绍: ssh-keygen:创建公钥和密钥 ssh-copy-id:把
本文向大家介绍在Linux中更改MySQL根密码,包括了在Linux中更改MySQL根密码的使用技巧和注意事项,需要的朋友参考一下 示例 要更改MySQL的root用户密码: 步骤1:停止MySQL服务器。 在Ubuntu或Debian中: sudo /etc/init.d/mysql stop 在CentOS,Fedora或Red Hat Enterprise Linux中: sudo /etc