Active Directory Cookbook for windows server 2003- P20 ppt

10 390 0
Active Directory Cookbook for windows server 2003- P20 ppt

Đang tải... (xem toàn văn)

Thông tin tài liệu

201 The value for the unicodePwd attribute must be a Unicode string that is surrounded by quotes and Base64 encoded. See Recipe 10.4 for more on encoding text with Base64. 6.18.3 Discussion The unicodePwd attribute can be directly modified over a SSL or TLS connection, but it can never be read. 6.18.4 See Also Recipe 10.4 for more on Base64 encoding, Recipe 14.1 for enabling SSL/TLS, MS KB 263991 (How to Set a User's Password with Ldifde), MS KB 264480 (Description of Password-Change Protocols in Windows 2000), and MS KB 269190 (HOWTO: Change a Windows 2000 User's Password Through LDAP) Recipe 6.19 Setting a User's Password via Kerberos 6.19.1 Problem You want to change a password using Kerberos from a Unix machine. 6.19.2 Solution If you have MIT Kerberos 5 client installed and configured properly, you can run the following commands, which will change your password in Active Directory: $ kinit Password for jsmith@RALLENCORP.COM: **** $ kpasswd Password for jsmith@RALLENCORP.COM: **** Enter new password: ****** Enter it again: ****** Password changed. 6.19.3 Discussion See Recipe 18.7 for more information on Kerberos. 6.19.4 See Also MS KB 264480 (Description of Password-Change Protocols in Windows 2000), RFC 3244 (Microsoft Windows 2000 Kerberos Change Password and Set Password Protocols), and IETF draft-ietf-cat-kerb-chg-password-02.txt 202 Recipe 6.20 Preventing a User from Changing His Password 6.20.1 Problem You want to disable a user's ability to change his password. 6.20.2 Solution 6.20.2.1 Using a graphical user interface 1. Open the Active Directory Users and Computers snap-in. 2. In the left pane, right-click on the domain and select Find. 3. Select the appropriate domain beside In. 4. Beside Name, type the name of the user you want to modify and click Find Now. 5. In the Search Results, double-click on the user. 6. Click the Account tab. 7. Under Account options, check the box beside User cannot change password. 8. Click OK. 6.20.2.2 Using a command-line interface > dsmod user <UserDN> -canchpwd no 6.20.2.3 Using VBScript ' This code disables a user's ability to change password ' SCRIPT CONFIGURATION strUserDN = "<UserDN>" ' e.g. cn=rallen,ou=Sales,dc=rallencorp,dc=com ' END CONFIGURATION Const ACETYPE_ACCESS_DENIED_OBJECT = 6 Const ACEFLAG_OBJECT_TYPE_PRESENT = 1 Const RIGHT_DS_CONTROL_ACCESS = 256 Const CHANGE_PASSWORD_GUID = "{ab721a53-1e2f-11d0-9819-00aa0040529b}" set objUser = GetObject("LDAP://" & strUserDN) set objSD = objUser.Get("ntSecurityDescriptor") set objDACL = objSD.DiscretionaryAcl ' Add a deny ACE for Everyone set objACE = CreateObject("AccessControlEntry") objACE.Trustee = "Everyone" objACE.AceFlags = 0 objACE.AceType = ACETYPE_ACCESS_DENIED_OBJECT objACE.Flags = ACEFLAG_OBJECT_TYPE_PRESENT objACE.ObjectType = CHANGE_PASSWORD_GUID objACE.AccessMask = RIGHT_DS_CONTROL_ACCESS objDACL.AddAce objACE ' Add a deny ACE for Self set objACE = CreateObject("AccessControlEntry") 203 objACE.Trustee = "Self" objACE.AceFlags = 0 objACE.AceType = ACETYPE_ACCESS_DENIED_OBJECT objACE.Flags = ACEFLAG_OBJECT_TYPE_PRESENT objACE.ObjectType = CHANGE_PASSWORD_GUID objACE.AccessMask = RIGHT_DS_CONTROL_ACCESS objDACL.AddAce objACE objSD.DiscretionaryAcl = objDACL objUser.Put "nTSecurityDescriptor", objSD objUser.SetInfo WScript.Echo "Enabled no password changing for " & strUserDN 6.20.3 Discussion Even though in the GUI solution you check and uncheck the "User cannot change password" setting, actually making the change in Active Directory is a little more complicated as is evident in the VBScript solution. Not allowing a user to change her password consists of setting two deny Change Password ACEs on the target user object. One deny ACE is for the Everyone account and the other is for Self. The VBScript solution should work as is, but it is not very robust in terms of checking to see if the ACEs already exist and making sure they are in the proper order. If you need to make the code more robust, I suggest checking out MS KB 269159 for more information on setting ACEs properly. 6.20.4 See Also MS KB 269159 (HOWTO: Use Visual Basic and ADsSecurity.dll to Properly Order ACEs in an ACL) Recipe 6.21 Requiring a User to Change Her Password at Next Logon 6.21.1 Problem You want to require a user to change her password the next time she logs on to the domain. 6.21.2 Solution 6.21.2.1 Using a graphical user interface 1. Open the Active Directory Users and Computers snap-in. 2. In the left pane, right-click on the domain and select Find. 3. Select the appropriate domain beside In. 4. Beside Name, type the name of the user you want to modify and click Find Now. 5. In the Search Results, double-click on the user. 204 6. Click the Account tab. 7. Under Account options, check the box beside User must change password at next logon. 8. Click OK. 6.21.2.2 Using a command-line interface > dsmod user "<UserDN>" -mustchpwd yes 6.21.2.3 Using VBScript ' This code sets the flag that requires a user to change their password ' SCRIPT CONFIGURATION strUserDN = "<UserDN>" ' e.g. cn=rallen,ou=Sales,dc=rallencorp,dc=com ' END CONFIGURATION set objUser = GetObject("LDAP://" & strUserDN) objUser.Put "pwdLastSet", 0 objUser.SetInfo WScript.Echo "User must change password at next logon: " & strUserDN 6.21.3 Discussion When a user changes her password, a timestamp is written to the pwdLastSet attribute of the user object. When the user logs in to the domain, this timestamp is compared to the maximum password age that is defined by the Domain Security Policy to determine if the password has expired. To force a user to change her password at next logon, set the pwdLastSet attribute of the target user to and verify that the user's account doesn't have the never expire password option enabled. To disable this option so that a user does not have to change her password, set pwdLastSet to -1. These two values (0 and -1) are the only ones that can be set on the pwdLastSet attribute. Recipe 6.22 Preventing a User's Password from Expiring 6.22.1 Problem You want to prevent a user's password from expiring. 6.22.2 Solution 6.22.2.1 Using a graphical user interface 1. Open the Active Directory Users and Computers snap-in. 2. In the left pane, right-click on the domain and select Find. 3. Select the appropriate domain beside In. 4. Beside Name, type the name of the user you want to modify and click Find Now. 5. In the Search Results, double-click on the user. 6. Click the Account tab. 205 7. Under Account options, check the box beside Password never expires. 8. Click OK. 6.22.2.2 Using a command-line interface > dsmod user "<UserDN>" -pwdneverexpires yes 6.22.2.3 Using VBScript ' This code sets a users password to never expire ' See Recipe 4.12 for the code for the CalcBit function ' SCRIPT CONFIGURATION strUserDN = "<UserDN>" ' e.g. cn=rallen,ou=Sales,dc=rallencorp,dc=com ' END CONFIGURATION intBit = 65536 strAttr = "userAccountControl" set objUser = GetObject("LDAP://" & strUserDN) intBitsOrig = objUser.Get(strAttr) intBitsCalc = CalcBit(intBitsOrig, intBit, TRUE) if intBitsOrig <> intBitsCalc then objUser.Put strAttr, intBitsCalc objUser.SetInfo WScript.Echo "Changed " & strAttr & " from " & _ intBitsOrig & " to " & intBitsCalc else WScript.Echo "Did not need to change " & strAttr & " (" & _ intBitsOrig & ")" end if 6.22.3 Discussion Setting a user's password to never expire overrides any password aging policy you've defined in the domain. To disable password expiration, you need to set the bit equivalent of 65536 (i.e., 10000000000000000) in the userAccountControl attribute of the target user. 6.22.4 See Also Recipe 4.12 for more on modifying a bit-flag attribute and Recipe 6.24 for more on setting the userAccountControl attribute Recipe 6.23 Finding Users Whose Passwords Are About to Expire 6.23.1 Problem You want to find the users whose passwords are about to expire. 206 6.23.2 Solution 6.23.2.1 Using a command-line interface > dsquery user -stalepwd <NumDaysSinceLastPwdChange> 6.23.2.2 Using Perl #!perl # This code finds the user accounts whose password is about to expire # SCRIPT CONFIGURATION # Domain and container/OU to check for accounts that are about to expire my $domain = '<DomainDNSName>'; my $cont = ''; # set to empty string to query entire domain # Or set to a relative path in the domain, e.g. cn=Users # Days since password change my $days_ago = <NumDaysSinceLastPwdChange> # e.g. 60; # END CONFIGURATION use strict; use Win32::OLE; $Win32::OLE::Warn = 3; use Math::BigInt; # Need to convert the number of seconds from $day_ago # to a large integer for comparison against pwdLastSet my $past_secs = time - 60*60*24*$days_ago; my $intObj = Math::BigInt->new($past_secs); $intObj = Math::BigInt->new($intObj->bmul('10 000 000')); my $past_largeint = Math::BigInt->new( $intObj->badd('116 444 736 000 000 000')); $past_largeint =~ s/^[+-]//; # Setup the ADO connections my $connObj = Win32::OLE->new('ADODB.Connection'); $connObj->{Provider} = "ADsDSOObject"; # Set these next two if you need to authenticate # $connObj->Properties->{'User ID'} = '<User>'; # $connObj->Properties->{'Password'} = '<Password>'; $connObj->Open; my $commObj = Win32::OLE->new('ADODB.Command'); $commObj->{ActiveConnection} = $connObj; $commObj->Properties->{'Page Size'} = 1000; # Grab the default domain naming context my $rootDSE = Win32::OLE->GetObject("LDAP://$domain/RootDSE"); my $rootNC = $rootDSE->Get("defaultNamingContext"); # Run ADO query and print results $cont .= "," if $cont and not $cont =~ /,$/; my $query = "<LDAP://$domain/$cont$rootNC>;"; $query .= "(&(objectclass=user)"; $query .= "(objectcategory=Person)"; $query .= "(!useraccountcontrol:1.2.840.113556.1.4.803:=2)"; $query .= "(pwdLastSet<=$past_largeint)"; $query .= "(!pwdLastSet=0));"; $query .= "cn,distinguishedName;"; $query .= "subtree"; $commObj->{CommandText} = $query; 207 my $resObj = $commObj->Execute($query); die "Could not query $domain: ",$Win32::OLE::LastError,"\n" unless ref $resObj; print "\nUsers who haven't set their passwd in $days_ago days or longer:\n"; my $total = 0; while (!($resObj->EOF)) { print "\t",$resObj->Fields("distinguishedName")->value,"\n"; $total++; $resObj->MoveNext; } print "Total: $total\n"; 6.23.3 Discussion When a Windows-based client logs on to Active Directory, a check is done against the domain password policy and the user's pwdLastSet attribute to determine if the user's password has expired. If it has, the user is prompted to change it. In a pure Windows-based environment, this notification process may be adequate, but if you have a lot of non-Windows-based computers that are joined to an Active Directory domain (e.g., Kerberos-enabled Unix clients), or you have a lot of application and service accounts, you'll need to develop your own user password expiration notification process. Even in a pure Windows environment, cached logins present a problem because when a user logs into the domain with cached credentials (i.e., when the client is not able to reach a domain controller), this password expiration notification check is not done. The process of finding users whose passwords are about to expire is a little complicated. Fortunately, the new dsquery user command helps by providing an option for searching for users that haven't changed their password for a number of days (-stalepwd). The downside to the dsquery user command is that it will not only find users whose password is about to expire, but also users that must change their password at next logon (i.e., pwdLastSet = 0). The Perl solution does not suffer from this limitation. The Perl solution consists of a two-step process. First, we need to calculate a time in the past at which we would consider a password "old" or "about" to expire. The pwdLastSet attribute is a replicated attribute on user objects that contain the timestamp (as a large integer) of when the user last set her password. If today is May 31 and we want to find all users who have not set their password for 30 days, we need to query for user's who have a pwdLastSet timestamp older than May 1. First, a brief word on timestamps stored as large integers. It may seem odd, but large integer timestamps are represented as the number of 100-nanosecond intervals since January 1, 1601. To convert the current time to a large integer, we have to find the current time in seconds since the epoch (January 1, 1970) multiply that times 10,000,000 and then add 116,444,736,000,000,000 to it. This will give you an approximate time (in 100-nanosecond intervals) as a large integer. It is only an approximate time because when dealing with big numbers like this, a degree of accuracy is lost during the arithmetic. 208 I chose to use Perl over VBScript because VBScript doesn't handle computing large integers given the current time and date very well. All right, now that you know how to calculate the current time, we need to calculate a time in the past as a large integer. Remember, we need to find the time at which passwords are considered close to expiring. In the Perl solution, you can configure the number of days since users changed their password. Once we've calculated this value, all we need is to come up with a search filter that we can use in ADO to find the matching users. The first part of the filter will match all user objects. $query .= "(&(objectclass=user)"; $query .= "(objectcategory=Person)"; But we really only want to find all enabled user objects (do you care if a disabled user object's password is about to expire?). This next bit-wise filter will match only enabled user objects. See Recipe 6.13 for more information on finding disabled and enabled users. $query .= "(!useraccountcontrol:1.2.840.113556.1.4.803:=2)"; The next part of the filter is the important part. This is where we use the derived last password change timestamp to compare against pwdLastSet. $query .= "(pwdLastSet<=$past_largeint)"; Finally, we exclude all users that are required to change their password at next logon (pwdLastSet equal to zero). $query .= "(!pwdLastSet=0));"; 6.23.4 See Also Recipe 6.11 for more on the password policy for a domain, Recipe 6.17 for how to set a user's password, and Recipe 6.22 for how to set a user's password to never expire Recipe 6.24 Setting a User's Account Options (userAccountControl) 6.24.1 Problem You want to view or update the userAccountControl attribute for a user. This attribute controls various account options, such as if the user must change their password at next logon and if the account is disabled. 209 6.24.2 Solution 6.24.2.1 Using a graphical user interface 1. Open the Active Directory Users and Computers snap-in. 2. In the left pane, right-click on the domain and select Find. 3. Select the appropriate domain beside In. 4. Beside Name, type the name of the user and click Find Now. 5. In the Search Results, double-click on the user. 6. Select the Account tab. 7. Many of the userAccountControl flags can be set under Account options. 8. Click OK after you're done. 6.24.2.2 Using a command-line interface The dsmod user command has several options for setting various userAccountControl flags, as shown in Table 6-2. Each switch accepts yes or no as a parameter to either enable or disable the setting. Table 6-2. dsmod user options for setting userAccountControl dsmod user switch Description -mustchpwd Sets whether the user must change password at next logon. -canchpwd Sets whether the user can change his password. -disabled Set account status to enabled or disabled. -reversiblepwd Sets whether the user's password is stored using reversible encryption. -pwdneverexpires Sets whether the user's password never expires. 6.24.2.3 Using VBScript ' This code enables or disables a bit value in the userAccountControl attr. ' See Recipe 4.12 for the code for the CalcBit function. ' SCRIPT CONFIGURATION strUserDN = "<UserDN>" ' e.g. cn=rallen,ou=Sales,dc=rallencorp,dc=com intBit = <BitValue> ' e.g. 65536 boolEnable = <TrueOrFalse> ' e.g. TRUE ' END CONFIGURATION strAttr = "userAccountControl" set objUser = GetObject("LDAP://" & strUserDN) intBitsOrig = objUser.Get(strAttr) intBitsCalc = CalcBit(intBitsOrig, intBit, boolEnable) if intBitsOrig <> intBitsCalc then objUser.Put strAttr, intBitsCalc objUser.SetInfo WScript.Echo "Changed " & strAttr & " from " & _ 210 intBitsOrig & " to " & intBitsCalc else WScript.Echo "Did not need to change " & strAttr & " (" & _ intBitsOrig & ")" end if 6.24.3 Discussion The userAccountControl attribute on user (and computer) objects could be considered the kitchen sink of miscellaneous and sometimes completely unrelated user account properties. If you have to work with creating and managing user objects very much, you'll need to become intimately familiar with this attribute. The userAccountControl attribute is a bit flag, which means you have to take a couple extra steps to search against it or modify it. See Recipe 4.9 for more on searching with a bit-wise filter and Recipe 4.12 for modifying a bit-flag attribute. The dsmod user command can be used to modify a subset of userAccountControl properties, as shown in Table 6-2. Table 6-3 contains the complete list userAccountControl properties as defined in the ADS_USER_FLAG_ENUM enumeration. Table 6-3. ADS_USER_FLAG_ENUM values Name Value Description ADS_UF_SCRIPT 1 Logon script is executed. ADS_UF_ACCOUNTDISABLE 2 Account is disabled. ADS_UF_HOMEDIR_REQUIRED 8 Home Directory is required. ADS_UF_LOCKOUT 16 Account is locked out. ADS_UF_PASSWD_NOTREQD 32 A password is not required. ADS_UF_PASSWD_CANT_CHANGE 64 Read-only flag that indicates cannot change their passwor d ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED 128 Store password using reversi b ADS_UF_TEMP_DUPLICATE_ACCOUNT 256 Account provides access to t h no other domain that trusts t h ADS_UF_NORMAL_ACCOUNT 512 Enabled user account. ADS_UF_INTERDOMAIN_TRUST_ACCOUNT 2048 A permit to trust account for domain that trusts other dom a ADS_UF_WORKSTATION_TRUST_ACCOUNT 4096 Enabled computer account. ADS_UF_SERVER_TRUST_ACCOUNT 8192 Computer account for backu p . following commands, which will change your password in Active Directory: $ kinit Password for jsmith@RALLENCORP.COM: **** $ kpasswd Password for jsmith@RALLENCORP.COM: **** Enter new password:. Discussion See Recipe 18.7 for more information on Kerberos. 6.19.4 See Also MS KB 264480 (Description of Password-Change Protocols in Windows 2000), RFC 3244 (Microsoft Windows 2000 Kerberos Change. change it. In a pure Windows- based environment, this notification process may be adequate, but if you have a lot of non -Windows- based computers that are joined to an Active Directory domain (e.g.,

Ngày đăng: 05/07/2014, 08:20

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan