Class RADUM::Container
In: lib/radum/container.rb
Parent: Object

The Container class represents a directory entry which contains users and groups, usually an orgainizational unit (OU).

Methods

Attributes

directory  [R]  The AD object the Container belongs to.
distinguished_name  [R]  The LDAP distinguishedName attribute for this Container.
groups  [R]  An Array of Group and UNIXGroup objects that are in this Container.
name  [R]  The String represenation of the Container object‘s name. The name should be the LDAP distinguishedName attribute without the AD root path component.
removed_groups  [R]  An Array of Group and UNIXGroup objects set for removal from this Container.
removed_users  [R]  An Array of User and UNIXUser objects set for removal from this Container.
users  [R]  An Array of User and UNIXUser objects that are in this Container.

Public Class methods

Create a new Container object that represents an Active Directory container or organizational unit that contains users and groups. This method takes a Hash containing arguments, all of which are required. The supported arguments follow:

  • :name => The relative path in Active Directory [required]
  • :directory => The Container object‘s associated AD [required]

An example instantiation follows:

  ad = RADUM::AD.new :root => 'dc=example,dc=com',
                     :user => 'cn=Administrator,cn=Users',
                     :password => 'password',
                     :server => '192.168.1.1'
  cn = RADUM::Container.new :name => 'ou=People', :directory => ad

The :name argument specifies the path to the container or organizational unit in Active Directory equivalent to the LDAP distinguishedName attribute for container or organizational unit without the root portion. The :directory argument is the AD object that owns the Container. A RuntimeError is raised if either of these arguments are missing.

Parameter Types

  • :name [String]
  • :directory [AD]

Extraneous spaces are removed from the :name argument. The Container :name can have spaces, but extra spaces after any "," characters are removed automatically along with leading and traling white space. The Container must not already be in the AD or a RuntimeError is raised. Note that you can create Container objects for an actual container in Active Directory or an organizational unit (referred to here as a "container" since it logically contains objects and this is a higher level representation). Only specify Containers that are really containers ("cn=Foo") or organizational units ("ou=Foo"). Also note that orgainizational units can hold containers, but containers cannot hold organizational units. Therefore "ou=foo,cn=bar" is invalid, but "cn=foo,ou=bar" is valid. A RuntimeError is raised if this rule is violated. Lastly, Container objects are in a conceptually flat namespace. In other words, "cn=foo,ou=bar" is its own Container object. It is not represented as a child of the "ou=bar" organizational unit. This has been accounted for when synchronizing with AD#sync so that things work. For example, the "cn=foo,ou=bar" Container object will cause the "ou=bar" organizational unit to be created first, if necessary, before the "cn=bar" child container is created.

[Source]

    # File lib/radum/container.rb, line 69
69:     def initialize(args = {})
70:       @name = args[:name] or raise "Container :name argument required."
71:       @name.gsub!(/,\s+/, ",")
72:       @name.strip!
73:       
74:       if @name =~ /[Oo][Uu]=.*[Cc][Nn]=/
75:         raise "Container CN objects cannot contain OU objects."
76:       end
77:       
78:       @directory = args[:directory] or raise "Container :directory argument" +
79:                                              " required."
80:       
81:       # The container name (like a user) must be unique (case-insensitive).
82:       # We would not want someone accidently making two equal containers
83:       # and adding users/groups in the wrong way.
84:       if @directory.find_container(name)
85:         raise "Container is already in the directory."
86:       end
87:       
88:       @distinguished_name = @name + "," + @directory.root
89:       # This has to be set first before adding the Container to the AD.
90:       @removed = false
91:       @directory.add_container self
92:       @users = []
93:       @removed_users = []
94:       @groups = []
95:       @removed_groups = []
96:     end

Public Instance methods

Add Group and UNIXGroup objects to the Container. Group and UNIXGroup objects that were removed or destroyed cannot be added back again and are ignored. The Group or UNIXGroup must have the Container as its container attribute or a RuntimeError is raised.

Parameter Types

[Source]

     # File lib/radum/container.rb, line 213
213:     def add_group(group)
214:       unless group.removed?
215:         if self == group.container
216:           # We don't want to add a group more than once.
217:           unless @groups.include?(group)
218:             @groups.push group
219:             @removed_groups.delete group
220:             @directory.rids.push group.rid if group.rid
221:             @directory.gids.push group.gid if group.instance_of?(UNIXGroup)
222:           end
223:         else
224:           raise "Group must be in this container."
225:         end
226:       end
227:     end

