Class RADUM::User
In: lib/radum/user.rb
Parent: Object

The User class represents a standard Windows user account.

Methods

Attributes

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).

Public Class methods

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:

  • :username => The User object‘s username [required]
  • :container => The User object‘s associated Container [required]
  • :primary_group => The User object‘s primary Windows group [required]
  • :disabled => User object disabled flag [default false]
  • :rid => The RID of the User object [optional]

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.

Parameter Types

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.

[Source]

     # 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

Public Instance methods

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.

Parameter Types

[Source]

     # 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.

Parameter Types

  • drive [String]
  • path [String]

[Source]

     # 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

Disable a User or UNIXUser account.

[Source]

     # File lib/radum/user.rb, line 180
180:     def disable
181:       unless @disabled
182:         @disabled = true
183:         @modified = true
184:       end
185:     end

True if the User or UNIXUser account is disabled, false otherwise. This is a boolean representation of the LDAP userAccountControl attribute.

[Source]

     # File lib/radum/user.rb, line 175
175:     def disabled?
176:       @disabled
177:     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.

[Source]

     # File lib/radum/user.rb, line 199
199:     def distinguished_name
200:       @distinguished_name
201:     end

Enable a User or UNIXUser account.

[Source]

     # File lib/radum/user.rb, line 188
188:     def enable
189:       if @disabled
190:         @disabled = false
191:         @modified = true
192:       end
193:     end

The User or UNIXUser first name.

[Source]

     # File lib/radum/user.rb, line 223
223:     def first_name
224:       @first_name
225:     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.

Parameter Types

[Source]

     # File lib/radum/user.rb, line 237
237:     def first_name=(first_name)
238:       @first_name = first_name
239:       @modified = true
240:     end

Force the User or UNIXUser to change their password on their next login. Note that the default value is to not force a password change on the next login.

[Source]

     # File lib/radum/user.rb, line 437
437:     def force_change_password
438:       @must_change_password = true
439:       @modified = true
440:     end

The User or UNIXUser middle initials.

[Source]

     # File lib/radum/user.rb, line 243
243:     def initials
244:       @initials
245:     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.

Parameter Types

[Source]

     # File lib/radum/user.rb, line 255
255:     def initials=(initials)
256:       @initials = initials
257:       @modified = true
258:     end

Check if the User or UNIXUser was loaded from Active Directory.

[Source]

     # File lib/radum/user.rb, line 607
607:     def loaded?
608:       @loaded
609:     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.

[Source]

     # 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.

[Source]

     # 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.

Parameter Types

  • path [String]

[Source]

     # 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.

Parameter Types

[Source]

     # 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

The User or UNIXUser middle name.

[Source]

     # File lib/radum/user.rb, line 261
261:     def middle_name
262:       @middle_name
263:     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.

Parameter Types

[Source]

     # File lib/radum/user.rb, line 274
274:     def middle_name=(middle_name)
275:       @middle_name = middle_name
276:       @modified = true
277:     end

True if the User or UNIXUser has been modified. This is true for manually created User or UNIXUser objects and false for initially loaded User and UNIXUser objects.

[Source]

     # File lib/radum/user.rb, line 614
614:     def modified?
615:       @modified
616:     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.

[Source]

     # 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.

[Source]

     # 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.

Parameter Types

[Source]

     # 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.

[Source]

     # 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.

Parameter Types

[Source]

     # 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

The path to the User or UNIXUser object‘s Windows profile.

[Source]

     # File lib/radum/user.rb, line 317
317:     def profile_path
318:       @profile_path
319:     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.

Parameter Types

[Source]

     # 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.

Parameter Types

[Source]

     # 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

True if the User or UNIXUser has been removed from its Container, false otherwise.

[Source]

     # File lib/radum/user.rb, line 635
635:     def removed?
636:       @removed
637:     end

The path to the User or UNIXUser object‘s logon script.

[Source]

     # File lib/radum/user.rb, line 300
300:     def script_path
301:       @script_path
302:     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.

Parameter Types

[Source]

     # File lib/radum/user.rb, line 311
311:     def script_path=(script_path)
312:       @script_path = script_path
313:       @modified = true
314:     end

The User or UNIXUser surname (last name).

[Source]

     # File lib/radum/user.rb, line 280
280:     def surname
281:       @surname
282:     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.

Parameter Types

[Source]

     # File lib/radum/user.rb, line 294
294:     def surname=(surname)
295:       @surname = surname
296:       @modified = true
297:     end

The String representation of the User object.

[Source]

     # File lib/radum/user.rb, line 645
645:     def to_s
646:       "User [(" + (@disabled ? "USER_DISABLED" : "USER_ENABLED") +
647:       ", RID #{@rid}) <#{@username}> #{@distinguished_name}]"
648:     end

Unset a forced password change for a User or UNIXUser. This will clear the forced password change.

[Source]

     # File lib/radum/user.rb, line 444
444:     def unset_change_password
445:       @must_change_password = false
446:       @modified = true
447:     end

[Validate]