Tải bản đầy đủ (.pdf) (10 trang)

Active Directory Cookbook for windows server 2003- P23 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (36.1 KB, 10 trang )


231
end if
end if
next

End Function
7.3.3 Discussion
As described in Recipe 7.2, group membership is stored in the multivalued member attribute on
group objects. But that attribute will not show the complete picture because group nesting is
allowed in Active Directory after you've transitioned from mixed mode. To view the complete
group membership, you have to recurse through each group's members.
In the VBScript example, I used a dictionary object (referred to as a hash or associative array in
other languages) to ensure I did not get in an infinite loop. The dictionary object stores each
group member; before the DisplayMembers function is called a check is performed to determine
if the group has already been evaluated. If so, a message is displayed indicating the group will
not be processed again. If this type of checking was not employed and you had a situation where
group A was a member of group B, group B was a member of group C, and group C was a
member of group A, the loop would repeat without terminating.
7.3.4 See Also
Recipe 7.2 for viewing group membership and MSDN: IADsMember
Recipe 7.4 Adding and Removing Members of a Group
7.4.1 Problem
You want to add or remove members of a group.
7.4.2 Solution
7.4.2.1 Using a graphical user interface
1. Follow the same steps as in Recipe 7.2 to view the members of the group.
2. To remove a member, click on the member name, click the Remove button, click Yes,
and click OK.
3. To add a member, click on the Add button, enter the name of the member, and click OK
twice.


7.4.2.2 Using a command-line interface
The
-addmbr option adds a member to a group:
> dsmod group "<GroupDN>" -addmbr "<MemberDN>"

232
The -rmmbr option removes a member from a group:
> dsmod group "<GroupDN>" -rmmbr "<MemberDN>"
The -chmbr option replaces the complete membership list:
> dsmod group "<GroupDN>" -chmbr "<Member1DN Member2DN . . . >"
7.4.2.3 Using VBScript
' This code adds a member to a group.
' SCRIPT CONFIGURATION
strGroupDN = "<GroupDN>" ' e.g. cn=SalesGroup,ou=Groups,dc=rallencorp,dc=com
strMemberDN = "<MemberDN>" ' e.g. cn=jsmith,cn=users,dc=rallencorp,dc=com
' END CONFIGURATION

set objGroup = GetObject("LDAP://" & strGroupDN)
' Add a member
objGroup.Add("LDAP://" & strMemberDN)
' This code removes a member from a group.
' SCRIPT CONFIGURATION
strGroupDN = "<GroupDN>" ' e.g. cn=SalesGroup,ou=Groups,dc=rallencorp,dc=com
strMemberDN = "<MemberDN>" ' e.g. cn=jsmith,cn=users,dc=rallencorp,dc=com
' END CONFIGURATION

set objGroup = GetObject("LDAP://" & strGroupDN)
' Remove a member
objGroup.Remove("LDAP://" & strMemberDN)
7.4.3 Discussion

Since there are no restrictions on what distinguished names you put in the member attribute, you
can essentially have any type of object as a member of a group, which makes groups very useful.
While Organizational Units (OUs) are typically used to structure objects that share certain
criteria,
group objects can be used to create loose collections of objects.
The benefit of using group objects as a collection mechanism is that the same object can be a
member of multiple groups whereas an object can only be a part of a single OU. Another key
difference is that you can assign permissions on resources to groups because they are considered
security principals in Active Directory, whereas OUs are not. This is different from some other
directories, such as Novel Netware, where OUs act more like security principals.
7.4.4 See Also
Recipe 7.2 for viewing group membership, MSDN: IADsGroup::Add, and MSDN:
IADsGroup::Remove

233
Recipe 7.5 Moving a Group
7.5.1 Problem
You want to move a group to a different OU or domain.
7.5.2 Solution
To move a group to a different OU, follow the instructions in Recipe 4.17. To move a group to a
different domain, follow the instructions in Recipe 4.18.
7.5.3 Discussion
The only type of group that can be moved between domains are universal groups. If you want to
move a global or domain local group to a different domain, first convert it to a universal group,
move the group, then convert it back to a global or domain local group.
When you convert a group between types, you may encounter problems because different groups
have different membership restrictions. See Introduction in Chapter 7 for more information on
grou type membership restrictions.
A much easier way to accomplish inter-domain group moves is by using the Active Directory
Migration Tool (ADMT). With ADMT, you can move and restructure groups without needing to

go to all the trouble of converting the group to a universal and modifying the group membership.
For more information on ADMT, see the following site:

7.5.4 See Also
Recipe 4.17 for moving an object to a different OU, Recipe 4.18 for moving an object to a
different domain, and Recipe 7.6
for changing group scope and type
Recipe 7.6 Changing the Scope or Type of a Group
7.6.1 Problem
You want to change the scope or type of a group.
7.6.2 Solution
7.6.2.1 Using a graphical user interface
1. Open the Active Directory Users and Computers snap-in.

234
2. If you need to change domains, right-click on Active Directory Users and Computers in
the left pane, select Connect to Domain, enter the domain name, and click OK.
3. In the left pane, right-click on the domain and select Find.
4. Enter the name of the group you want to modify and click Find Now.
5. Double-click on the group in the results pane.
6. In the group properties dialog box, select the new scope or type and click OK.
7.6.2.2 Using a command-line interface
The following example changes the group scope for <GroupDN> to <NewScope>, which should be
l for domain local group, g for global group, or u for universal group.
> dsmod group "<GroupDN>" -scope <NewScope>
The following example changes the group type for <GroupDN>. For the -secgrp switch, specify
yes to change to a security group or no to make the group a distribution list.
> dsmod group "<GroupDN>" -secgrp yes|no
7.6.2.3 Using VBScript
' This code sets the scope and type of the specified group

' to a universal security group.
' SCRIPT CONFIGURATION
strGroupDN = "<GroupDN>" ' e.g. cn=SalesGroup,ou=Groups,dc=rallencorp,dc=com
' END CONFIGURATION

' Constants taken from ADS_GROUP_TYPE_ENUM
ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 1
ADS_GROUP_TYPE_GLOBAL_GROUP = 2
ADS_GROUP_TYPE_LOCAL_GROUP = 4
ADS_GROUP_TYPE_SECURITY_ENABLED = -2147483648
ADS_GROUP_TYPE_UNIVERSAL_GROUP = 8

set objGroup = GetObject("LDAP://" & strGroupDN )
objGroup.Put "groupType", ADS_GROUP_TYPE_UNIVERSAL_GROUP _
Or ADS_GROUP_TYPE_SECURITY_ENABLED
objGroup.SetInfo
7.6.3 Discussion
Group scope and type are stored as a flag in the groupType attribute on group objects. To
directly update
groupType, you must logically OR the values associated with each type and
scope, as shown in the API solution. Note that there is no specific value for the distribution list
type. If you want to create a distribution list, just do not include the
ADS_GROUP_TYPE_SECURITY_ENABLED flag when setting groupType.

For a good description of the usage scenarios for each group type, see
Chapter 11 in Active Directory, Second Edition.


235
7.6.4 See Also

MS KB 231273 (Group Type and Scope Usage in Windows), MSDN:
ADS_GROUP_TYPE_ENUM, and MSDN: What Type of Group to Use
Recipe 7.7 Delegating Control for Managing
Membership of a Group
7.7.1 Problem
You want to delegate control of managing the membership of a group.
7.7.2 Solution
7.7.2.1 Using a graphical user interface

This is a new feature of Windows Server 2003 version of ADUC.

1. Open the Active Directory Users and Computers snap-in.
2. If you need to change domains, right-click on Active Directory Users and Computers in
the left pane, select Connect to Domain, enter the domain name, and click OK.
3. In the left pane, right-click on the domain and select Find.
4. Enter the name of the group and click Find Now.
5. Double-click on the group in the results pane.
6. Select the Managed By tab.
7. Click the Change button.
8. Locate the group or user to delegate control to and click OK.
9. Check the box beside Manager can update membership list.
10. Click OK.
7.7.2.2 Using a command-line interface
> dsacls <GroupDN> /G <GroupName>@DomainName:WP;member;
In the following example, the SalesAdmin group will be given rights to modify membership of
the PreSales group.
> dsacls cn=presales,ou=sales,dc=rallencorp,dc=com /G
:[RETURN]
WP;member;
7.7.2.3 Using VBScript

' This code grants write access to the member attribute of a group.
' SCRIPT CONFIGURATION
strGroupDN = "<GroupDN>" ' e.g. cn=SalesGroup,ou=Sales,dc=rallencorp,dc=com"

236
strUserOrGroup = "<UserOrGroup>" ' e.g. or RALLENCORP\joe
' END CONFIGURATION

set objGroup = GetObject("LDAP://" & strGroupDN)
'############################
' Constants
'############################
' ADS_ACETYPE_ENUM
Const ADS_ACETYPE_ACCESS_ALLOWED_OBJECT = &h5
Const ADS_FLAG_OBJECT_TYPE_PRESENT = &h1
Const ADS_RIGHT_DS_WRITE_PROP = &h20

' From schemaIDGUID of member attribute
Const MEMBER_ATTRIBUTE = "{bf9679c0-0de6-11d0-a285-00aa003049e2}"