Add User and UNIXUser objects to the Container. User and UNIXUser objects that were removed or destroyed cannot be added back again and are ignored. The User or UNIXUser must have the Container as its container attribute or a RuntimeError is raised.

Parameter Types

[Source]

     # File lib/radum/container.rb, line 106
106:     def add_user(user)
107:       unless user.removed?
108:         if self == user.container
109:           # We don't want to add a user more than once.
110:           unless @users.include?(user)
111:             @users.push user
112:             @removed_users.delete user
113:             @directory.rids.push user.rid if user.rid
114:             @directory.uids.push user.uid if user.instance_of?(UNIXUser)
115:           end
116:         else
117:           raise "User must be in this container."
118:         end
119:       end
120:     end

Destroy a reference to the Group or UNIXGroup. This removes any reference to the Group or UNIXGroup from the RADUM system. This is different from removing a Group or UNIXGroup. Removal causes the Group or UNIXGroup to be deleted from Active Directory. Destroying the Group or UNIXGroup does not cause the Group or UNIXGroup to be removed from Active Directory, but it does remove all references to the Group or UNIXGroup from the system. The Group or UNIXGroup must be in the Container or a RuntimeError is raised. This does set the Group or UNIXGroup object‘s removed attribute to true and any references to the Group or UNIXGroup should be discarded. Once a Group or UNIXGroup is destroyed it cannot be added back to the Container.

Parameter Types

[Source]

     # File lib/radum/container.rb, line 310
310:     def destroy_group(group)
311:       # Note you have to allow destruction of groups even if they have been
312:       # removed because this is the only way removed groups are really deleted
313:       # from the RADUM environment once they are deleted from Active Directory.
314:       if self == group.container
315:         # We cannot destroy a group that still has a user referencing it as
316:         # their primary_group or unix_main_group.
317:         @directory.users.each do |user|
318:           if group == user.primary_group
319:             raise "Cannot destroy group #{group.name}: it is " +
320:                   "#{user.username}'s primary Windows group."
321:           end
322:           
323:           if user.instance_of?(UNIXUser)
324:             if group == user.unix_main_group
325:               raise "Cannot destroy group #{group.name}: it is " +
326:                     "#{user.username}'s UNIX main group."
327:             end
328:           end
329:         end
330:         
331:         @groups.delete group
332:         @removed_groups.delete group
333:         @directory.rids.delete group.rid if group.rid
334:         @directory.gids.delete group.gid if group.instance_of?(UNIXGroup)
335:         
336:         @directory.groups.each do |current_group|
337:           if current_group.groups.include?(group)
338:             current_group.destroy_group group
339:           end
340:         end
341:         
342:         @directory.users.each do |user|
343:           user.destroy_group group
344:         end
345:         
346:         group.set_removed
347:       else
348:         raise "Group must be in this container."
349:       end
350:     end

Destroy a reference to the User or UNIXUser. This removes any reference to the User or UNIXUser from the RADUM system. This is different from removing a User or UNIXUser. Removal causes the User or UNIXUser to be deleted from Active Directory. Destroying the User or UNIXUser does not cause the User or UNIXUser to be removed from Active Directory, but it does remove all references to the User or UNIXUser from the system. The User or UNIXUser must be in the Container or a RuntimeError is raised. This does set the User or UNIXUser object‘s removed attribute to true and any references to the User or UNIXUser should be discarded. Once a User or UNIXUser is destroyed it cannot be added back to the Container.

Parameter Types

[Source]

     # File lib/radum/container.rb, line 185
185:     def destroy_user(user)
186:       # Note you have to allow destruction of users even if they have been
187:       # removed because this is the only way removed users are really deleted
188:       # from the RADUM environment once they are deleted from Active Directory.
189:       if self == user.container
190:         @users.delete user
191:         @removed_users.delete user
192:         @directory.rids.delete user.rid if user.rid
193:         @directory.uids.delete user.uid if user.instance_of?(UNIXUser)
194:         
195:         @directory.groups.each do |group|
196:           group.destroy_user user if group.users.include?(user)
197:         end
198:         
199:         user.set_removed
200:       else
201:         raise "User must be in this container."
202:       end
203:     end

