5 changed files with 310 additions and 293 deletions
-
15README.md
-
12examples/client.rb
-
46examples/rbslapd4.rb
-
397lib/ldap/server/router.rb
-
133lib/ldap/server/util.rb
@ -0,0 +1,12 @@ |
|||
require 'simple_ldap_authenticator' |
|||
|
|||
DOMAIN = 'artcode' |
|||
TLD = 're' |
|||
|
|||
SimpleLdapAuthenticator.servers = ['127.0.0.1'] |
|||
SimpleLdapAuthenticator.port = 1389 |
|||
SimpleLdapAuthenticator.use_ssl = false |
|||
# SimpleLdapAuthenticator.login_format = '%s@mydomain.com' |
|||
SimpleLdapAuthenticator.login_format = "uid=%s,ou=Users,dc=#{DOMAIN},dc=#{TLD}" |
|||
|
|||
p SimpleLdapAuthenticator.valid?('admin', 'adminpassword') |
|||
@ -1,88 +1,85 @@ |
|||
require 'ldap/server/result' |
|||
|
|||
module LDAP |
|||
class Server |
|||
class Server |
|||
class Operation |
|||
# Return true if connection is not authenticated |
|||
|
|||
class Operation |
|||
|
|||
# Return true if connection is not authenticated |
|||
def anonymous? |
|||
@connection.binddn.nil? |
|||
end |
|||
|
|||
def anonymous? |
|||
@connection.binddn.nil? |
|||
end |
|||
# Split dn string into its component parts, returning |
|||
# [ {attr=>val}, {attr=>val}, ... ] |
|||
# |
|||
# This is pretty horrible legacy stuff from X500; see RFC2253 for the |
|||
# full gore. It's stupid that the LDAP protocol sends the DN in string |
|||
# form, rather than in ASN1 form (as it does with search filters, for |
|||
# example), even though the DN syntax is defined in terms of ASN1! |
|||
# |
|||
# Attribute names are downcased, but values are not. For any |
|||
# case-insensitive attributes it's up to you to downcase them. |
|||
# |
|||
# Note that only v2 clients should add extra space around the comma. |
|||
# This is accepted, and so is semicolon instead of comma, but the |
|||
# full RFC1779 backwards-compatibility rules (e.g. quoted values) |
|||
# are not implemented. |
|||
# |
|||
# I *think* these functions will work correctly with UTF8-encoded |
|||
# characters, given that a multibyte UTF8 character does not contain |
|||
# the bytes 00-7F and therefore we cannot confuse '\', '+' etc |
|||
|
|||
# Split dn string into its component parts, returning |
|||
# [ {attr=>val}, {attr=>val}, ... ] |
|||
# |
|||
# This is pretty horrible legacy stuff from X500; see RFC2253 for the |
|||
# full gore. It's stupid that the LDAP protocol sends the DN in string |
|||
# form, rather than in ASN1 form (as it does with search filters, for |
|||
# example), even though the DN syntax is defined in terms of ASN1! |
|||
# |
|||
# Attribute names are downcased, but values are not. For any |
|||
# case-insensitive attributes it's up to you to downcase them. |
|||
# |
|||
# Note that only v2 clients should add extra space around the comma. |
|||
# This is accepted, and so is semicolon instead of comma, but the |
|||
# full RFC1779 backwards-compatibility rules (e.g. quoted values) |
|||
# are not implemented. |
|||
# |
|||
# I *think* these functions will work correctly with UTF8-encoded |
|||
# characters, given that a multibyte UTF8 character does not contain |
|||
# the bytes 00-7F and therefore we cannot confuse '\', '+' etc |
|||
def self.split_dn(dn) |
|||
# convert \\ to \5c, \+ to \2b etc |
|||
p "dn=#{dn}" |
|||
dn.gsub!(/\\([ #,+"\\<>;])/) { |match| format '\\%02x', match[1].ord } |
|||
|
|||
def self.split_dn(dn) |
|||
# convert \\ to \5c, \+ to \2b etc |
|||
dn.gsub!(/\\([ #,+"\\<>;])/) { |match| format "\\%02x", match[1].ord } |
|||
# Now we know that \\ and \, do not exist, it's safe to split |
|||
parts = dn.split(/\s*[,;]\s*/) |
|||
|
|||
# Now we know that \\ and \, do not exist, it's safe to split |
|||
parts = dn.split(/\s*[,;]\s*/) |
|||
parts.collect do |part| |
|||
res = {} |
|||
|
|||
parts.collect do |part| |
|||
res = {} |
|||
# Split each part into attr=val+attr=val |
|||
avs = part.split(/\+/) |
|||
|
|||
# Split each part into attr=val+attr=val |
|||
avs = part.split(/\+/) |
|||
avs.each do |av| |
|||
# These should all be of form attr=value |
|||
raise LDAP::ResultError::ProtocolError, "Bad DN component: #{av}" unless av =~ /^([^=]+)=(.*)$/ |
|||
|
|||
avs.each do |av| |
|||
# These should all be of form attr=value |
|||
unless av =~ /^([^=]+)=(.*)$/ |
|||
raise LDAP::ResultError::ProtocolError, "Bad DN component: #{av}" |
|||
attr = ::Regexp.last_match(1).downcase |
|||
val = ::Regexp.last_match(2) |
|||
# Now we can decode those bits |
|||
attr.gsub!(/\\([a-f0-9][a-f0-9])/i) { ::Regexp.last_match(1).hex.chr } |
|||
val.gsub!(/\\([a-f0-9][a-f0-9])/i) { ::Regexp.last_match(1).hex.chr } |
|||
res[attr] = val |
|||
end |
|||
attr, val = $1.downcase, $2 |
|||
# Now we can decode those bits |
|||
attr.gsub!(/\\([a-f0-9][a-f0-9])/i) { $1.hex.chr } |
|||
val.gsub!(/\\([a-f0-9][a-f0-9])/i) { $1.hex.chr } |
|||
res[attr] = val |
|||
res |
|||
end |
|||
res |
|||
end |
|||
end |
|||
|
|||
# Reverse of split_dn. Join [elements...] |
|||
# where each element can be {attr=>val,...} or [[attr,val],...] |
|||
# or just [attr,val] |
|||
# Reverse of split_dn. Join [elements...] |
|||
# where each element can be {attr=>val,...} or [[attr,val],...] |
|||
# or just [attr,val] |
|||
|
|||
def self.join_dn(elements) |
|||
dn = "" |
|||
elements.each do |elem| |
|||
av = "" |
|||
elem = [elem] if elem[0].is_a?(String) |
|||
elem.each do |attr,val| |
|||
av << "+" unless av == "" |
|||
def self.join_dn(elements) |
|||
dn = '' |
|||
elements.each do |elem| |
|||
av = '' |
|||
elem = [elem] if elem[0].is_a?(String) |
|||
elem.each do |attr, val| |
|||
av << '+' unless av == '' |
|||
|
|||
av << attr << "=" << |
|||
val.sub(/^([# ])/, '\\\\\\1'). |
|||
sub(/( )$/, '\\\\\\1'). |
|||
gsub(/([,+"\\<>;])/, '\\\\\\1') |
|||
av << attr << '=' << |
|||
val.sub(/^([# ])/, '\\\\\\1') |
|||
.sub(/( )$/, '\\\\\\1') |
|||
.gsub(/([,+"\\<>;])/, '\\\\\\1') |
|||
end |
|||
dn << ',' unless dn == '' |
|||
dn << av |
|||
end |
|||
dn << "," unless dn == "" |
|||
dn << av |
|||
dn |
|||
end |
|||
dn |
|||
end |
|||
|
|||
end # class Operation |
|||
|
|||
end # class Server |
|||
end # class Operation |
|||
end # class Server |
|||
end # module LDAP |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue