On Tue, 2007-09-25 at 04:06 +0900, Martin DeMello wrote:
Is there any ruby library that will let me authenticate against an
active directory server from a linux machine? I looked through the AD
gems but the documentation assumed that I knew what I was doing
already, and seemed to imply that I needed to be running this from a
windows box sitting in a windows domain.
I recently had this problem.
class LDAPAuth
def initialize dn, host, port=389
@dn = dn
@c = LDAP::Conn.new host, port
@c.set_option LDAP::LDAP_OPT_PROTOCOL_VERSION, 3
@bound = false
end
def bind user, pass
@bound = [email protected](user, pass).nil?
end
def groups_of user, dn=@dn
raise Exception, "Not bound." unless @bound
@c.search2(dn, LDAP::LDAP_SCOPE_SUBTREE,
“sAMAccountName=#{user}”, [‘memberOf’]).first[‘memberOf’].map { |
e| /CN=([^,]+?)[,$]/i.match(e).captures.first }
end
def close
@c.unbind unless @c.nil?
@c = nil
end
def method_missing n, *a
@c.send n, *a
end
end
Check the line wrapping since it may catch you out. This is a tad quick
and dirty, but may do the trick. To authenticate like you’d wish:
l = LDAPAuth.new “OU=Accounts,DC=company,DC=com,DC=au”,
“pdc.company.com.au” # note that LDAP won’t let you search the root of a
DN, an OU must be specified
begin
l.bind “[email protected]”, “mypassword”
begin
raise Exception, "unauthorized" unless
l.groups_of(“joe”).include? “Enterprise Admins”
…
rescue
# not in the right group!
end
rescue
# credentials are bad!
…
end
My example code is fairly ugly, but I hope you get it. Note that we’re
bound to AD with the user’s own credentials - there may be a case where
the user doesn’t even have permissions to check their own group
memberships. In this case, you’d need to authenticate by trying to bind
with user credentials, but then authorise by binding with some (system)
account privileged for the purpose of checking memberships like this.
It’s a bit iffy, yes, but there’s probably a better way.
Also note this implementation uses the sAMAccountName LDAP attribute for
looking up a user to determine group membership status; thus a
non-domain-qualified name is used with LDAPAuth#groups_of (“joe”, not
“[email protected]”). Your schema may vary!
HTH
Arlen