'############################
' Create ACL
'############################
set objSD = objGroup.Get("ntSecurityDescriptor")
set objDACL = objSD.DiscretionaryAcl

' Set WP for member attribute
set objACE = CreateObject("AccessControlEntry")
objACE.Trustee = strUserOrGroup
objACE.AccessMask = ADS_RIGHT_DS_WRITE_PROP

objACE.AceFlags = 0
objACE.Flags = ADS_FLAG_OBJECT_TYPE_PRESENT
objACE.AceType = ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
objACE.ObjectType = MEMBER_ATTRIBUTE

objDACL.AddAce objACE

'############################
' Set ACL
'############################
objSD.DiscretionaryAcl = objDACL
objGroup.Put "ntSecurityDescriptor", objSD
objGroup.SetInfo
WScript.Echo "Delegated control of member attribute for " & _
strGroupDN & " to " & strUserOrGroup
7.7.3 Discussion
To grant a user or group the ability to manage group membership, you have to grant the write
property (WP) permission on the
member attribute of the target group. You can add this ACE
directly using dsacls or more indirectly with ADUC. ADUC in Windows Server 2003 has a
new feature that allows you to simply check a box to grant the ability to modify group
membership to the object represented by the managedBy attribute.
If you want to configure additional permissions, such as the ability to modify the
description
attribute for the group, you will need to go to the Security tab in ADUC, or specify the
appropriate attribute with the
/G switch with dsacls. For example, this will grant write property
on the description attribute:

237

/G <GroupName>@DomainDNSName:WP;description;
7.7.4 See Also
Recipe 14.10 for delegating control in Active Directory
Recipe 7.8 Resolving a Primary Group ID
7.8.1 Problem
You want to find the name of a user's primary group.
7.8.2 Solution
7.8.2.1 Using a graphical user interface
1. Open the Active Directory Users and Computers snap-in.
2. If you need to change domains, right-click on Active Directory Users and Computers in
the left pane, select Connect to Domain, enter the domain name, and click OK.
3. In the left pane, right-click on the domain and select Find.
4. Type the name of the user and click Find Now.
5. In the Search Results, double-click on the user.
6. Click the Member Of tab.
7. The Primary Group name is shown on the bottom half of the dialog box.
7.8.2.2 Using VBScript
' This code prints the group name of a user's primary group
' SCRIPT CONFIGURATION
strNTDomain = "<DomainName>" ' NetBios Name of the AD domain, e.g. RALLENCORP
strUser = "<UserName>" ' e.g. Administrator
' END CONFIGURATION

' Iterate over the user's groups and create a search filter
' that contains each group
set objUser = GetObject("WinNT://" & strNTDomain & "/" & strUser & ",user")
strFilter = ""
for each objGroup in objUser.Groups
strFilter = strFilter & "(samAccountName=" & objGroup.Name & ")"
next

strFilter = "(|" & strFilter & ")"

' Now need to perform a search to retrieve each group
' and their primaryGroupToken
strBase = "<LDAP://" & strNTDomain & ">;"
strFilter = "(&(objectcategory=group)" & strFilter & ");"
strAttrs = "name,primaryGroupToken,cn;"
strScope = "subtree;"
set objConn = CreateObject("ADODB.Connection")
objConn.Provider = "ADsDSOObject"
objConn.Open "Active Directory Provider"

238
set objComm = CreateObject("ADODB.Command")
set objComm.ActiveConnection = objConn
objComm.CommandText = strBase & strFilter & strAttrs & strScope
' Be sure to enable paging in case number of groups > 1000
objComm.Properties("Page Size") = 1000
set objRS = objComm.Execute

' Iterate over each group again and stop after a match with the user's
' primaryGroupID has been made
strPrimaryGroup = ""
while ( (not objRS.EOF) and (strPrimaryGroup = "") )
if (objUser.PrimaryGroupID = objRS.Fields("primaryGroupToken").value) then
strPrimaryGroup = objRS.Fields("name").Value
end if
objRS.moveNext
wend
objConn.Close


WScript.Echo "Primary Group for " & strUser & " is " & strPrimaryGroup & _
" (" & objUser.PrimaryGroupID & ")"
7.8.3 Discussion
When trying to determine a user's group membership, you have to look at both user's memberOf
attribute, which contains a list of DNs for each group the user is a member of, and the user's
primary group. By default, all users are assigned Domain Users as their primary group.
Therefore, by default all users in a domain are implicitly members of the Domain Users group.
Unfortunately, a user's primary group will not show up in the memberOf attribute unless
explicitly added.

