【问题标题】:How to modify userAccountControl in ActiveDirectory from RubyOnRails3 with Ruby1.9.2 and roryO's net-ldap - gem?如何使用 Ruby1.9.2 和 roryO 的 net-ldap - gem 从 RubyOnRails3 修改 ActiveDirectory 中的 userAccountControl?
【发布时间】:2011-07-18 00:02:12
【问题描述】:

我想要做的是启用/禁用 Active Directory 用户帐户。 在 Active Directory 中,该信息作为 HEX 值存储在名为 userAccessControl 的属性中的位寄存器中。在我们的 Windows 2008 Server R1 中,对于具有用户密码永不过期选项的启用帐户,这是 0x10200,对于具有用户密码永不过期选项的禁用帐户,这是 0x10202。

现在只需触摸启用/禁用信息的标志,我编写了以下方法...

def set_account_active_flag(activate)
  success = false
  get_aduser if @aduser.nil?
  puts "#####################################"
  unless @uac.nil? || @uac.blank?
    tmpuac = @uac.to_i
    tmpuac = activate ? tmpuac & 2 == 0 ? tmpuac | 2
                                        : tmpuac
                      : tmpuac & 2 == 2 ? tmpuac ^ 2
                                        : tmpuac
    ldap_con = self.class.initialize_ldap_con
    # success = ldap_con.replace_attribute ldap_encode(@dn), :userAccountControl, tmpuac


   success = ldap_con.replace_attribute ldap_encode(@dn), :userAccountControl, ldap_encode(tmpuac.to_s)
  else
    puts ">>>>>\nuserAccessControl-Register is not available\n<<<<<"
  end
rescue Net::LDAP::LdapError => e
  puts "NET::LDAP::LdapError\n#{e}"
ensure
  puts "-------------------------------------"
  puts "LDAP operation failed (#{ldap_con.get_operation_result.code}):"
  puts "-------------------------------------"
  puts ldap_con.get_operation_result.message
  puts "#####################################"
  return success
end

好的...内部结构:

  • get_aduser 只是一种加载一组广告属性(['dn','userPrincipalName', 'givenname','sn', 'mail', 'memberof', 'userAccountControl'])并存储它们的方法进入尝试登录的用户的实例变量(@dn、@user_principal_name、@first_name、@last_name、@groups、@uac)

这部分就像一个魅力。 @uac(作为字符串返回),我可以转换为整数

x = @uac.to_i

然后将其用作位寄存器来检查和修改标志

x &  2 # => 0 if unset, => 1 if set
x |= 2 # sets the flag
x ^= 2 # unsets the flag

我认为这项工作就像将值写回我的 Active Directory 一样简单。

我的问题来了: 到目前为止,我尝试将新的 userAccountControl 值写回为 integerstring,但两次尝试都失败了,尽管在这两种情况下的 operation-result-message 都是 {Code: 0、消息:'成功'}

尝试将新的 userAccessControl 值写回 integer 引发 NET::LDAP::LdapError

#####################################
NET::LDAP::LdapError 
response missing or invalid
-------------------------------------
LDAP operation failed (0):
-------------------------------------
Success
#####################################
=> false 

尝试将新的 userAccessControl 值写回 string 不会引发错误,但仍会导致错误

#####################################
-------------------------------------
LDAP operation failed (0):
-------------------------------------
Success
#####################################
=> false 

所以我想知道,“我做错了什么?”

有人知道如何将 userAccessControl 写回 ActiveDirectory 吗?

我是否必须使用类似于写回用户密码的笨拙算法来转换新的 userAccessControl-Value?

非常感谢您提供任何有用的提示甚至解决方案。

最好的问候,

英戈甘宾

【问题讨论】:

    标签: ruby-on-rails ruby active-directory ldap


    【解决方案1】:

    好的,从玩弄所有 ldap 连接的东西并尝试了几种不同的方法,比如使用我在 rails 中执行的 php-scripts 编写整个节目,看来编写修改后的值实际上并没有真正的问题回来!

    我做错了什么? 没有! ……嗯……或多或少……就是……

    为什么我没有意识到上述方法“有点”有效?

    • 让 ActiveDirectory 管理单元查看用户列表不会在点击“F5”时实现微小的“停用”图标...实际上我认为 F5 会实现该列表...但事实并非如此。所以我没有看到那里的变化。
    • 上面的代码包含一点逻辑错误。不是启用帐户,而是禁用帐户,反之亦然,因为上述方法假定 AD 控制标志称为“帐户活动”,但事实并非如此,该标志是“帐户停用”。所以设置标志意味着DEACTIVATION,这与我上面的方法相反。
    • 除了 AD-Account-DEACTIVATION-Flag 之外,我们的用户记录中还有一个类似的标志。我的测试用户实际上在那里被禁用,并且直接调用了 LDAP 修改而不设置用户记录设置 => 所以即使没有禁用 AD 帐户,我的测试用户记录仍然被禁用并且不允许登录。
    • 最后但并非最不重要的一点:即使修改成功,实际尝试替换“userAccountControl”值的返回值仍然返回 false(在下面给出的正确解决方案中仍然如此):

       success = ldap_con.replace_attribute ldap_encode(@dn), :userAccountControl, ldap_encode(tmpuac.to_s)
      

    这里设置帐户停用的固定方法(并且要写回的值应为字符串):

    def set_account_deactivation(deactivate)
      get_aduser if @dn.nil?
      success = false
      unless @uac.nil? || @uac.blank?
        tmpuac = @uac.to_i
        # deactivate = true means 'Account Deactivated'-flag => false
        tmpuac = deactivate ? tmpuac & 2 == 0 ? tmpuac | 2  # flag not set (active)  = account is not deactivated ? deactivate
                                              : tmpuac      #                                                     : leave as is
                            : tmpuac & 2 == 2 ? tmpuac ^ 2  # flag set (deactivated) = account is deactivated     ? activate
                                              : tmpuac      #                                                     : leave as is
        ldap_con = self.class.initialize_ldap_con
        success = ldap_con.replace_attribute ldap_encode(@dn), :useraccountcontrol, ldap_encode("#{tmpuac}")
      else
        puts "Failed to read userAccessControl-Register!"
      end
    rescue Net::LDAP::LdapError => e
      puts "NET::LDAP::LdapError\n#{e}"
    ensure
      return success
    end
    
    def ldap_encode(string)
      if string.encoding.name != 'ASCII-8BIT'
        string.dup.force_encoding 'ASCII-8BIT'
      else
        string
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-21
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      相关资源
      最近更新 更多