activesambaldap 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|