[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Help with MS ActiveDirectory access

CParticle

10/4/2006 4:05:00 AM

Hey All,

I'm hoping to get some help connecting to Active directory to pull down
a list of user objects from the entire domain(all ou's). Let me say
that while I need user objects now knowing how to get any objects from
the domain would be useful as well.

I've looked on the web and in the news groups including this one and
not found much in the way of functional examples that I could use.
My ruby version is <<ruby 1.8.5 (2006-08-25) [i386-mswin32]>>
installed from the one-click-installer from www.Ruby-lang.org

I've installed the missing ado.rb file for DBI. Ultimately I the two
things that I would like avoid though are.
1) having to recurse through the ou's one at a time to get what I need
2) any non-standard ruby modules or gems (as much as possible)

I'm thinking DBI and ADO to connect to AD might be the right way but
I've not seen any good examples on how to do that. I've been working
on this for two and a half days so any help would be much appreciated.
Below I've listed two pieces code that I've found

#This code only gives me a subset of all the AD properties and doesn't
use generic LDAP field names
require 'win32ole'
domain = WIN32OLE.connect("WinNT://corp.company.com")
domain.each {|myobj| puts myobj.name if myobj.name.upcase ==
'MYUSERNAME'}

#This also works although this is the ldap solution and only shows one
ou at a time
#this would require recursion to get the whole domain
require 'win32ole'
rootDSE = WIN32OLE.connect("LDAP://RootDSE")
domainDN = rootDSE.Get("DefaultNamingContext")
#I know I'm specifying an ou but I can just uo text to an array.each
pulled from the RootDSE when made recursive
userContainer = WIN32OLE.connect("LDAP://ou=MyCity,ou=MyorgUnit," +
domainDN)
puts userContainer.each {|usr| puts usr.sAMAccountName}

3 Answers

CParticle

10/4/2006 5:45:00 PM

0

I've done some more searching

This is the DBI connection string that I'm currently working with is

require 'win32ole'
require 'DBI'
myAD = DBI.connect('DBI:ADO:ADsDSOObject')

I've also found this thread that deal with MS SQL 2003
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-t...

It lead me to this
DBI:ADO:Provider=SQLOLEDB;Data Source=YOURSERVER;Initial
Catalog=YOURDB;User Id=YOU;Password=YOURPASSWORD;

which I modified to
myAD = DBI.connect('DBI:ADO:Provider=ADsDSOObject;Data
Source=corp.company.com;')

but that didn't work either

the first gets an error on 'connect' stating that
[Microsoft][ODBC Driver Manager] Data source name not found and no
default
driver specified

the second gets an error on 'connect stating that
OLE error code:800A0CB3 in ADODB.Connection Current provider does not
support transactions.

I'm mostly a newbie with Ruby but it doesn't seem like I'm doing
anything too complicated here if anyone can point me to better DBI and
Ruby active directory docs that would be great. If you think I've
botched something on the install let me know.

Thanks
C.Particle

CParticle

10/27/2006 3:37:00 PM

0

OK After much pain and heartache I managed to finally get an account
added to the domain after first figuring my earlier searching issues.
I'm posting mostly cause in trying to research this I found little in
the way of example where someone actually Added / Created a new account
onto MS AD (Microsoft Active Directory). Hopefully my experience will
make someone else's life easier. The two pieces of code below are very
different ways of doing some similar tasks on AD. I'm certain each
code snippet can be written in the method of the other but I didn't
manage to get it working successfully and I'm not likely to try at this
point. My code can probably be written in more of a RubyWay but I've
got it working and that good enough for me. Disclaimer the name of the
network below have been modified to protect the privacy of my company
but the rest is the unchanged.

Just want to say thank you Francis Cianfrocca for pointing me to Ruby's
Net:ldap library and his pointers that helped me write my probably ugly
search code below.
---search code---------------------------------------------
require 'rubygems'
require 'net/ldap'
ldap = Net::LDAP.new
ldap.host = "192.168.1.1" # your DC's IP address
ldap.port = 389
user = "adminacct@company.com" # your admin account at your domain
pass = "password" # password to match the above account
ldap.auth user, pass # my domain requires authentication to get the
info I need
if ldap.bind # code to verify authentication
puts 'authentication succeeded'
else
puts 'authentication failed'
end
nuser = "cparti" + "*" # the star is to wildcard the end of the
username and this can be
#made a single string I have it separated because I used a variable for
the first part
filter = Net::LDAP::Filter.eq("samaccountname",nuser) &
~(Net::LDAP::Filter.eq("objectclass","computer"))
# the above filter should be in one line and searches for
# samaccount user name matching my criteris
# and computer absent form objectclass
treebase = "dc=company,dc=com"
attrs = ["mail", "cn", "sn", "samaccountname"]
acctNameArray = Array.new
#the code below search the entire domain for all accounts
#matching my nuser string then prints the samaccountname
#only and puts it into an array for later use
ldap.search( :base => treebase, :filter => filter, :attributes => attrs
) do |entry|
puts "DN: " + entry.dn
entry.each do |attribute, values|
if attribute.to_s.downcase == "samaccountname" then
print " #{attribute}:"
values.each do |value|
puts " #{value}"
acctNameArray << value.to_s.downcase
end
end
end
end
puts acctNameArray.sort
------------------------------------------------------------------


--------create account code-----------------------------------
require 'win32ole'
rootDSE = WIN32OLE.connect("LDAP://RootDSE")
domainDN = rootDSE.Get("DefaultNamingContext")
userContainer = WIN32OLE.connect("LDAP://ou=developers,ou=users," +
domainDN)
sAMAccountName = "rubt01"
userPrincipalName = "rubyt01@csg.csgsystems.com"
mynewuser = userContainer.Create("user","cn=Rubyldap Test")
mynewuser.Put("sAMAccountName",sAMAccountName)
mynewuser.Put("userPrincipalName",userPrincipalName)
mynewuser.SetInfo
--------------------------------------------------------------------------

A few things to note about actually creating an account. The above
items that I have is less than what I want is considerable less than
was I want, but I had to cut it down to this to get it to work. I
found mentioned elsewhere that AD wont add certain data before the
account is created things like the mailbox address. Well it seems that
AD (at least mine) is pickier than just that. My code would run execute
either with no errors or tell me that SetInfo was a missing method. I
won't claim to know the ins and outs of AD or Ruby I only know what I
found. Soon as cut the fields down to what's above my account was
created. My goal from here is to use the update the account after its
been created with all my specific values after the account is created.
My hope is that now that I've figured out how to get this working I'll
be able to start changing vbscript example from the active directory
cookbook into Ruby. For the record I'm not using the vbscipt because I
want to work and learn in a language that I can use on other platforms
as well.

Sorry to have board you all.

C.Particle

CParticle

10/30/2006 9:23:00 PM

0

Below is my attempt to create and account using the Net::LDAP#add
command
not much luck with this script completes without error but nothing gets
added to the Domain. If anyone has anything to add please go ahead and
comment.

require 'rubygems'
require 'net/ldap'

ldap = Net::LDAP.new
ldap.host = "192.168.1.1"
ldap.port = 389
user = "adminuser@company.com"
pass = "password"
ldap.auth user, pass

dn = "cn=Rubyldap, Test,ou=myou,dc=company,dc=com"
attr = {
:cn => "Rubyldap, Test",
:objectClass => "user",
:sAMAccountName => "rubytest",
:userPrincipalName => "rubytest@company.com"
}
ldap.add( :dn => dn, :attributes => attr )