Remove a Group or UNIXGroup object from the Container. This sets the Group or UNIXGroup object‘s removed attribute to true. A Group or UNIXGroup cannot be removed if it is still any User object‘s primary Windows group. A UNIXGroup cannot be removed if it is any User object‘s UNIX main group. In both cases, a RuntimeError will be raised. If the Group or UNIXGroup is removed from the Container, it is effectively deleted from Active Directory. Any Group or UNIXGroup objects the Group or UNIXGroup belongs to will have their membership removed. This means that the Group or UNIXGroup will have their Group or UNIXGroup memberships removed for each Group or UNIXGroup they were in as well. The Group or UNIXGroup cannot be added back after removed, but it will only be removed from Active Directory after AD#sync is called. Any references to the Group or UNIXGroup should be discarded. The Group or UNIXGroup must be in the Container or a RuntimeError is raised. Already removed Group or UNIXGroup objects are ignored.

There are further checks in Active Directory to make sure the Group or UNIXGroup can really be removed. A warning is displayed if the Group or UNIXGroup cannot be removed in the AD#sync call. In this method, RADUM only checks objects it knows about at the time of the call.

Parameter Types

[Source]

     # File lib/radum/container.rb, line 253
253:     def remove_group(group)
254:       return if group.removed?
255:       if self == group.container
256:         # We cannot remove a group that still has a user referencing it as
257:         # their primary_group or unix_main_group.
258:         @directory.users.each do |user|
259:           if group == user.primary_group
260:             raise "Cannot remove group #{group.name}: it is " +
261:                   "#{user.username}'s primary Windows group."
262:           end
263:           
264:           if user.instance_of?(UNIXUser)
265:             if group == user.unix_main_group
266:               raise "Cannot remove group #{group.name}: it is " +
267:                     "#{user.username}'s UNIX main group."
268:             end
269:           end
270:         end
271:         
272:         @groups.delete group
273:         @directory.rids.delete group.rid if group.rid
274:         @directory.gids.delete group.gid if group.instance_of?(UNIXGroup)
275:         
276:         @directory.groups.each do |current_group|
277:           if current_group.groups.include?(group)
278:             current_group.remove_group group
279:           end
280:         end
281:         
282:         @directory.users.each do |user|
283:           if user.groups.include?(group)
284:             user.remove_group group
285:           end
286:         end
287:         
288:         group.set_removed
289:         @removed_groups.push group unless @removed_groups.include?(group)
290:       else
291:         raise "Group must be in this container."
292:       end
293:     end

Remove a User or UNIXUser object from the Container. This sets the User or UNIXUser object‘s removed attribute to true. If the User or UNIXUser is removed from the Container, it is effectively deleted from Active Directory. Any Group or UNIXGroup objects the User or UNIXUser belongs to will have their membership removed. This means that the User or UNIXUser will have their Group or UNIXGroup memberships removed for each Group or UNIXGroup they were in as well. The User or UNIXUser cannot be added back after removed, but it will only be removed from Active Directory after AD#sync is called. Any references to the User or UNIXUser should be discarded. The User or UNIXUser must be in the Container or a RuntimeError is raised. Already removed User or UNIXUser objects are ignored.

Parameter Types

[Source]

     # File lib/radum/container.rb, line 138
138:     def remove_user(user)
139:       return if user.removed?
140:       if self == user.container
141:         @users.delete user
142:         @directory.rids.delete user.rid if user.rid
143:         @directory.uids.delete user.uid if user.instance_of?(UNIXUser)
144:         
145:         @directory.groups.each do |group|
146:           if group.users.include?(user)
147:             if user.instance_of?(UNIXUser)
148:               group.remove_user user unless group == user.unix_main_group
149:             else
150:               group.remove_user user
151:             end
152:           end
153:         end
154:         
155:         user.set_removed
156:         
157:         # We have to remove the user first before we can remove the user's
158:         # membership in their unix_main_group. It is safe to attempt removing
159:         # a user from their unix_main_group if they are already removed.
160:         if user.instance_of?(UNIXUser)
161:           user.unix_main_group.remove_user user
162:         end
163:         
164:         @removed_users.push user unless @removed_users.include?(user)
165:       else
166:         raise "User must be in this container."
167:       end
168:     end

True if the Container has been removed from its AD, false otherwise.

[Source]

     # File lib/radum/container.rb, line 353
353:     def removed?
354:       @removed
355:     end

The String representation of the Container object.

[Source]

     # File lib/radum/container.rb, line 363
363:     def to_s
364:       "Container <#{@name}> [#{@distinguished_name}]"
365:     end

[Validate]