RADUM

From Shaun Rowland Wiki

Jump to: navigation, search

Contents


Ruby Active Directory User Management

The RADUM module provides an interface to Microsoft Active Directory for working with users and groups. The User class represents a standard Windows user account. The UNIXUser class represents a Windows account that has UNIX attributes. Similarly, the Group class represents a standard Windows group, and the UNIXGroup class represents a Windows group that has UNIX attributes. UNIX attributes are supported if Active Directory has been extended, such as when Microsoft Identity Management for UNIX has been installed. LDAP extensions for UNIX are not required if only Windows users and groups are operated on. This module concentrates only on users and groups at this time.

This is a pure Ruby implementation. Windows command line tools are not used in any way, so this will work from other platforms such as Mac OS X and Linux in addition to Windows. RADUM does require the Active Directory server to support SSL because that is a requirement for creating user accounts through LDAP. This means that a domain must have a certificate server. Using a self-signed certificate should be fine.

I need a tool that works with users and groups, but one that also makes a distinction between regular Windows users and groups and those same objects that have UNIX attributes. There are some important rules to follow with users who have UNIX attributes. For example, they need to have a UNIX main group and that group needs to have a GID attribute. While it is not an error for the user to also be a member of that group from the UNIX perspective, it is redundant, so I make sure that doesn’t happen. I also put logic in that lets one set the user’s primary Windows group (Windows group or Windows group with UNIX attributes). Note that the primary Windows group for a user can only be of certain group types and users don’t show up in the LDAP member attribute of that group either. Instead of expecting the user to deal with this through Active Directory manipulation using LDAP, RADUM deals with it.

Resources

Source code and documentation can be found at the following locations:

Note that the gem is in RubyForge and available from the gem command:

gem install radum

Most of the RADUM documentation exists in the RADUM RDoc.

Requirements

RADUM works with Ruby 1.8, but it does not work with Ruby 1.9 yet because ruby-net-ldap does not at this time. RADUM has been exclusively tested against Windows Server 2008 and Windows Server 2003 R2 Standard Edition SP2. The testing system had Microsoft Identity Management for UNIX installed and had the Certificate Services Role added, which is added using Add/Remove Programs in Windows Server 2003. Microsoft Identity Management for UNIX is generally required for editing UNIXUser and UNIXGroup objects in the Active Directory Users and Computers GUI tool if desired, and the Certificate Services Role is required in the domain because SSL is required for creating User and UNIXUser objects using LDAP. The LDAP attributes required for UNIXUser objects don‘t necessarily require Microsoft Identity Management for UNIX to be installed.

RADUM works with a domain functional level of Windows 2003 Server or higher. Most of RADUM will work with a domain functional level of Windows 2000 native except for Universal group types and groups being members of groups. If those features are not needed, the Windows 2000 native domain functional level can be used, but RADUM assumes these features are possible, so one would need to ensure they do not use them if working at a domain functional level lower than Windows Server 2003. RADUM was not tested at a domain functional level lower than Windows 2000 native.

Example Code

The following is an extremely simple example program:

#!/usr/bin/ruby
 
require 'rubygems'
require 'radum'
 
ad = RADUM::AD.new :root => 'dc=vmware,dc=local', :password => 'password',
                   :user => 'cn=Administrator,cn=Users',
                   :server => '192.168.10.4'
cn = RADUM::Container.new :name => "ou=Staff", :directory => ad
 
# Load all current information. The "cn=Users" container is added to the AD
# object implicitly since most users have "Domain Users" as their primary
# Windows group.
ad.load
 
# Find the next UID and GID values that can be used. This searches all the
# objects RADUM knows about as well as the Active Directory.
uid = ad.load_next_uid
gid = ad.load_next_gid
 
# Create a UNIXGroup and UNIXUser. A Group is found to use as the primary_group
# for the UNIXUser first.
du = ad.find_group_by_name('Domain Users')
ug = RADUM::UNIXGroup.new :name => 'enable', :container => cn,
                          :gid => gid, :nis_domain => 'vmware'
uu = RADUM::UNIXUser.new :username => 'shaun',
                         :container => cn, :primary_group => du,
                         :uid => uid, :shell => "/bin/bash",
                         :home_directory => "/home/shaun",
                         :unix_main_group => ug, :nis_domain => 'vmware'
uu.first_name = 'Shaun'
uu.initials = 'M'
uu.surname = 'Rowland'
uu.gecos = 'Shaun Rowland'
 
# Print current information in the loaded Container objects.
ad.containers.each do |container|
  puts
  puts container
  puts
  puts "Groups"
  puts "------"
 
  container.groups.each do |group|
    puts group
  end
 
  puts
  puts "Users"
  puts "-----"
 
  container.users.each do |user|
    puts user
  end
end
 
# Syncrhonize changes back to Active Directory.
ad.sync

Running that code produces the following output:

[rowland@rowland: radum]$ ./demo.rb 

Container [cn=Users,dc=vmware,dc=local]

Groups
------
Group [(GROUP_DOMAIN_LOCAL_SECURITY, RID 571) cn=Allowed RODC Password Replication Group,cn=Users,dc=vmware,dc=local]
Group [(GROUP_DOMAIN_LOCAL_SECURITY, RID 517) cn=Cert Publishers,cn=Users,dc=vmware,dc=local]
Group [(GROUP_DOMAIN_LOCAL_SECURITY, RID 572) cn=Denied RODC Password Replication Group,cn=Users,dc=vmware,dc=local]
Group [(GROUP_DOMAIN_LOCAL_SECURITY, RID 1102) cn=DnsAdmins,cn=Users,dc=vmware,dc=local]
Group [(GROUP_GLOBAL_SECURITY, RID 1103) cn=DnsUpdateProxy,cn=Users,dc=vmware,dc=local]
Group [(GROUP_GLOBAL_SECURITY, RID 512) cn=Domain Admins,cn=Users,dc=vmware,dc=local]
Group [(GROUP_GLOBAL_SECURITY, RID 515) cn=Domain Computers,cn=Users,dc=vmware,dc=local]
Group [(GROUP_GLOBAL_SECURITY, RID 516) cn=Domain Controllers,cn=Users,dc=vmware,dc=local]
Group [(GROUP_GLOBAL_SECURITY, RID 514) cn=Domain Guests,cn=Users,dc=vmware,dc=local]
Group [(GROUP_GLOBAL_SECURITY, RID 513) cn=Domain Users,cn=Users,dc=vmware,dc=local]
Group [(GROUP_UNIVERSAL_SECURITY, RID 519) cn=Enterprise Admins,cn=Users,dc=vmware,dc=local]
Group [(GROUP_UNIVERSAL_SECURITY, RID 498) cn=Enterprise Read-only Domain Controllers,cn=Users,dc=vmware,dc=local]
Group [(GROUP_GLOBAL_SECURITY, RID 520) cn=Group Policy Creator Owners,cn=Users,dc=vmware,dc=local]
Group [(GROUP_DOMAIN_LOCAL_SECURITY, RID 553) cn=RAS and IAS Servers,cn=Users,dc=vmware,dc=local]
Group [(GROUP_GLOBAL_SECURITY, RID 521) cn=Read-only Domain Controllers,cn=Users,dc=vmware,dc=local]
Group [(GROUP_UNIVERSAL_SECURITY, RID 518) cn=Schema Admins,cn=Users,dc=vmware,dc=local]

Users
-----
User [(USER_ENABLED, RID 500) Administrator CN=Administrator,CN=Users,DC=vmware,DC=local]
User [(USER_ENABLED, RID 501) Guest CN=Guest,CN=Users,DC=vmware,DC=local]
User [(USER_DISABLED, RID 502) krbtgt CN=krbtgt,CN=Users,DC=vmware,DC=local]

Container [ou=Staff,dc=vmware,dc=local]

Groups
------
UNIXGroup [(GROUP_GLOBAL_SECURITY, RID , GID 1001) cn=enable,ou=Staff,dc=vmware,dc=local]

Users
-----
UNIXUser [(USER_ENABLED, RID , UID 1001, GID 1001) shaun cn=shaun,ou=Staff,dc=vmware,dc=local]

There is more work to do with respect to Ruby 1.9 testing, but that is mainly dependent on ruby-net-ldap being updated. It seems there are some behavioral differences with the next version of ruby-net-ldap, but once there is a release I should be able to update the code to deal with the differences.

Software Projects

Personal tools