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.
Files changed (46) hide show
  1. data/NEWS.en +11 -3
  2. data/NEWS.ja +13 -2
  3. data/README.en +22 -3
  4. data/README.ja +21 -3
  5. data/Rakefile +38 -3
  6. data/bin/asl-groupadd +1 -1
  7. data/bin/asl-groupdel +3 -3
  8. data/bin/asl-groupmod +3 -3
  9. data/bin/asl-groupshow +1 -1
  10. data/bin/asl-passwd +1 -7
  11. data/bin/asl-populate +10 -10
  12. data/bin/asl-samba-computeradd +3 -3
  13. data/bin/asl-samba-groupadd +1 -1
  14. data/bin/asl-samba-groupdel +3 -3
  15. data/bin/asl-samba-groupmod +3 -3
  16. data/bin/asl-samba-useradd +3 -3
  17. data/bin/asl-samba-userdel +3 -3
  18. data/bin/asl-samba-usermod +3 -3
  19. data/bin/asl-useradd +4 -4
  20. data/bin/asl-userdel +3 -3
  21. data/bin/asl-usermod +3 -3
  22. data/bin/asl-usershow +1 -1
  23. data/lib/active_samba_ldap/{account.rb → account_entry.rb} +6 -1
  24. data/lib/active_samba_ldap/base.rb +8 -0
  25. data/lib/active_samba_ldap/command.rb +2 -0
  26. data/lib/active_samba_ldap/computer.rb +15 -4
  27. data/lib/active_samba_ldap/{computer_account.rb → computer_account_entry.rb} +2 -2
  28. data/lib/active_samba_ldap/configuration.rb +13 -4
  29. data/lib/active_samba_ldap/group.rb +7 -172
  30. data/lib/active_samba_ldap/group_entry.rb +188 -0
  31. data/lib/active_samba_ldap/populate.rb +7 -4
  32. data/lib/active_samba_ldap/{samba_account.rb → samba_account_entry.rb} +34 -9
  33. data/lib/active_samba_ldap/samba_entry.rb +26 -0
  34. data/lib/active_samba_ldap/{samba_group.rb → samba_group_entry.rb} +26 -10
  35. data/lib/active_samba_ldap/user.rb +33 -4
  36. data/lib/active_samba_ldap/{user_account.rb → user_account_entry.rb} +2 -2
  37. data/lib/active_samba_ldap/version.rb +1 -1
  38. data/lib/active_samba_ldap.rb +4 -2
  39. data/rails/plugin/active_samba_ldap/init.rb +1 -1
  40. data/test/asl-test-utils.rb +3 -3
  41. data/test/run-test.rb +2 -0
  42. data/test/test-unit-ext/priority.rb +4 -0
  43. metadata +17 -17
  44. data/lib/active_samba_ldap/configuration_files +0 -2
  45. data/lib/active_samba_ldap/samba_computer.rb +0 -20
  46. data/lib/active_samba_ldap/samba_user.rb +0 -39
@@ -1,182 +1,17 @@
1
- require 'English'
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
- class << self
12
- def ldap_mapping(options={})
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(SambaUser)
41
- @options[:group_class] = group_class = Class.new(SambaGroup)
42
- @options[:computer_class] = computer_class = Class.new(SambaComputer)
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
- container.save!
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 SambaAccount
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 default_classes
55
- super + ["sambaSamAccount"]
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
- if @target
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
- entry
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/group'
1
+ require 'active_samba_ldap/samba_entry'
2
2
 
3
3
  module ActiveSambaLdap
4
- class SambaGroup < Group
5
- include Reloadable
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
- class << self
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 default_classes
80
- super + ["sambaGroupMapping"]
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
- change_type(options[:group_type] || "domain") unless samba_group_type
86
- self.display_name ||= options[:display_name] || cn
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
- # pass
135
+ # pass
120
136
  else
121
137
  raise ArgumentError, "invalid type: #{type}"
122
138
  end