bsb_active_directory 8.0

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.
@@ -0,0 +1,114 @@
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
+ #
23
+ # The ActiveDirectory::Container class represents a more malleable way
24
+ # of dealing with LDAP Distinguished Names (dn), like
25
+ # "cn=UserName,ou=Users,dc=example,dc=org".
26
+ #
27
+ # The following two representations of the above dn are identical:
28
+ #
29
+ # dn = "cn=UserName,ou=Users,dc=example,dc=org"
30
+ # dn = ActiveDirectory::Container.dc('org').dc('example').ou('Users').cn('UserName').to_s
31
+ #
32
+ class Container
33
+ attr_reader :type
34
+ attr_reader :name
35
+ attr_reader :parent
36
+
37
+ def initialize(type, name, node = nil) #:nodoc:
38
+ @type = type
39
+ @name = name
40
+ @node = node
41
+ end
42
+
43
+ #
44
+ # Creates a starting OU (Organizational Unit) dn part.
45
+ #
46
+ # # ou_part = "ou=OrganizationalUnit"
47
+ # ou_part = ActiveDirectory::Container.ou('OrganizationalUnit').to_s
48
+ #
49
+ def self.ou(name)
50
+ new(:ou, name, nil)
51
+ end
52
+
53
+ #
54
+ # Creates a starting DC (Domain Component) dn part.
55
+ #
56
+ # # dc_part = "dc=net"
57
+ # dc_part = ActiveDirectory::Container.dc('net').to_s
58
+ #
59
+ def self.dc(name)
60
+ new(:dc, name, nil)
61
+ end
62
+
63
+ #
64
+ # Creates a starting CN (Canonical Name) dn part.
65
+ #
66
+ # # cn_part = "cn=CanonicalName"
67
+ # cn_part = ActiveDirectory::Container.cn('CanonicalName').to_s
68
+ #
69
+ def self.cn(name)
70
+ new(:cn, name, nil)
71
+ end
72
+
73
+ #
74
+ # Appends an OU (Organizational Unit) dn part to another Container.
75
+ #
76
+ # # ou = "ou=InfoTech,dc=net"
77
+ # ou = ActiveDirectory::Container.dc("net").ou("InfoTech").to_s
78
+ #
79
+ def ou(name)
80
+ self.class.new(:ou, name, self)
81
+ end
82
+
83
+ #
84
+ # Appends a DC (Domain Component) dn part to another Container.
85
+ #
86
+ # # base = "dc=example,dc=net"
87
+ # base = ActiveDirectory::Container.dc("net").dc("example").to_s
88
+ #
89
+ def dc(name)
90
+ self.class.new(:dc, name, self)
91
+ end
92
+
93
+ #
94
+ # Appends a CN (Canonical Name) dn part to another Container.
95
+ #
96
+ # # user = "cn=UID,ou=Users"
97
+ # user = ActiveDirectory::Container.ou("Users").cn("UID")
98
+ #
99
+ def cn(name)
100
+ self.class.new(:cn, name, self)
101
+ end
102
+
103
+ #
104
+ # Converts the Container object to its String representation.
105
+ #
106
+ def to_s
107
+ @node ? "#{@type}=#{name},#{@node}" : "#{@type}=#{name}"
108
+ end
109
+
110
+ def ==(other) #:nodoc:
111
+ to_s.casecmp(other.to_s.downcase).zero?
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,39 @@
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 Binary
24
+ #
25
+ # Encodes a hex string into a GUID
26
+ #
27
+ def self.encode(hex_string)
28
+ [hex_string].pack('H*')
29
+ end
30
+
31
+ #
32
+ # Decodes a binary GUID as a hex string
33
+ #
34
+ def self.decode(guid)
35
+ guid.unpack('H*').first.to_s
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
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 Date
24
+ #
25
+ # Converts a time object into an ISO8601 format compatable with Active Directory
26
+ #
27
+ def self.encode(local_time)
28
+ local_time.strftime('%Y%m%d%H%M%S.0Z')
29
+ end
30
+
31
+ #
32
+ # Decodes an Active Directory date when stored as ISO8601
33
+ #
34
+ def self.decode(remote_time)
35
+ Time.parse(remote_time)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -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 DnArray
24
+ #
25
+ # Encodes an array of objects into a list of dns
26
+ #
27
+ def self.encode(obj_array)
28
+ obj_array.collect(&: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
+ Base.find(:all, distinguishedname: dn_array)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -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 GroupDnArray
24
+ #
25
+ # Encodes an array of objects into a list of dns
26
+ #
27
+ def self.encode(obj_array)
28
+ obj_array.collect(&: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
+ Group.find(:all, distinguishedname: dn_array)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,47 @@
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 MemberDnArray
24
+ #
25
+ # Encodes an array of objects into a list of dns
26
+ #
27
+ def self.encode(obj_array)
28
+ obj_array.collect(&: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
+ # Ensures that the objects are cast correctly
36
+ users = User.find(:all, distinguishedname: dn_array)
37
+ groups = Group.find(:all, distinguishedname: dn_array)
38
+
39
+ arr = []
40
+ arr << users unless users.nil?
41
+ arr << groups unless groups.nil?
42
+
43
+ arr.flatten
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,41 @@
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 Password
24
+ #
25
+ # Encodes an unencrypted password into an encrypted password
26
+ # that the Active Directory server will understand.
27
+ #
28
+ def self.encode(password)
29
+ ("\"#{password}\"".split(//).collect { |c| "#{c}\000" }).join
30
+ end
31
+
32
+ #
33
+ # Always returns nil, since you can't decrypt the User's encrypted
34
+ # password.
35
+ #
36
+ def self.decode(_hashed)
37
+ nil
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,45 @@
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 Timestamp
24
+ AD_DIVISOR = 10_000_000 #:nodoc:
25
+ AD_OFFSET = 11_644_473_600 #:nodoc:
26
+
27
+ #
28
+ # Encodes a local Time object (or the number of seconds since January
29
+ # 1, 1970) into a timestamp that the Active Directory server can
30
+ # understand (number of 100 nanosecond time units since January 1, 1600)
31
+ #
32
+ def self.encode(local_time)
33
+ (local_time.to_i + AD_OFFSET) * AD_DIVISOR
34
+ end
35
+
36
+ #
37
+ # Decodes an Active Directory timestamp (the number of 100 nanosecond time
38
+ # units since January 1, 1600) into a Ruby Time object.
39
+ #
40
+ def self.decode(remote_time)
41
+ Time.at((remote_time.to_i / AD_DIVISOR) - AD_OFFSET)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -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(&: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,160 @@
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
+ require 'bsb_active_directory/attributes'
22
+
23
+ module ActiveDirectory
24
+ class Group < Base
25
+ include Member
26
+
27
+ def self.filter # :nodoc:
28
+ Net::LDAP::Filter.eq(:objectClass, 'group')
29
+ end
30
+
31
+ def self.required_attributes # :nodoc:
32
+ { objectClass: %w[top group] }
33
+ end
34
+
35
+ def reload # :nodoc:
36
+ @member_users_non_r = nil
37
+ @member_users_r = nil
38
+ @member_groups_non_r = nil
39
+ @member_groups_r = nil
40
+ @groups = nil
41
+ super
42
+ end
43
+
44
+ #
45
+ # Returns true if the passed User or Group object belongs to
46
+ # this group. For performance reasons, the check is handled
47
+ # by the User or Group object passed.
48
+ #
49
+ def has_member?(user)
50
+ user.member_of?(self)
51
+ end
52
+
53
+ def self.create_security_group(ou, name, type)
54
+ type_mask = GroupType::SECURITY_ENABLED
55
+ case type
56
+ when :local
57
+ type_mask |= GroupType::RESSOURCE_GROUP
58
+ when :global
59
+ type_mask |= GroupType::ACCOUNT_GROUP
60
+ when :universal
61
+ type_mask |= GroupType::UNIVERSAL_GROUP
62
+ else
63
+ raise "Unknown type specified : #{type}"
64
+ end
65
+ dn = 'CN=' + name + ',' + ou
66
+ attributes = {
67
+ objectClass: %w[top group],
68
+ sAMAccountName: name,
69
+ objectCategory: 'CN=Group,CN=Schema,CN=Configuration,DC=afssa,DC=fr',
70
+ groupType: type_mask.to_s
71
+ }
72
+ @@ldap.add(dn: dn, attributes: attributes)
73
+ from_dn(dn)
74
+ end
75
+
76
+ #
77
+ # Add the passed User or Group object to this Group. Returns true if
78
+ # the User or Group is already a member of the group, or if the operation
79
+ # to add them succeeds.
80
+ #
81
+ def add(new_member)
82
+ return false unless new_member.is_a?(User) || new_member.is_a?(Group)
83
+ if @@ldap.modify(dn: distinguishedName, operations: [
84
+ [:add, :member, new_member.distinguishedName]
85
+ ])
86
+ return true
87
+ else
88
+ return has_member?(new_member)
89
+ end
90
+ end
91
+
92
+ #
93
+ # Remove a User or Group from this Group. Returns true if the User or
94
+ # Group does not belong to this Group, or if the oepration to remove them
95
+ # succeeds.
96
+ #
97
+ def remove(member)
98
+ return false unless member.is_a?(User) || member.is_a?(Group)
99
+ if @@ldap.modify(dn: distinguishedName, operations: [
100
+ [:delete, :member, member.distinguishedName]
101
+ ])
102
+ return true
103
+ else
104
+ return !has_member?(member)
105
+ end
106
+ end
107
+
108
+ def has_members?
109
+ return @entry.member.nil? || @entry.member.empty? ? false : true
110
+ rescue NoMethodError
111
+ return false
112
+ end
113
+
114
+ #
115
+ # Returns an array of all User objects that belong to this group.
116
+ #
117
+ # If the recursive argument is passed as false, then only Users who
118
+ # belong explicitly to this Group are returned.
119
+ #
120
+ # If the recursive argument is passed as true, then all Users who
121
+ # belong to this Group, or any of its subgroups, are returned.
122
+ #
123
+ def member_users(recursive = false)
124
+ @member_users = User.find(:all, distinguishedname: @entry[:member]).delete_if(&:nil?)
125
+ if recursive
126
+ member_groups.each do |group|
127
+ @member_users.concat(group.member_users(true))
128
+ end
129
+ end
130
+ @member_users
131
+ end
132
+
133
+ #
134
+ # Returns an array of all Group objects that belong to this group.
135
+ #
136
+ # If the recursive argument is passed as false, then only Groups that
137
+ # belong explicitly to this Group are returned.
138
+ #
139
+ # If the recursive argument is passed as true, then all Groups that
140
+ # belong to this Group, or any of its subgroups, are returned.
141
+ #
142
+ def member_groups(recursive = false)
143
+ @member_groups ||= Group.find(:all, distinguishedname: @entry[:member]).delete_if(&:nil?)
144
+ if recursive
145
+ member_groups.each do |group|
146
+ @member_groups.concat(group.member_groups(true))
147
+ end
148
+ end
149
+ @member_groups
150
+ end
151
+
152
+ #
153
+ # Returns an array of Group objects that this Group belongs to.
154
+ #
155
+ def groups
156
+ return [] if memberOf.nil?
157
+ @groups ||= Group.find(:all, distinguishedname: @entry.memberOf).delete_if(&:nil?)
158
+ end
159
+ end
160
+ 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.map(&:dn).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