| Class | RADUM::User |
| In: |
lib/radum/user.rb
|
| Parent: | Object |
The User class represents a standard Windows user account.
| container | [R] | The Container object the User or UNIXUser belongs to. |
| groups | [R] | The Group or UNIXGroup objects the User or UNIXUser is a member of. User and UNIXUser objects are implicit members of their primary_group as well, but that is not added to the groups array directly. This matches the implicit membership in the primary Windows group in Active Directory. |
| removed_groups | [R] | An array of Group or UNIXGroup objects removed from the User or UNIXUser. |
| rid | [R] | The RID of the User or UNIXUser object. This corresponds to part of the LDAP objectSid attribute. This is set when the User or UNIXUser is loaded by AD#load from the AD object the Container belogs to. This attribute should not be specified in the User.new method when creating a new User or UNIXUser by hand. |
| username | [R] | The User or UNIXUser object username. This corresponds to the LDAP sAMAccountName and msSFU30Name attributes. This is also used for part of the LDAP userPrincipalName attribute. This does not contain any LDAP path components, unlike the Container objet‘s name attribute (because Containers can be different types of objects, like a cn=name or ou=name). |
Create a new User object that represents a Windows user in Active Directory. This method takes a Hash containing arguments, some of which are required and others optional. The supported arguments follow:
The :username argument (case-insensitive) and the :rid argument must be unique in the AD object, otherwise a RuntimeError is raised. The :username argument has leading and trailing white space removed. The :primary_group argument must be of the RADUM group type GROUP_GLOBAL_SECURITY or GROUP_UNIVERSAL_SECURITY and not a removed group, otherwise a RuntimeError is raised. The :disabled argument indicates if the User object should be disabled, and it defaults to false. The :rid argument should not be set directly except from the AD#load method itself. The User object automatically adds itself to the Container object specified by the :container argument.
Note that a User will not be forced to change their Windows password on their first login unless this is changed by calling the toggle_must_change_password method. If no password is set for the User, a random password will be generated. The random password will probably meet Group Policy password security requirements, but it is suggested that a password be set to ensure this is the case, otherwise setting the User password during Active Directory creation might fail, which results in a disabled Active Directory user account that has no password.
One difference with respect to the Active Directory Users and Computers GUI tool should be noted. When creating user accounts with the GUI tool, the LDAP cn attribute is set to "first_name initials. surname" and that is what is displayed in the Name column in the tool. This means you cannot create user accounts with the same first name, initials, and surname. RADUM uses the username as the LDAP cn attribute (it really just does not specify that when the first step is done creating an initial acocunt). This means that you can have two user accounts with different usernames but with the same first name, initials, and surname. In the RADUM case, the Name column in the GUI tool shows the username. RADUM adds the "first_name initals. surname" string to the LDAP description attribute, so the GUI tool shows that in the Description column, therefore all the useful information is there (by default the LDAP description attribute is blank). This implementation detail was chosen because it seemed like the best choice, otherwise the username and a combination of other name attributes would have to be all checked for unique values instead of just the username itself, and by default having the username and other name attributes (if set) show up in the GUI tool is more useful in the opinion of the author.
See the documentation for each attribute method for what the default values of each attribute is based on calling this method.
# File lib/radum/user.rb, line 87
87: def initialize(args = {})
88: @rid = args[:rid] || nil
89: @container = args[:container] or raise "User :container argument" +
90: " required."
91:
92: # The RID must be unique.
93: if @container.directory.rids.include?(@rid)
94: raise "RID #{rid} is already in use in the directory."
95: end
96:
97: @username = args[:username] or raise "User :username argument required."
98: @username.strip!
99:
100: # The username (sAMAccountName) must be unique (case-insensitive). This
101: # is needed in case someone tries to make the same username in two
102: # different containers.
103: if @container.directory.find_user_by_username(@username)
104: raise "User is already in the directory."
105: end
106:
107: @primary_group = args[:primary_group] or raise "User :primary_group" +
108: " argument required."
109:
110: if @primary_group.removed?
111: raise "User primary_group cannot be a removed group."
112: end
113:
114: # The primary group must be of one of these two types. It appears you can
115: # change a group's type to GROUP_DOMAIN_LOCAL_SECURITY in the AD Users and
116: # Groups tool if someone has that as their primary group, but you can't
117: # set a group of that type as someone's primary group. You can't change
118: # the type of a group to anything that has an AD group type of
119: # "Distribution" most definitely. The AD group type must be "Security"
120: # for primary groups. I am just going to avoid as much confusion as
121: # possible unless someone were to complain.
122: unless @primary_group.type == GROUP_GLOBAL_SECURITY ||
123: @primary_group.type == GROUP_UNIVERSAL_SECURITY
124: raise "User primary group must be of type GROUP_GLOBAL_SECURITY" +
125: " or GROUP_UNIVERSAL_SECURITY."
126: end
127:
128: @disabled = args[:disabled] || false
129: @distinguished_name = "cn=" + @username + "," + @container.name +
130: "," + @container.directory.root
131: @groups = []
132: @removed_groups = []
133: @first_name = @username
134: @initials = nil
135: @middle_name = nil
136: @surname = nil
137: # These are attributes of the Profile tab in Active Directory Users and
138: # Computers.
139: @script_path = nil
140: @profile_path = nil
141: # The local_path variable is set alone if it represents the "Local
142: # path" part of the Home folder section of the Profile tab. In this
143: # case, local_drive should be left nil. If it is used to represent the
144: # "Connect" part of the Home folder section of the Profile tab,
145: # local_path and local_drive should both be set. Note that these
146: # two options in the Home folder section of the Profile tab are mutually
147: # exclusive. This is enforced in the setter methods. Also note these
148: # variables represent the following LDAP attributes:
149: #
150: # local_path --> homeDirectory
151: # local_drive --> homeDrive
152: #
153: # I am using these names because there is a home_directory instance
154: # variable to represent UNIX home directories, and the way these are
155: # set with the methods defined in this class better reflect the Active
156: # Directory Users and Computers tool.
157: @local_path = nil
158: @local_drive = nil
159: # Password related instance variables. The password itself is not
160: # reflected here unless we are trying to change it to a new value
161: # (otherwise it is just nil).
162: @password = nil
163: @must_change_password = false
164: # This has to be set first before adding the User to the Container. This
165: # is delayed for a UNIXUser because it needs the rest of its attributes
166: # set before adding to the Container.
167: @removed = false
168: @container.add_user self unless instance_of?(UNIXUser)
169: @modified = true
170: @loaded = false
171: end
Make the User or UNIXUser a member of the Group or UNIXGroup. This is represented in the LDAP member attribute for the Group or UNIXGroup. A User or UNIXUser is listed in the Group or UNIXGroup LDAP member attribute unless it is the User or UNIXUser object‘s primary_group. In that case, the User or UNIXUser object‘s membership is based solely on the User or UNIXUser object‘s LDAP primaryGroupID attribute (which contains the RID of that Group or UNIXGroup - the Group or UNIXGroup does not list the User or UNIXUser in its LDAP member attribute, hence the logic in the code). The unix_main_group for UNIXUsers has the UNIXUser as a member in a similar way based on the LDAP gidNumber attribute for the UNIXUser. The UNIXGroup object‘s LDAP memberUid and msSFU30PosixMember attributes do not list the UNIXUser as a member if the UNIXGroup is their unix_main_group, but this module makes sure UNIXUsers are also members of their unix_main_group from the Windows perspective. A RuntimeError is raised if the User or UNIXUser already has this Group or UNIXGroup as their primary_group or if the Group or UNIXGroup is not in the same AD object. A RuntimeError is raised if the Group or UNIXGroup has been removed.
This automatically adds the User or UNIXUser to the Group or UNIXGroup object‘s list of users.
# File lib/radum/user.rb, line 524
524: def add_group(group)
525: if group.removed?
526: raise "Cannot add a removed group."
527: end
528:
529: if @container.directory == group.container.directory
530: unless @primary_group == group
531: @groups.push group unless @groups.include?(group)
532: @removed_groups.delete group
533: group.add_user self unless group.users.include?(self)
534: else
535: raise "User is already a member of their primary group."
536: end
537: else
538: raise "Group must be in the same directory."
539: end
540: end
Set the User or UNIXUser "Connect … To" in the Active Directory Users and Computers Profile tab Home folder section. One can either set the "Connect … To" or set the "Local path" part of the Home folder section. This sets the LDAP homeDrive and homeDirectory attributes. If you want to simply set a "Local path" for the Home folder, use the User#local_path= method instead.
As an example, to connect drive Z: to \\server\share, do the following on a User or UNIXUser object named user:
user.connect_drive_to "Z:", "\\\\server\\share"
These values can be retrived using:
user.local_drive # --> "Z:" user.local_path # --> "\\server\share"
The user.local_path value is also used by itself if only the "Local path" was set for the Home folder section of the Profile tab in Active Directory Users and Computers using the User#local_path= method, but here it is also used in this case as well.
# File lib/radum/user.rb, line 394
394: def connect_drive_to(drive, path)
395: @local_drive = drive
396: @local_path = path
397: @modified = true
398: end
The LDAP distinguishedName attribute for this User or UNIXUser. The default value is the username, Container, and AD root. The value should only be different if an account is loaded that was created by the Active Directory Users and Computers tool or some other mechanism.
# File lib/radum/user.rb, line 199
199: def distinguished_name
200: @distinguished_name
201: end
Set the User or UNIXUser first name. This corresponds to the LDAP givenName attribute and is used in the LDAP displayName, description, and name attributes. This defaults to the username when a User or UNIXUser is created using User.new or UNIXUser.new, but is set to the correct value when a User or UNIXUser is loaded by AD#load from the AD object the Container belongs to.
# File lib/radum/user.rb, line 237
237: def first_name=(first_name)
238: @first_name = first_name
239: @modified = true
240: end
Set the User or UNIXUser middle initials. This is usually what is set instead of their middle name when creating user accounts using the Active Directory Users and Computers GUI tool. The "." should not be added as it will be automatically displayed when necessary.
# File lib/radum/user.rb, line 255
255: def initials=(initials)
256: @initials = initials
257: @modified = true
258: end
The drive used in the User#connect_drive_to method when setting the "Connect … To" Home folder section of the Active Directory Users and Computers Profile tab section. This value should be used in conjunction with the User#local_path value if the User#connect_drive_to method was called.
# File lib/radum/user.rb, line 364
364: def local_drive
365: @local_drive
366: end
The "Local path" represented in the Active Directory Users and Computers Profile tab Home folder section. This also represents the path value used in the User#connect_drive_to method and is used in conjunction with User#local_drive in the case User#connect_drive_to was called instead of simply calling the User#local_path= method.
# File lib/radum/user.rb, line 338
338: def local_path
339: @local_path
340: end
Set the User or UNIXUser "Local path" in the Active Directory Users and Computers Profile tab Home folder section. One can either set the "Local path" or set the "Connect … To" part of the Home folder section. This sets the LDAP homeDirectory attribute only. If you want to connect a drive to a path for the Home folder, use then User#connect_drive_to method instead. Note that this method makes sure that the homeDrive LDAP attribute is not set to enforce the proper behavior on the LDAP side.
# File lib/radum/user.rb, line 353
353: def local_path=(path)
354: @local_drive = nil
355: @local_path = path
356: @modified = true
357: end
Determine if a User or UNIXUser is a member of the Group or UNIXGroup. This also evaluates to true if the Group or UNIXGroup is the User or UNIXUser object‘s primary_group.
# File lib/radum/user.rb, line 591
591: def member_of?(group)
592: # Group memberships are removed when groups are removed so there is
593: # no need to check the group's removed status.
594: @groups.include?(group) || @primary_group == group
595: end
Set the User or UNIXUser middle name. This corresponds to the LDAP middleName attribute and is used in the LDAP displayName and description attributes. This defaults to nil when a User or UNIXUser is created using User.new or UNIXUser.new, but is set to the correct value when a User or UNIXUser is loaded by AD#load from the AD object the Container belongs to.
# File lib/radum/user.rb, line 274
274: def middle_name=(middle_name)
275: @middle_name = middle_name
276: @modified = true
277: end
Check if the User or UNIXUser has to change their Windows password on their first login. Returns true if this is the case, false otherwise. This defaults to false when User or UNIXUser objects are created.
# File lib/radum/user.rb, line 430
430: def must_change_password?
431: @must_change_password
432: end
The User or UNIXUser Windows password. This is only set to a value other than nil if the password should be changed on the next AD#sync call. Once the User or UNIXUser is synchronized with Active Directory, the password attribute is set to nil again. This is because the password attribute does not actually reflect the current Active Directory user password, which cannot be read through LDAP directly.
# File lib/radum/user.rb, line 406
406: def password
407: @password
408: end
Set the User or UNIXUser Windows password. This defaults to nil when a User or UNIXUser is created using User.new or UNIXUser.new. This does not reflect the current User or UNIXUser password, but if it is set, the password will be changed. Once the User or UNIXUser is synchronized with Active Directory using AD#sync the password attribute is set to nil again. This is because the password attribute does not actually reflect the current Active Directory user password, which cannot be read through LDAP directly.
# File lib/radum/user.rb, line 422
422: def password=(password)
423: @password = password
424: @modified = true
425: end
The User or UNIXUser primary Windows group. This is usually the "Domain Users" Windows group. User and UNIXUser objects are not members of this group directly. They are members through their LDAP primaryGroupID attribute.
# File lib/radum/user.rb, line 453
453: def primary_group
454: @primary_group
455: end
Set the User or UNIXUser primary Windows group. The primary Windows group is used by the POSIX subsystem. This is something that Windows typically ignores in general, and User or UNIXUser objects are members implicitly by their LDAP primaryGroupID attribute. The Group or UNIXGroup specified must be of the RADUM group type GROUP_GLOBAL_SECURITY or GROUP_UNIVERSAL_SECURITY or a RuntimeError is raised. The Group or UNIXGroup specified must be in the same AD object or a RuntimeError is raised. A RuntimeError is raised if the Group or UNIXGroup has been removed.
When a User or UNIXUser changes their primary Windows group, they are automatically given normal group membership in the old primary Windows group by Active Directory. This method does the same.
# File lib/radum/user.rb, line 474
474: def primary_group=(group)
475: if group.removed?
476: raise "Cannot set a removed group as the primary_group."
477: end
478:
479: unless @container.directory == group.container.directory
480: raise "Group must be in the same directory."
481: end
482:
483: unless group.type == GROUP_GLOBAL_SECURITY ||
484: group.type == GROUP_UNIVERSAL_SECURITY
485: raise "User primary group must be of type GROUP_GLOBAL_SECURITY" +
486: " or GROUP_UNIVERSAL_SECURITY."
487: end
488:
489: old_group = @primary_group
490: # This must be set before calling remove_group() because there is a
491: # special case where the group is also the UNIX main group (in the
492: # UNIXUser remote_group() method).
493: @primary_group = group
494: remove_group group
495: add_group old_group
496: @modified = true
497: end
Set the User or UNIXUser profile path. This corresponds to the LDAP profilePath attribute and is the "Profile path" setting in the Profile tab of the Active Directory Users and Computers tool.
# File lib/radum/user.rb, line 328
328: def profile_path=(profile_path)
329: @profile_path = profile_path
330: @modified = true
331: end
Remove the User membership in the Group or UNIXGroup. This automatically removes the User from the Group or UNIXGroup object‘s list of users. A RuntimeError is raised if the Group or UNIXGroup has been removed. This method will ignore an attempt to remove a User or UNIXUser from their primary Windows group since that is an implicit membership.
# File lib/radum/user.rb, line 551
551: def remove_group(group)
552: if group.removed?
553: raise "Cannot remove a removed group."
554: end
555:
556: # This method can be called on a primary_group change. If the user was a
557: # member of the primary_group, we want to make sure we remove that
558: # membership. It is also possible the user was not already a member of
559: # that primary_group. We only want to add that group to the
560: # @removed_groups array if they were really a member, otherwise we would
561: # not care.
562: if @groups.include? group
563: @removed_groups.push group unless @removed_groups.include?(group)
564: end
565:
566: @groups.delete group
567: group.remove_user self if group.users.include?(self)
568: end
Set the User or UNIXUser logon script path. This corresponds to the LDAP scriptPath attribute and is the "Logon script" setting in the Profile tab of the Active Directory Users and Computers tool.
# File lib/radum/user.rb, line 311
311: def script_path=(script_path)
312: @script_path = script_path
313: @modified = true
314: end
Set the User or UNIXUser surname (last name). This corresponds to the LDAP sn attribute and is used in the LDAP displayName, description, and name attributes. This defaults to nil when a User or UNIXUser is created using User.new or UNIXUser.new, but is set to the correct value when a User or UNIXUser is loaded by AD#load from the AD object the Container belongs to.
# File lib/radum/user.rb, line 294
294: def surname=(surname)
295: @surname = surname
296: @modified = true
297: end