userAccountControl
является битовой маской, поэтому вы должны использовать оператор or
для объединения флагов, а не оператор +
.
Но, что более важно, в соответствии с Как использовать флажки UserAccountControl для управления свойствами учетной записи пользователя :
PASSWD_CANT_CHANGE
Примечание: Вы не можете назначить это разрешение, напрямую изменив атрибут UserAccountControl . Сведения о том, как установить разрешение программно, см. В разделе «Описания флагов свойств».
Где в разделе «Описания флагов свойств» указано:
Эта страница, в свою очередь, гласит:
Возможность пользователя изменить свой пароль - это разрешение, которое может быть предоставлено или отклонено. Чтобы отказать в этом разрешении, задайте два ACE в списке управления доступом на уровне дескриптора безопасности (DACL) объекта пользователя с типом ADS_ACETYPE_ACCESS_DENIED_OBJECT . Один ACE отклоняет разрешение для пользователя, а другой ACE запрещает разрешение группе «Все». Оба ACE являются объектно-определяемыми c, запрещающими ACE, которые указывают GUID расширенного разрешения для смены паролей. Чтобы предоставить это разрешение, установите те же ACE с ADS_ACETYPE_ACCESS_ALLOWED_OBJECT типа туза .
Следующая процедура описывает, как изменить или добавить ACE для этого разрешения.
Чтобы изменить или добавить элементы ACE для этого разрешения
Привязать к объекту пользователя.
Получить объект IADsSecurityDescriptor
из ntSecurityDescriptor
свойство объекта пользователя.
Получите интерфейс IADsAccessControlList
для дескриптора безопасности из свойства IADsSecurityDescriptor.DiscretionaryAcl
.
Перечислите ACE для объекта и найдите ACE, которые имеют GUID смены пароля ({AB721A53-1E2F-11D0-9819-00AA0040529B}
) для свойства IADsAccessControlEntry.ObjectType
и "Everyone" или "NT AUTHORITY \ SELF" для свойства IADsAccessControlEntry.Trustee
.
Примечание. Строки «Все» и «NT AUTHORITY \ SELF» локализуются на основе языка первого контроллера домена в домене. Из-за этого строки не должны использоваться напрямую. Имена учетных записей должны быть получены во время выполнения путем вызова функции LookupAccountSid
с SID для «Все» («S-1-1-0») и «NT AUTHORITY \ SELF» («S-1-5-10»). ") известные руководители безопасности. Примеры функций GetSidAccountName
, GetSidAccountName_Everyone
и GetSidAccountName_Self
C ++, показанные в Чтение пользователя не может изменить пароль (поставщик LDAP) , демонстрируют, как это сделать.
Измените свойство IADsAccessControlEntry.AceType
ACE, которые были найдены, на ADS_ACETYPE_ACCESS_DENIED_OBJECT
, если пользователь не может изменить свой пароль, или ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
, если пользователь может изменить свой пароль.
Если ACE «Все» не найден, создайте новый объект IADsAccessControlEntry
, который содержит значения свойств, показанные в таблице ниже, и добавьте новую запись в ACL с помощью метода IADsAccessControlList.AddAce
.
Если ACE "NT AUTHORITY \ SELF" не найден, создайте новый объект IADsAccessControlEntry
с такими же значениями свойств, которые показаны в таблице ниже, за исключением того, что свойство Trustee содержит имя учетной записи для SID "S-1-5-10 "(" NT AUTHORITY \ SELF "). Добавьте запись в ACL с помощью метода IADsAccessControlList.AddAce
.
Чтобы обновить свойство ntSecurityDescriptor
объекта, вызовите метод IADs.Put
с тем же IADsSecurityDescriptor
, полученным в Шаг 2.
Подтвердите локальные изменения на сервере с помощью метода IADs.SetInfo
.
Если любой из ACE был создан, вы необходимо изменить порядок ACL, чтобы ACE были в правильном порядке. Для этого вызовите функцию GetNamedSecurityInfo
с LDAP ADsPath объекта, а затем функцию SetNamedSecurityInfo
с тем же DACL. Это переупорядочение произойдет автоматически при добавлении ACE.
В следующей таблице перечислены значения свойств объекта IADsAccessControlEntry
.
AccessMask
ADS_RIGHT_DS_CONTROL_ACCESS
AceType
ADS_ACETYPE_ACCESS_DENIED_OBJECT
, если пользователь не может изменить свой пароль, или ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
, если пользователь может изменить свой пароль.
AceFlags
0
Flags
ADS_FLAG_OBJECT_TYPE_PRESENT
ObjectType
"{AB721A53-1E2F-11D0-9819-00AA0040529B}" ", который представляет собой GUID для смены пароля в виде строки.
InheritedObjectType
Не используется
Trustee
Имя учетной записи для SID "S-1-1-0" (Все).
Там довольно длинный пример кода на той же странице.