Services for Macintosh and POSIX-based applications are the main users of
primary groups. If you don't use either of those, you don't need to worry
about changing a user's primary group.

The primary group is stored in the primaryGroupID attribute on user objects. Unfortunately, the
RID of the group is stored in that attribute, not the DN or even sAMAccountName as you might
expect.
group objects have a primaryGroupToken attribute, which contains the same value, but
is a constructed attribute. Because Active Directory dynamically constructs it, you cannot utilize
it in search filters. So even if you have the primaryGroupID of a user, e.g., 513, you cannot do a
simple query to find out which group it is associated with.
You can find the name of a user's primary group relatively easily using the Active Directory
Users and Computers snap-in as I described in the GUI solution. Finding it via a script, on the
other hand, is considerably more complicated. There are a few different ways to go about
determining a group given a primary group ID and they are covered pretty well in MS KB
321360 and 297951. For the API solution, I use the approach I feel is the most efficient.
I first used the WinNT: provider to retrieve a user's groups. The difference between using the
WinNT: provider and using the LDAP: provider is that the WinNT: provider returns the primary


239
group as part of the IADsGroup collection whereas the LDAP: provider does not. Unfortunately,
there is no indication which of the groups is the primary group. So I needed to iterate over each
group and build an LDAP filter that will be used later to retrieve each group using ADO. After I
execute the ADO query, I then iterate over each group and check the primaryGroupToken
attribute of that group to see if it matches the user's primaryGroupID attribute. If it does, I've
found the user's primary group.
7.8.4 See Also
MS KB 297951 (HOWTO: Use the PrimaryGroupID Attribute to Find the Primary Group for a
User) and MS KB 321360 (How to Use Native ADSI Components to Find the Primary Group)
Recipe 7.9 Enabling Universal Group Membership
Caching

This recipe requires the Windows Server 2003 forest functional level.

7.9.1 Problem
You want to enable universal group membership caching so that a global catalog server is not
needed during user logins.
7.9.2 Solution
7.9.2.1 Using a graphical user interface
1. Open the Active Directory Sites and Services snap-in.
2. In the left pane, browse to the site you want to enable group caching for and click on it.
3. In the right pane, double-click on the NTDS Site Settings object.
4. Under Universal Group Membership Caching, check the box beside Enable Universal
Group Caching.
5. If you want to force the cache refresh from a particular site, select a site or else leave the
default set to <Default>.
6. Click OK.
7.9.2.2 Using a command-line interface
You can use a combination of the

dsquery site and dsget site commands to find if a site has
group caching enabled.
> dsquery site -name <SiteName> | dsget site -dn -cachegroups -prefGCSite

240
You can use ldifde to enable group caching. Create a file called enable_univ_cache.ldf with the
following contents, but change <SiteName> to the name of the site you want to enable, and
<ForestRootDN> with the distinguished name of the forest root domain:
dn: cn=NTDS Site
Settings,cn=<SiteName>,cn=sites,cn=configuration,<ForestRootDN>
changetype: modify
replace: options
options: 32
-
Then use the following command to import the change:
> ldifde -i -f enable_univ_cache.ldf
7.9.2.3 Using VBScript
' This code enables universal group caching for the specified site.
' SCRIPT CONFIGURATION
strSiteName = "<SiteName>" ' e.g. Default-First-Site-Name
' END CONFIGURATION

set objRootDSE = GetObject("LDAP://RootDSE")
set objSite = GetObject("LDAP://cn=NTDS Site Settings,cn=" & strSiteName & _
",cn=sites," & objRootDSE.Get("configurationNamingContext") )
objSite.Put "options", 32
objSite.SetInfo
WScript.Echo "Successfully enabled universal group caching for " & _
strSiteName
7.9.3 Discussion

When a client logs on to a Windows 2000 Active Directory domain controller, the domain
controller must contact a global catalog server (if it is not one itself) in order to fully authenticate
the client. This is necessary because of universal groups.
Universal groups can be created and used anywhere in a forest. Objects located anywhere in a
forest can be added as members of a universal group. Since a universal group could be created in
a domain other than where the user object resides, it is necessary to store universal group
membership in the global catalog. That way, during logon, domain controllers can query a global
catalog to determine all universal groups a user is a member of. Microsoft's primary reason for
making this a requirement during logon is that a user could be part of a universal group that has
been explicitly denied access to certain resources. If universal groups aren't evaluated, a user
could gain access to resources that were previously restricted.
To remove this limitation in Windows Server 2003 Active Directory, universal group caching
was introduced. Universal group caching can be enabled on a per site basis and allows domain
controllers to cache universal group information locally, therefore, removing the need to query
the global catalog during client logon.

×