Как изменить userAccountControl в ActiveDirectory из RubyOnRails3 с Ruby1.9.2 и net-ldap - gem roryO? - PullRequest
1 голос
/ 18 марта 2011

Я хочу включить / отключить учетную запись Active Directory. В Active Directory эта информация хранится в битовом регистре в атрибуте с именем userAccessControl как HEX-значение. В нашей 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', 'данное имя', '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 как integer и как string , но обе попытки заканчиваются неудачей, хотя сообщение-результат-операция в обоих случаях равно {Code: 0, Сообщение: 'Успех'}

Попытка записать новое значение userAccessControl в виде целое число повышает значение NET :: LDAP :: LdapError

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

Попытка записать новое значение userAccessControl в виде строка не вызывает ошибку, но все равно приводит к ложному

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

Так что мне интересно: «Что я делаю не так?»

Кто-нибудь знает, как записать userAccessControl в ActiveDirectory?

Должен ли я преобразовывать новое значение userAccessControl-Value, используя что-то вроде этого неуклюжего алгоритма, необходимого для записи пароля пользователя?

Заранее большое спасибо за любой полезный совет или даже решение.

С наилучшими пожеланиями,

Инго Гамбин

1 Ответ

1 голос
/ 21 марта 2011

Хорошо, из-за того, что мы играем со всеми подключениями ldap и попробовали несколько разных подходов, таких как написание всего шоу с использованием php-скриптов, которые я выполнил из rails, кажется, что на самом деле нет реальной проблемы в написании модифицированного значенияназад!

Что я сделал не так? Ничего !... ну ... более или менее ... то есть ...

Почему я не смог реализовать вышеприведенный подход "своего рода"?

  • ИмеяActiveDirectory SnapIn, чтобы увидеть список пользователей, не актуализирует крошечный «деактивированный» значок при нажатии «F5» ... на самом деле я предполагал, что F5 актуализирует список вообще ... но это не так.Поэтому я не увидел изменений там.
  • Приведенный выше код содержит небольшую логическую ошибку.Вместо того, чтобы включить учетную запись, она отключается, и наоборот, так как в вышеприведенном методе предполагается, что AD-control-flag называется «Учетная запись активна», но это не так, флаг «Учетная запись деактивирована».Таким образом, установка флага означает DEACTIVATION, что противоположно моему методу, описанному выше.
  • В дополнение к AD-Account-DEACTIVATION-Flag у нас есть аналогичный флаг в нашей пользовательской записи.Мой тестовый пользователь фактически был там отключен, и LDAP-модификация была вызвана напрямую, без установки параметра записи пользователя =>, поэтому даже если учетная запись AD не была отключена, моя запись тестового пользователя все еще была отключена и не позволялаlogin.
  • Последнее, но не менее важное: возвращаемое значение фактической попытки заменить значение '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
...