datacom_active_directory 1.5.5.datacom
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/README.md +45 -0
- data/Rakefile +20 -0
- data/active_directory.gemspec +22 -0
- data/lib/active_directory.rb +95 -0
- data/lib/active_directory/base.rb +587 -0
- data/lib/active_directory/computer.rb +35 -0
- data/lib/active_directory/container.rb +114 -0
- data/lib/active_directory/field_type/binary.rb +39 -0
- data/lib/active_directory/field_type/date.rb +39 -0
- data/lib/active_directory/field_type/dn_array.rb +40 -0
- data/lib/active_directory/field_type/group_dn_array.rb +40 -0
- data/lib/active_directory/field_type/member_dn_array.rb +47 -0
- data/lib/active_directory/field_type/password.rb +41 -0
- data/lib/active_directory/field_type/timestamp.rb +45 -0
- data/lib/active_directory/field_type/user_dn_array.rb +40 -0
- data/lib/active_directory/group.rb +138 -0
- data/lib/active_directory/member.rb +53 -0
- data/lib/active_directory/user.rb +167 -0
- data/lib/active_directory/version.rb +3 -0
- metadata +79 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
#-- license
|
2
|
+
#
|
3
|
+
# Based on original code by Justin Mecham and James Hunt
|
4
|
+
# at http://rubyforge.org/projects/activedirectory
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
#++ license
|
20
|
+
|
21
|
+
module ActiveDirectory
|
22
|
+
module FieldType
|
23
|
+
class UserDnArray
|
24
|
+
#
|
25
|
+
# Encodes an array of objects into a list of dns
|
26
|
+
#
|
27
|
+
def self.encode(obj_array)
|
28
|
+
obj_array.collect { |obj| obj.dn }
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Decodes a list of DNs into the objects that they are
|
33
|
+
#
|
34
|
+
def self.decode(dn_array)
|
35
|
+
# How to do user or group?
|
36
|
+
User.find(:all, :distinguishedname => dn_array)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
#-- license
|
2
|
+
#
|
3
|
+
# Based on original code by Justin Mecham and James Hunt
|
4
|
+
# at http://rubyforge.org/projects/activedirectory
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
#++ license
|
20
|
+
|
21
|
+
module ActiveDirectory
|
22
|
+
class Group < Base
|
23
|
+
include Member
|
24
|
+
|
25
|
+
def self.filter # :nodoc:
|
26
|
+
Net::LDAP::Filter.eq(:objectClass,'group')
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.required_attributes # :nodoc:
|
30
|
+
{ :objectClass => [ 'top', 'group' ] }
|
31
|
+
end
|
32
|
+
|
33
|
+
def reload # :nodoc:
|
34
|
+
@member_users_non_r = nil
|
35
|
+
@member_users_r = nil
|
36
|
+
@member_groups_non_r = nil
|
37
|
+
@member_groups_r = nil
|
38
|
+
@groups = nil
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Returns true if the passed User or Group object belongs to
|
44
|
+
# this group. For performance reasons, the check is handled
|
45
|
+
# by the User or Group object passed.
|
46
|
+
#
|
47
|
+
def has_member?(user)
|
48
|
+
user.member_of?(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Add the passed User or Group object to this Group. Returns true if
|
53
|
+
# the User or Group is already a member of the group, or if the operation
|
54
|
+
# to add them succeeds.
|
55
|
+
#
|
56
|
+
def add(new_member)
|
57
|
+
return false unless new_member.is_a?(User) || new_member.is_a?(Group)
|
58
|
+
if @@ldap.modify(:dn => distinguishedName, :operations => [
|
59
|
+
[ :add, :member, new_member.distinguishedName ]
|
60
|
+
])
|
61
|
+
return true
|
62
|
+
else
|
63
|
+
return has_member?(new_member)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Remove a User or Group from this Group. Returns true if the User or
|
69
|
+
# Group does not belong to this Group, or if the oepration to remove them
|
70
|
+
# succeeds.
|
71
|
+
#
|
72
|
+
def remove(member)
|
73
|
+
return false unless member.is_a?(User) || member.is_a?(Group)
|
74
|
+
if @@ldap.modify(:dn => distinguishedName, :operations => [
|
75
|
+
[ :delete, :member, member.distinguishedName ]
|
76
|
+
])
|
77
|
+
return true
|
78
|
+
else
|
79
|
+
return !has_member?(member)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def has_members?
|
84
|
+
begin
|
85
|
+
return (@entry.member.nil? || @entry.member.empty?) ? false : true
|
86
|
+
rescue NoMethodError
|
87
|
+
return false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Returns an array of all User objects that belong to this group.
|
93
|
+
#
|
94
|
+
# If the recursive argument is passed as false, then only Users who
|
95
|
+
# belong explicitly to this Group are returned.
|
96
|
+
#
|
97
|
+
# If the recursive argument is passed as true, then all Users who
|
98
|
+
# belong to this Group, or any of its subgroups, are returned.
|
99
|
+
#
|
100
|
+
def member_users(recursive = false)
|
101
|
+
return [] unless @entry.respond_to?(:member)
|
102
|
+
@member_users = User.find(:all, :distinguishedname => @entry.member).delete_if { |u| u.nil? }
|
103
|
+
if recursive then
|
104
|
+
self.member_groups.each do |group|
|
105
|
+
@member_users.concat(group.member_users(true))
|
106
|
+
end
|
107
|
+
end
|
108
|
+
return @member_users
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Returns an array of all Group objects that belong to this group.
|
113
|
+
#
|
114
|
+
# If the recursive argument is passed as false, then only Groups that
|
115
|
+
# belong explicitly to this Group are returned.
|
116
|
+
#
|
117
|
+
# If the recursive argument is passed as true, then all Groups that
|
118
|
+
# belong to this Group, or any of its subgroups, are returned.
|
119
|
+
#
|
120
|
+
def member_groups(recursive = false)
|
121
|
+
@member_groups ||= Group.find(:all, :distinguishedname => @entry.member).delete_if { |g| g.nil? }
|
122
|
+
if recursive then
|
123
|
+
self.member_groups.each do |group|
|
124
|
+
@member_groups.concat(group.member_groups(true))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
return @member_groups
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Returns an array of Group objects that this Group belongs to.
|
132
|
+
#
|
133
|
+
def groups
|
134
|
+
return [] if memberOf.nil?
|
135
|
+
@groups ||= Group.find(:all, :distinguishedname => @entry.memberOf).delete_if { |g| g.nil? }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#-- license
|
2
|
+
#
|
3
|
+
# Based on original code by Justin Mecham and James Hunt
|
4
|
+
# at http://rubyforge.org/projects/activedirectory
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
#++ license
|
20
|
+
|
21
|
+
module ActiveDirectory
|
22
|
+
module Member
|
23
|
+
#
|
24
|
+
# Returns true if this member (User or Group) is a member of
|
25
|
+
# the passed Group object.
|
26
|
+
#
|
27
|
+
def member_of?(usergroup)
|
28
|
+
group_dns = memberOf
|
29
|
+
return false if group_dns.nil? || group_dns.empty?
|
30
|
+
#group_dns = [group_dns] unless group_dns.is_a?(Array)
|
31
|
+
group_dns.include?(usergroup.dn)
|
32
|
+
end
|
33
|
+
|
34
|
+
#
|
35
|
+
# Add the member to the passed Group object. Returns true if this object
|
36
|
+
# is already a member of the Group, or if the operation to add it succeeded.
|
37
|
+
#
|
38
|
+
def join(group)
|
39
|
+
return false unless group.is_a?(Group)
|
40
|
+
group.add(self)
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# Remove the member from the passed Group object. Returns true if this
|
45
|
+
# object is not a member of the Group, or if the operation to remove it
|
46
|
+
# succeeded.
|
47
|
+
#
|
48
|
+
def unjoin(group)
|
49
|
+
return false unless group.is_a?(Group)
|
50
|
+
group.remove(self)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
#-- license
|
2
|
+
#
|
3
|
+
# Based on original code by Justin Mecham and James Hunt
|
4
|
+
# at http://rubyforge.org/projects/activedirectory
|
5
|
+
#
|
6
|
+
# This program is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# This program is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
#++ license
|
20
|
+
|
21
|
+
module ActiveDirectory
|
22
|
+
class User < Base
|
23
|
+
include Member
|
24
|
+
|
25
|
+
UAC_ACCOUNT_DISABLED = 0x0002
|
26
|
+
UAC_NORMAL_ACCOUNT = 0x0200 # 512
|
27
|
+
UAC_PASSWORD_NEVER_EXPIRES = 0x10000 #65536
|
28
|
+
|
29
|
+
def self.filter # :nodoc:
|
30
|
+
Net::LDAP::Filter.eq(:objectClass,'user') & ~Net::LDAP::Filter.eq(:objectClass,'computer')
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.required_attributes #:nodoc:
|
34
|
+
{ :objectClass => ['top', 'organizationalPerson', 'person', 'user'] }
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Try to authenticate the current User against Active Directory
|
39
|
+
# using the supplied password. Returns false upon failure.
|
40
|
+
#
|
41
|
+
# Authenticate can fail for a variety of reasons, primarily:
|
42
|
+
#
|
43
|
+
# * The password is wrong
|
44
|
+
# * The account is locked
|
45
|
+
# * The account is disabled
|
46
|
+
#
|
47
|
+
# User#locked? and User#disabled? can be used to identify the
|
48
|
+
# latter two cases, and if the account is enabled and unlocked,
|
49
|
+
# Athe password is probably invalid.
|
50
|
+
#
|
51
|
+
def authenticate(password)
|
52
|
+
return false if password.to_s.empty?
|
53
|
+
|
54
|
+
auth_ldap = @@ldap.dup.bind_as(
|
55
|
+
:filter => "(sAMAccountName=#{sAMAccountName})",
|
56
|
+
:password => password
|
57
|
+
)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Return the User's manager (another User object), depending on
|
62
|
+
# what is stored in the manager attribute.
|
63
|
+
#
|
64
|
+
# Returns nil if the schema does not include the manager attribute
|
65
|
+
# or if no manager has been configured.
|
66
|
+
#
|
67
|
+
def manager
|
68
|
+
return nil if @entry.manager.nil?
|
69
|
+
User.find_by_distinguishedName(@entry.manager.to_s)
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Returns an array of Group objects that this User belongs to.
|
74
|
+
# Only the immediate parent groups are returned, so if the user
|
75
|
+
# Sally is in a group called Sales, and Sales is in a group
|
76
|
+
# called Marketting, this method would only return the Sales group.
|
77
|
+
#
|
78
|
+
def groups
|
79
|
+
@groups ||= Group.find(:all, :distinguishedname => @entry.memberOf)
|
80
|
+
end
|
81
|
+
|
82
|
+
#
|
83
|
+
# Returns an array of User objects that have this
|
84
|
+
# User as their manager.
|
85
|
+
#
|
86
|
+
def direct_reports
|
87
|
+
return [] if @entry.directReports.nil?
|
88
|
+
@direct_reports ||= User.find(:all, @entry.directReports)
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Returns true if this account has been locked out
|
93
|
+
# (usually because of too many invalid authentication attempts).
|
94
|
+
#
|
95
|
+
# Locked accounts can be unlocked with the User#unlock! method.
|
96
|
+
#
|
97
|
+
def locked?
|
98
|
+
!lockoutTime.nil? && lockoutTime.to_i != 0
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# Returns true if this account has been disabled.
|
103
|
+
#
|
104
|
+
def disabled?
|
105
|
+
userAccountControl.to_i & UAC_ACCOUNT_DISABLED != 0
|
106
|
+
end
|
107
|
+
|
108
|
+
#
|
109
|
+
# Returns true if this account is expired.
|
110
|
+
#
|
111
|
+
def expired?
|
112
|
+
!lockoutTime.nil? && lockoutTime.to_i != 0
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# Returns true if this account has a password that does not expire.
|
117
|
+
#
|
118
|
+
def password_never_expires?
|
119
|
+
userAccountControl.to_i & UAC_PASSWORD_NEVER_EXPIRES != 0
|
120
|
+
end
|
121
|
+
|
122
|
+
#
|
123
|
+
# Returns true if the user should be able to log in with a correct
|
124
|
+
# password (essentially, their account is not disabled or locked
|
125
|
+
# out).
|
126
|
+
#
|
127
|
+
def can_login?
|
128
|
+
!disabled? && !locked?
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Change the password for this account.
|
133
|
+
#
|
134
|
+
# This operation requires that the bind user specified in
|
135
|
+
# Base.setup have heightened privileges. It also requires an
|
136
|
+
# SSL connection.
|
137
|
+
#
|
138
|
+
# If the force_change argument is passed as true, the password will
|
139
|
+
# be marked as 'expired', forcing the user to change it the next
|
140
|
+
# time they successfully log into the domain.
|
141
|
+
#
|
142
|
+
def change_password(new_password, force_change = false)
|
143
|
+
settings = @@settings.dup.merge({
|
144
|
+
:port => 636,
|
145
|
+
:encryption => { :method => :simple_tls }
|
146
|
+
})
|
147
|
+
|
148
|
+
ldap = Net::LDAP.new(settings)
|
149
|
+
ldap.modify(
|
150
|
+
:dn => distinguishedName,
|
151
|
+
:operations => [
|
152
|
+
[ :replace, :lockoutTime, [ '0' ] ],
|
153
|
+
[ :replace, :unicodePwd, [ FieldType::Password.encode(new_password) ] ],
|
154
|
+
[ :replace, :userAccountControl, [ UAC_NORMAL_ACCOUNT.to_s ] ],
|
155
|
+
[ :replace, :pwdLastSet, [ (force_change ? '0' : '-1') ] ]
|
156
|
+
]
|
157
|
+
)
|
158
|
+
end
|
159
|
+
|
160
|
+
#
|
161
|
+
# Unlocks this account.
|
162
|
+
#
|
163
|
+
def unlock!
|
164
|
+
@@ldap.replace_attribute(distinguishedName, :lockoutTime, ['0'])
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: datacom_active_directory
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.5.5.datacom
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brad Murray
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: datacom-net-ldap
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.5.0.datacom
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.5.0.datacom
|
27
|
+
description: ' Datacom NZ fork of ActiveDirectory. Uses Net::LDAP to provide a means
|
28
|
+
of accessing and modifying an Active Directory data store. This is a fork of the
|
29
|
+
activedirectory gem.'
|
30
|
+
email:
|
31
|
+
- wyaeld@gmail.com
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- .gitignore
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- active_directory.gemspec
|
40
|
+
- lib/active_directory.rb
|
41
|
+
- lib/active_directory/base.rb
|
42
|
+
- lib/active_directory/computer.rb
|
43
|
+
- lib/active_directory/container.rb
|
44
|
+
- lib/active_directory/field_type/binary.rb
|
45
|
+
- lib/active_directory/field_type/date.rb
|
46
|
+
- lib/active_directory/field_type/dn_array.rb
|
47
|
+
- lib/active_directory/field_type/group_dn_array.rb
|
48
|
+
- lib/active_directory/field_type/member_dn_array.rb
|
49
|
+
- lib/active_directory/field_type/password.rb
|
50
|
+
- lib/active_directory/field_type/timestamp.rb
|
51
|
+
- lib/active_directory/field_type/user_dn_array.rb
|
52
|
+
- lib/active_directory/group.rb
|
53
|
+
- lib/active_directory/member.rb
|
54
|
+
- lib/active_directory/user.rb
|
55
|
+
- lib/active_directory/version.rb
|
56
|
+
homepage: http://github.com/datacom/active_directory
|
57
|
+
licenses: []
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>'
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.3.1
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 2.1.11
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: An interface library for accessing Microsoft's Active Directory.
|
79
|
+
test_files: []
|