activesambaldap 0.0.2 → 0.0.3
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.
- data/NEWS.en +11 -3
- data/NEWS.ja +13 -2
- data/README.en +22 -3
- data/README.ja +21 -3
- data/Rakefile +38 -3
- data/bin/asl-groupadd +1 -1
- data/bin/asl-groupdel +3 -3
- data/bin/asl-groupmod +3 -3
- data/bin/asl-groupshow +1 -1
- data/bin/asl-passwd +1 -7
- data/bin/asl-populate +10 -10
- data/bin/asl-samba-computeradd +3 -3
- data/bin/asl-samba-groupadd +1 -1
- data/bin/asl-samba-groupdel +3 -3
- data/bin/asl-samba-groupmod +3 -3
- data/bin/asl-samba-useradd +3 -3
- data/bin/asl-samba-userdel +3 -3
- data/bin/asl-samba-usermod +3 -3
- data/bin/asl-useradd +4 -4
- data/bin/asl-userdel +3 -3
- data/bin/asl-usermod +3 -3
- data/bin/asl-usershow +1 -1
- data/lib/active_samba_ldap/{account.rb → account_entry.rb} +6 -1
- data/lib/active_samba_ldap/base.rb +8 -0
- data/lib/active_samba_ldap/command.rb +2 -0
- data/lib/active_samba_ldap/computer.rb +15 -4
- data/lib/active_samba_ldap/{computer_account.rb → computer_account_entry.rb} +2 -2
- data/lib/active_samba_ldap/configuration.rb +13 -4
- data/lib/active_samba_ldap/group.rb +7 -172
- data/lib/active_samba_ldap/group_entry.rb +188 -0
- data/lib/active_samba_ldap/populate.rb +7 -4
- data/lib/active_samba_ldap/{samba_account.rb → samba_account_entry.rb} +34 -9
- data/lib/active_samba_ldap/samba_entry.rb +26 -0
- data/lib/active_samba_ldap/{samba_group.rb → samba_group_entry.rb} +26 -10
- data/lib/active_samba_ldap/user.rb +33 -4
- data/lib/active_samba_ldap/{user_account.rb → user_account_entry.rb} +2 -2
- data/lib/active_samba_ldap/version.rb +1 -1
- data/lib/active_samba_ldap.rb +4 -2
- data/rails/plugin/active_samba_ldap/init.rb +1 -1
- data/test/asl-test-utils.rb +3 -3
- data/test/run-test.rb +2 -0
- data/test/test-unit-ext/priority.rb +4 -0
- metadata +17 -17
- data/lib/active_samba_ldap/configuration_files +0 -2
- data/lib/active_samba_ldap/samba_computer.rb +0 -20
- data/lib/active_samba_ldap/samba_user.rb +0 -39
@@ -1,182 +1,17 @@
|
|
1
|
-
require '
|
2
|
-
|
1
|
+
require 'active_samba_ldap/base'
|
3
2
|
require 'active_samba_ldap/entry'
|
3
|
+
require 'active_samba_ldap/samba_entry'
|
4
|
+
require 'active_samba_ldap/group_entry'
|
5
|
+
require 'active_samba_ldap/samba_group_entry'
|
4
6
|
|
5
7
|
module ActiveSambaLdap
|
6
8
|
class Group < Base
|
7
9
|
include Reloadable
|
8
10
|
|
9
11
|
include Entry
|
12
|
+
include SambaEntry
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
options = default_options.merge(options)
|
14
|
-
super(extract_ldap_mapping_options(options))
|
15
|
-
init_associations(options)
|
16
|
-
end
|
17
|
-
|
18
|
-
def find_by_name_or_gid_number(key)
|
19
|
-
group = nil
|
20
|
-
begin
|
21
|
-
gid_number = Integer(key)
|
22
|
-
group = find_by_gid_number(gid_number)
|
23
|
-
raise GidNumberDoesNotExist.new(gid_number) if group.nil?
|
24
|
-
rescue ArgumentError
|
25
|
-
raise GroupDoesNotExist.new(key) unless exists?(key)
|
26
|
-
group = find(key)
|
27
|
-
end
|
28
|
-
group
|
29
|
-
end
|
30
|
-
|
31
|
-
def find_by_gid_number(number)
|
32
|
-
attribute = "gidNumber"
|
33
|
-
value = Integer(number).to_s
|
34
|
-
find(:first, :filter => "(#{attribute}=#{value})")
|
35
|
-
end
|
36
|
-
|
37
|
-
private
|
38
|
-
def default_options
|
39
|
-
{
|
40
|
-
:dn_attribute => "cn",
|
41
|
-
:prefix => configuration[:groups_suffix],
|
42
|
-
:classes => default_classes,
|
43
|
-
|
44
|
-
:members_wrap => "memberUid",
|
45
|
-
:users_class => default_user_class,
|
46
|
-
:computers_class => default_computer_class,
|
47
|
-
|
48
|
-
:primary_members_foreign_key => "gidNumber",
|
49
|
-
:primary_members_primary_key => "gidNumber",
|
50
|
-
:primary_users_class => default_user_class,
|
51
|
-
:primary_computers_class => default_computer_class,
|
52
|
-
}
|
53
|
-
end
|
54
|
-
|
55
|
-
def default_classes
|
56
|
-
["top", "posixGroup"]
|
57
|
-
end
|
58
|
-
|
59
|
-
def default_user_class
|
60
|
-
"User"
|
61
|
-
end
|
62
|
-
|
63
|
-
def default_computer_class
|
64
|
-
"Computer"
|
65
|
-
end
|
66
|
-
|
67
|
-
def init_associations(options)
|
68
|
-
association_options = {}
|
69
|
-
options.each do |key, value|
|
70
|
-
case key.to_s
|
71
|
-
when /^((?:primary_)?(?:(?:user|computer|member)s))_/
|
72
|
-
association_options[$1] ||= {}
|
73
|
-
association_options[$1][$POSTMATCH.to_sym] = value
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
members_opts = association_options["members"] || {}
|
78
|
-
user_members_opts = association_options["users"] || {}
|
79
|
-
computer_members_opts = association_options["computers"] || {}
|
80
|
-
has_many :users, members_opts.merge(user_members_opts)
|
81
|
-
has_many :computers, members_opts.merge(computer_members_opts)
|
82
|
-
|
83
|
-
primary_members_opts = association_options["primary_members"] || {}
|
84
|
-
primary_user_members_opts =
|
85
|
-
association_options["primary_users"] || {}
|
86
|
-
primary_computer_members_opts =
|
87
|
-
association_options["primary_computers"] || {}
|
88
|
-
has_many :primary_users,
|
89
|
-
primary_members_opts.merge(primary_user_members_opts)
|
90
|
-
has_many :primary_computers,
|
91
|
-
primary_members_opts.merge(primary_computer_members_opts)
|
92
|
-
end
|
93
|
-
|
94
|
-
def prepare_create_options(group, options)
|
95
|
-
prepare_create_options_for_number(:gid_number, group, options)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def fill_default_values(options={})
|
100
|
-
gid_number = options[:gid_number]
|
101
|
-
change_gid_number(gid_number) if gid_number
|
102
|
-
self.description ||= options[:description] || cn
|
103
|
-
end
|
104
|
-
|
105
|
-
def members
|
106
|
-
users.to_ary + computers.to_ary
|
107
|
-
end
|
108
|
-
|
109
|
-
def reload_members
|
110
|
-
users.reload
|
111
|
-
computers.reload
|
112
|
-
end
|
113
|
-
|
114
|
-
def primary_members
|
115
|
-
primary_users.to_ary + primary_computers.to_ary
|
116
|
-
end
|
117
|
-
|
118
|
-
def reload_primary_members
|
119
|
-
primary_users.reload
|
120
|
-
primary_computers.reload
|
121
|
-
end
|
122
|
-
|
123
|
-
def change_gid_number(gid, allow_non_unique=false)
|
124
|
-
check_unique_gid_number(gid) unless allow_non_unique
|
125
|
-
self.gid_number = gid.to_s
|
126
|
-
end
|
127
|
-
|
128
|
-
def destroy(options={})
|
129
|
-
if options[:remove_members]
|
130
|
-
if options[:force_change_primary_members]
|
131
|
-
change_primary_members(options)
|
132
|
-
end
|
133
|
-
reload_primary_members
|
134
|
-
unless primary_members.empty?
|
135
|
-
not_destroyed_members = primary_members.collect {|x| x.uid}
|
136
|
-
raise PrimaryGroupCanNotBeDestroyed.new(cn, not_destroyed_members)
|
137
|
-
end
|
138
|
-
self.users = []
|
139
|
-
self.computers = []
|
140
|
-
end
|
141
|
-
super()
|
142
|
-
end
|
143
|
-
|
144
|
-
private
|
145
|
-
def ensure_uid(member_or_uid)
|
146
|
-
if member_or_uid.is_a?(String)
|
147
|
-
member_or_uid
|
148
|
-
else
|
149
|
-
member_or_uid.uid
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def check_unique_gid_number(gid_number)
|
154
|
-
ActiveSambaLdap::Base.restart_nscd do
|
155
|
-
if self.class.find_by_gid_number(Integer(gid_number))
|
156
|
-
raise GidNumberAlreadyExists.new(gid_number)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
def change_primary_members(options={})
|
162
|
-
name = cn
|
163
|
-
|
164
|
-
pr_members = primary_members
|
165
|
-
cannot_removed_members = []
|
166
|
-
pr_members.each do |member|
|
167
|
-
if (member.groups.collect {|group| group.cn} - [name]).empty?
|
168
|
-
cannot_removed_members << member.uid
|
169
|
-
end
|
170
|
-
end
|
171
|
-
unless cannot_removed_members.empty?
|
172
|
-
raise CanNotChangePrimaryGroup.new(name, cannot_removed_members)
|
173
|
-
end
|
174
|
-
|
175
|
-
pr_members.each do |member|
|
176
|
-
new_group = member.groups.find {|gr| gr.cn != name}
|
177
|
-
member.primary_group = new_group
|
178
|
-
member.save!
|
179
|
-
end
|
180
|
-
end
|
14
|
+
include GroupEntry
|
15
|
+
include SambaGroupEntry
|
181
16
|
end
|
182
17
|
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'English'
|
2
|
+
|
3
|
+
require 'active_samba_ldap/entry'
|
4
|
+
|
5
|
+
module ActiveSambaLdap
|
6
|
+
module GroupEntry
|
7
|
+
def self.included(base)
|
8
|
+
super
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
def ldap_mapping(options={})
|
14
|
+
options = default_options.merge(options)
|
15
|
+
super(extract_ldap_mapping_options(options))
|
16
|
+
init_associations(options)
|
17
|
+
end
|
18
|
+
|
19
|
+
def find_by_name_or_gid_number(key)
|
20
|
+
group = nil
|
21
|
+
begin
|
22
|
+
gid_number = Integer(key)
|
23
|
+
group = find_by_gid_number(gid_number)
|
24
|
+
raise GidNumberDoesNotExist.new(gid_number) if group.nil?
|
25
|
+
rescue ArgumentError
|
26
|
+
raise GroupDoesNotExist.new(key) unless exists?(key)
|
27
|
+
group = find(key)
|
28
|
+
end
|
29
|
+
group
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_by_gid_number(number)
|
33
|
+
attribute = "gidNumber"
|
34
|
+
value = Integer(number).to_s
|
35
|
+
find(:first, :filter => "(#{attribute}=#{value})")
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def default_options
|
40
|
+
{
|
41
|
+
:dn_attribute => "cn",
|
42
|
+
:prefix => configuration[:groups_suffix],
|
43
|
+
:classes => default_classes,
|
44
|
+
:recommended_classes => default_recommended_classes,
|
45
|
+
|
46
|
+
:members_wrap => "memberUid",
|
47
|
+
:users_class => default_user_class,
|
48
|
+
:computers_class => default_computer_class,
|
49
|
+
|
50
|
+
:primary_members_foreign_key => "gidNumber",
|
51
|
+
:primary_members_primary_key => "gidNumber",
|
52
|
+
:primary_users_class => default_user_class,
|
53
|
+
:primary_computers_class => default_computer_class,
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
def default_classes
|
58
|
+
["top", "posixGroup"]
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_recommended_classes
|
62
|
+
[]
|
63
|
+
end
|
64
|
+
|
65
|
+
def default_user_class
|
66
|
+
"User"
|
67
|
+
end
|
68
|
+
|
69
|
+
def default_computer_class
|
70
|
+
"Computer"
|
71
|
+
end
|
72
|
+
|
73
|
+
def init_associations(options)
|
74
|
+
association_options = {}
|
75
|
+
options.each do |key, value|
|
76
|
+
case key.to_s
|
77
|
+
when /^((?:primary_)?(?:(?:user|computer|member)s))_/
|
78
|
+
association_options[$1] ||= {}
|
79
|
+
association_options[$1][$POSTMATCH.to_sym] = value
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
members_opts = association_options["members"] || {}
|
84
|
+
user_members_opts = association_options["users"] || {}
|
85
|
+
computer_members_opts = association_options["computers"] || {}
|
86
|
+
has_many :users, members_opts.merge(user_members_opts)
|
87
|
+
has_many :computers, members_opts.merge(computer_members_opts)
|
88
|
+
|
89
|
+
primary_members_opts = association_options["primary_members"] || {}
|
90
|
+
primary_user_members_opts =
|
91
|
+
association_options["primary_users"] || {}
|
92
|
+
primary_computer_members_opts =
|
93
|
+
association_options["primary_computers"] || {}
|
94
|
+
has_many :primary_users,
|
95
|
+
primary_members_opts.merge(primary_user_members_opts)
|
96
|
+
has_many :primary_computers,
|
97
|
+
primary_members_opts.merge(primary_computer_members_opts)
|
98
|
+
end
|
99
|
+
|
100
|
+
def prepare_create_options(group, options)
|
101
|
+
prepare_create_options_for_number(:gid_number, group, options)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def fill_default_values(options={})
|
106
|
+
gid_number = options[:gid_number]
|
107
|
+
change_gid_number(gid_number) if gid_number
|
108
|
+
self.description ||= options[:description] || cn
|
109
|
+
end
|
110
|
+
|
111
|
+
def members
|
112
|
+
users.to_ary + computers.to_ary
|
113
|
+
end
|
114
|
+
|
115
|
+
def reload_members
|
116
|
+
users.reload
|
117
|
+
computers.reload
|
118
|
+
end
|
119
|
+
|
120
|
+
def primary_members
|
121
|
+
primary_users.to_ary + primary_computers.to_ary
|
122
|
+
end
|
123
|
+
|
124
|
+
def reload_primary_members
|
125
|
+
primary_users.reload
|
126
|
+
primary_computers.reload
|
127
|
+
end
|
128
|
+
|
129
|
+
def change_gid_number(gid, allow_non_unique=false)
|
130
|
+
check_unique_gid_number(gid) unless allow_non_unique
|
131
|
+
self.gid_number = gid.to_s
|
132
|
+
end
|
133
|
+
|
134
|
+
def destroy(options={})
|
135
|
+
if options[:remove_members]
|
136
|
+
if options[:force_change_primary_members]
|
137
|
+
change_primary_members(options)
|
138
|
+
end
|
139
|
+
reload_primary_members
|
140
|
+
unless primary_members.empty?
|
141
|
+
not_destroyed_members = primary_members.collect {|x| x.uid}
|
142
|
+
raise PrimaryGroupCanNotBeDestroyed.new(cn, not_destroyed_members)
|
143
|
+
end
|
144
|
+
self.users = []
|
145
|
+
self.computers = []
|
146
|
+
end
|
147
|
+
super()
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
def ensure_uid(member_or_uid)
|
152
|
+
if member_or_uid.is_a?(String)
|
153
|
+
member_or_uid
|
154
|
+
else
|
155
|
+
member_or_uid.uid
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def check_unique_gid_number(gid_number)
|
160
|
+
ActiveSambaLdap::Base.restart_nscd do
|
161
|
+
if self.class.find_by_gid_number(Integer(gid_number))
|
162
|
+
raise GidNumberAlreadyExists.new(gid_number)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def change_primary_members(options={})
|
168
|
+
name = cn
|
169
|
+
|
170
|
+
pr_members = primary_members
|
171
|
+
cannot_removed_members = []
|
172
|
+
pr_members.each do |member|
|
173
|
+
if (member.groups.collect {|group| group.cn} - [name]).empty?
|
174
|
+
cannot_removed_members << member.uid
|
175
|
+
end
|
176
|
+
end
|
177
|
+
unless cannot_removed_members.empty?
|
178
|
+
raise CanNotChangePrimaryGroup.new(name, cannot_removed_members)
|
179
|
+
end
|
180
|
+
|
181
|
+
pr_members.each do |member|
|
182
|
+
new_group = member.groups.find {|gr| gr.cn != name}
|
183
|
+
member.primary_group = new_group
|
184
|
+
member.save!
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -37,9 +37,9 @@ module ActiveSambaLdap
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def init_classes
|
40
|
-
@options[:user_class] = user_class = Class.new(
|
41
|
-
@options[:group_class] = group_class = Class.new(
|
42
|
-
@options[:computer_class] = computer_class = Class.new(
|
40
|
+
@options[:user_class] = user_class = Class.new(User)
|
41
|
+
@options[:group_class] = group_class = Class.new(Group)
|
42
|
+
@options[:computer_class] = computer_class = Class.new(Computer)
|
43
43
|
@options[:idmap_class] = idmap_class = Class.new(Idmap)
|
44
44
|
@options[:unix_id_pool_class] = id_pool_class = Class.new(UnixIdPool)
|
45
45
|
|
@@ -112,7 +112,10 @@ module ActiveSambaLdap
|
|
112
112
|
next if container_class.exists?(value, :prefix => suffix)
|
113
113
|
container = container_class.new(value)
|
114
114
|
yield(container) if block_given?
|
115
|
-
|
115
|
+
begin
|
116
|
+
container.save!
|
117
|
+
rescue ActiveLdap::OperationNotPermitted
|
118
|
+
end
|
116
119
|
entries << container
|
117
120
|
end
|
118
121
|
entries
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module ActiveSambaLdap
|
2
|
-
module
|
2
|
+
module SambaAccountEntry
|
3
3
|
def self.included(base)
|
4
4
|
super
|
5
5
|
base.extend(ClassMethods)
|
@@ -24,10 +24,15 @@ module ActiveSambaLdap
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
FAR_FUTURE_TIME = Time.parse("2050/01/01").to_i.to_s
|
27
|
+
# FAR_FUTURE_TIME = Time.parse("2050/01/01").to_i.to_s
|
28
|
+
FAR_FUTURE_TIME = Time.parse("2038/01/19").to_i.to_s
|
28
29
|
ACCOUNT_FLAGS_RE = /\A\[([NDHTUMWSLXI ]+)\]\z/
|
29
30
|
|
30
31
|
module ClassMethods
|
32
|
+
def samba_object_class
|
33
|
+
"sambaSamAccount"
|
34
|
+
end
|
35
|
+
|
31
36
|
def uid2rid(uid)
|
32
37
|
uid = Integer(uid)
|
33
38
|
if WELL_KNOWN_RIDS.include?(uid)
|
@@ -51,8 +56,8 @@ module ActiveSambaLdap
|
|
51
56
|
end
|
52
57
|
|
53
58
|
private
|
54
|
-
def
|
55
|
-
super + [
|
59
|
+
def default_recommended_classes
|
60
|
+
super + [samba_object_class]
|
56
61
|
end
|
57
62
|
|
58
63
|
def primary_group_options(options)
|
@@ -61,8 +66,10 @@ module ActiveSambaLdap
|
|
61
66
|
|
62
67
|
module PrimaryGroupProxy
|
63
68
|
def replace(entry)
|
64
|
-
super
|
65
|
-
|
69
|
+
result = super
|
70
|
+
return result unless @owner.samba_available?
|
71
|
+
|
72
|
+
if @target and @target.samba_available?
|
66
73
|
if @target.samba_sid.to_s.empty?
|
67
74
|
raise GroupDoesNotHaveSambaSID.new(@target.gid_number)
|
68
75
|
end
|
@@ -70,13 +77,15 @@ module ActiveSambaLdap
|
|
70
77
|
else
|
71
78
|
@owner.samba_primary_group_sid = nil
|
72
79
|
end
|
73
|
-
|
80
|
+
|
81
|
+
result
|
74
82
|
end
|
75
83
|
end
|
76
84
|
end
|
77
85
|
|
78
86
|
def fill_default_values(options={})
|
79
|
-
super
|
87
|
+
result = super
|
88
|
+
return result unless samba_available?
|
80
89
|
|
81
90
|
self.samba_logon_time ||= "0"
|
82
91
|
self.samba_logoff_time ||= FAR_FUTURE_TIME
|
@@ -116,45 +125,55 @@ module ActiveSambaLdap
|
|
116
125
|
end
|
117
126
|
|
118
127
|
def change_uid_number(uid, allow_non_unique=false)
|
119
|
-
super
|
128
|
+
result = super
|
129
|
+
return result unless samba_available?
|
130
|
+
|
120
131
|
rid = self.class.uid2rid(uid_number.to_s)
|
121
132
|
change_sid(rid, allow_non_unique)
|
122
133
|
end
|
123
134
|
|
124
135
|
def change_uid_number_by_rid(rid, allow_non_unique=false)
|
136
|
+
assert_samba_available
|
125
137
|
change_uid_number(self.class.rid2uid(rid), allow_non_unique)
|
126
138
|
end
|
127
139
|
|
128
140
|
def change_sid(rid, allow_non_unique=false)
|
141
|
+
assert_samba_available
|
129
142
|
sid = "#{self.class.configuration[:sid]}-#{rid}"
|
130
143
|
# check_unique_sid_number(sid) unless allow_non_unique
|
131
144
|
self.samba_sid = sid
|
132
145
|
end
|
133
146
|
|
134
147
|
def rid
|
148
|
+
assert_samba_available
|
135
149
|
Integer(samba_sid.split(/-/).last)
|
136
150
|
end
|
137
151
|
|
138
152
|
def change_samba_password(password)
|
153
|
+
assert_samba_available
|
139
154
|
self.samba_lm_password = Samba::Encrypt.lm_hash(password)
|
140
155
|
self.samba_nt_password = Samba::Encrypt.ntlm_hash(password)
|
141
156
|
self.samba_pwd_last_set = Time.now.to_i.to_s
|
142
157
|
end
|
143
158
|
|
144
159
|
def enable_password_change
|
160
|
+
assert_samba_available
|
145
161
|
self.samba_pwd_can_change = "0"
|
146
162
|
end
|
147
163
|
|
148
164
|
def disable_password_change
|
165
|
+
assert_samba_available
|
149
166
|
self.samba_pwd_can_change = FAR_FUTURE_TIME
|
150
167
|
end
|
151
168
|
|
152
169
|
def can_change_password?
|
170
|
+
assert_samba_available
|
153
171
|
samba_pwd_can_change.nil? or
|
154
172
|
Time.at(samba_pwd_can_change.to_i) <= Time.now
|
155
173
|
end
|
156
174
|
|
157
175
|
def enable_forcing_password_change
|
176
|
+
assert_samba_available
|
158
177
|
self.samba_pwd_must_change = "0"
|
159
178
|
if /X/ =~ samba_acct_flags.to_s
|
160
179
|
self.samba_acct_flags = samba_acct_flags.sub(/X/, '')
|
@@ -165,22 +184,26 @@ module ActiveSambaLdap
|
|
165
184
|
end
|
166
185
|
|
167
186
|
def disable_forcing_password_change
|
187
|
+
assert_samba_available
|
168
188
|
self.samba_pwd_must_change = FAR_FUTURE_TIME
|
169
189
|
end
|
170
190
|
|
171
191
|
def must_change_password?
|
192
|
+
assert_samba_available
|
172
193
|
!(/X/ =~ samba_acct_flags.to_s or
|
173
194
|
samba_pwd_must_change.nil? or
|
174
195
|
Time.at(samba_pwd_must_change.to_i) > Time.now)
|
175
196
|
end
|
176
197
|
|
177
198
|
def enable
|
199
|
+
assert_samba_available
|
178
200
|
if /D/ =~ samba_acct_flags.to_s
|
179
201
|
self.samba_acct_flags = samba_acct_flags.gsub(/D/, '')
|
180
202
|
end
|
181
203
|
end
|
182
204
|
|
183
205
|
def disable
|
206
|
+
assert_samba_available
|
184
207
|
flags = ""
|
185
208
|
if ACCOUNT_FLAGS_RE =~ samba_acct_flags.to_s
|
186
209
|
flags = $1
|
@@ -190,10 +213,12 @@ module ActiveSambaLdap
|
|
190
213
|
end
|
191
214
|
|
192
215
|
def enabled?
|
216
|
+
assert_samba_available
|
193
217
|
!disabled?
|
194
218
|
end
|
195
219
|
|
196
220
|
def disabled?
|
221
|
+
assert_samba_available
|
197
222
|
(/D/ =~ samba_acct_flags.to_s) ? true : false
|
198
223
|
end
|
199
224
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ActiveSambaLdap
|
2
|
+
module SambaEntry
|
3
|
+
def samba_available?
|
4
|
+
classes.include?(samba_object_class)
|
5
|
+
end
|
6
|
+
|
7
|
+
def remove_samba_availability
|
8
|
+
remove_class(samba_object_class)
|
9
|
+
end
|
10
|
+
|
11
|
+
def ensure_samba_available
|
12
|
+
add_class(samba_object_class)
|
13
|
+
end
|
14
|
+
|
15
|
+
def samba_object_class
|
16
|
+
self.class.samba_object_class
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def assert_samba_available
|
21
|
+
unless samba_available?
|
22
|
+
raise NotSambaAavialableError.new(self)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,8 +1,13 @@
|
|
1
|
-
require 'active_samba_ldap/
|
1
|
+
require 'active_samba_ldap/samba_entry'
|
2
2
|
|
3
3
|
module ActiveSambaLdap
|
4
|
-
|
5
|
-
include
|
4
|
+
module SambaGroupEntry
|
5
|
+
include SambaEntry
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
super
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
6
11
|
|
7
12
|
# from librpc/ndr/security.h in Samba
|
8
13
|
SID_BUILTIN = "S-1-5-32"
|
@@ -52,7 +57,11 @@ module ActiveSambaLdap
|
|
52
57
|
"builtin" => 5,
|
53
58
|
}
|
54
59
|
|
55
|
-
|
60
|
+
module ClassMethods
|
61
|
+
def samba_object_class
|
62
|
+
"sambaGroupMapping"
|
63
|
+
end
|
64
|
+
|
56
65
|
def gid2rid(gid)
|
57
66
|
gid = Integer(gid)
|
58
67
|
if WELL_KNOWN_RIDS.include?(gid)
|
@@ -76,28 +85,33 @@ module ActiveSambaLdap
|
|
76
85
|
end
|
77
86
|
|
78
87
|
private
|
79
|
-
def
|
80
|
-
super + [
|
88
|
+
def default_recommended_classes
|
89
|
+
super + [samba_object_class]
|
81
90
|
end
|
82
91
|
end
|
83
92
|
|
84
93
|
def fill_default_values(options={})
|
85
|
-
|
86
|
-
|
94
|
+
if samba_available?
|
95
|
+
change_type(options[:group_type] || "domain") unless samba_group_type
|
96
|
+
self.display_name ||= options[:display_name] || cn
|
97
|
+
end
|
87
98
|
super
|
88
99
|
end
|
89
100
|
|
90
101
|
def change_gid_number(gid, allow_non_unique=false)
|
91
|
-
super
|
102
|
+
result = super
|
103
|
+
return result unless samba_available?
|
92
104
|
rid = self.class.gid2rid(gid_number.to_s)
|
93
105
|
change_sid(rid, allow_non_unique)
|
94
106
|
end
|
95
107
|
|
96
108
|
def change_gid_number_by_rid(rid, allow_non_unique=false)
|
109
|
+
assert_samba_available
|
97
110
|
change_gid_number(self.class.rid2gid(rid), allow_non_unique)
|
98
111
|
end
|
99
112
|
|
100
113
|
def change_sid(rid, allow_non_unique=false)
|
114
|
+
assert_samba_available
|
101
115
|
if (LOCAL_ADMINS_RID..LOCAL_REPLICATORS_RID).include?(rid.to_i)
|
102
116
|
sid = "#{SID_BUILTIN}-#{rid}"
|
103
117
|
else
|
@@ -108,15 +122,17 @@ module ActiveSambaLdap
|
|
108
122
|
end
|
109
123
|
|
110
124
|
def rid
|
125
|
+
assert_samba_available
|
111
126
|
Integer(samba_sid.split(/-/).last)
|
112
127
|
end
|
113
128
|
|
114
129
|
def change_type(type)
|
130
|
+
assert_samba_available
|
115
131
|
normalized_type = type.to_s.downcase
|
116
132
|
if TYPES.has_key?(normalized_type)
|
117
133
|
type = TYPES[normalized_type]
|
118
134
|
elsif TYPES.values.include?(type.to_i)
|
119
|
-
|
135
|
+
# pass
|
120
136
|
else
|
121
137
|
raise ArgumentError, "invalid type: #{type}"
|
122
138
|
end
|