activesambaldap 0.0.1

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 (85) hide show
  1. data/NEWS.en +9 -0
  2. data/NEWS.ja +10 -0
  3. data/README.en +310 -0
  4. data/README.ja +307 -0
  5. data/Rakefile +95 -0
  6. data/bin/asl-groupadd +70 -0
  7. data/bin/asl-groupdel +58 -0
  8. data/bin/asl-groupmod +133 -0
  9. data/bin/asl-groupshow +31 -0
  10. data/bin/asl-passwd +99 -0
  11. data/bin/asl-populate +96 -0
  12. data/bin/asl-purge +24 -0
  13. data/bin/asl-samba-computeradd +94 -0
  14. data/bin/asl-samba-groupadd +55 -0
  15. data/bin/asl-samba-groupdel +53 -0
  16. data/bin/asl-samba-groupmod +98 -0
  17. data/bin/asl-samba-useradd +98 -0
  18. data/bin/asl-samba-userdel +47 -0
  19. data/bin/asl-samba-usermod +92 -0
  20. data/bin/asl-useradd +263 -0
  21. data/bin/asl-userdel +75 -0
  22. data/bin/asl-usermod +335 -0
  23. data/bin/asl-usershow +31 -0
  24. data/lib/active_samba_ldap/account.rb +199 -0
  25. data/lib/active_samba_ldap/base.rb +126 -0
  26. data/lib/active_samba_ldap/command.rb +94 -0
  27. data/lib/active_samba_ldap/computer.rb +13 -0
  28. data/lib/active_samba_ldap/computer_account.rb +34 -0
  29. data/lib/active_samba_ldap/configuration.rb +322 -0
  30. data/lib/active_samba_ldap/dc.rb +17 -0
  31. data/lib/active_samba_ldap/entry.rb +80 -0
  32. data/lib/active_samba_ldap/group.rb +182 -0
  33. data/lib/active_samba_ldap/idmap.rb +17 -0
  34. data/lib/active_samba_ldap/ou.rb +18 -0
  35. data/lib/active_samba_ldap/populate.rb +254 -0
  36. data/lib/active_samba_ldap/samba_account.rb +200 -0
  37. data/lib/active_samba_ldap/samba_computer.rb +20 -0
  38. data/lib/active_samba_ldap/samba_group.rb +126 -0
  39. data/lib/active_samba_ldap/samba_user.rb +39 -0
  40. data/lib/active_samba_ldap/unix_id_pool.rb +41 -0
  41. data/lib/active_samba_ldap/user.rb +14 -0
  42. data/lib/active_samba_ldap/user_account.rb +30 -0
  43. data/lib/active_samba_ldap/version.rb +3 -0
  44. data/lib/active_samba_ldap.rb +29 -0
  45. data/lib/samba/encrypt.rb +86 -0
  46. data/misc/rd2html.rb +42 -0
  47. data/rails/plugin/active_samba_ldap/README +30 -0
  48. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/scaffold_asl_generator.rb +28 -0
  49. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/computer.rb +3 -0
  50. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/dc.rb +3 -0
  51. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/group.rb +3 -0
  52. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/idmap.rb +3 -0
  53. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/ldap.yml +24 -0
  54. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/ou.rb +3 -0
  55. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_controller.rb +12 -0
  56. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_helper.rb +2 -0
  57. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_index.rhtml +17 -0
  58. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_populate.rhtml +15 -0
  59. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_purge.rhtml +10 -0
  60. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/unix_id_pool.rb +3 -0
  61. data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/user.rb +3 -0
  62. data/rails/plugin/active_samba_ldap/init.rb +6 -0
  63. data/test/asl-test-utils.rb +276 -0
  64. data/test/command.rb +64 -0
  65. data/test/config.yaml.sample +17 -0
  66. data/test/run-test.rb +18 -0
  67. data/test/test-unit-ext/always-show-result.rb +28 -0
  68. data/test/test-unit-ext/priority.rb +159 -0
  69. data/test/test-unit-ext.rb +2 -0
  70. data/test/test_asl_groupadd.rb +69 -0
  71. data/test/test_asl_groupdel.rb +88 -0
  72. data/test/test_asl_groupmod.rb +256 -0
  73. data/test/test_asl_groupshow.rb +21 -0
  74. data/test/test_asl_passwd.rb +125 -0
  75. data/test/test_asl_populate.rb +92 -0
  76. data/test/test_asl_purge.rb +21 -0
  77. data/test/test_asl_useradd.rb +710 -0
  78. data/test/test_asl_userdel.rb +73 -0
  79. data/test/test_asl_usermod.rb +541 -0
  80. data/test/test_asl_usershow.rb +27 -0
  81. data/test/test_group.rb +21 -0
  82. data/test/test_password.rb +51 -0
  83. data/test/test_samba_encrypt.rb +36 -0
  84. data/test/test_user_home_directory.rb +43 -0
  85. metadata +177 -0
@@ -0,0 +1,126 @@
1
+ module ActiveSambaLdap
2
+ class Error < StandardError
3
+ end
4
+
5
+ class RequiredVariableIsNotSet < Error
6
+ attr_reader :name
7
+ def initialize(name)
8
+ @name = name
9
+ super("required variable '#{name}' is not set")
10
+ end
11
+ end
12
+
13
+ class RequiredVariablesAreNotSet < RequiredVariableIsNotSet
14
+ attr_reader :names
15
+ def initialize(names)
16
+ @names = names
17
+ super("required variables '#{names.join(', ')}' are not set")
18
+ end
19
+ end
20
+
21
+ class UidNumberAlreadyExists < Error
22
+ attr_reader :number
23
+ def initialize(number)
24
+ @number = number
25
+ super("uid number '#{@number}' already exists")
26
+ end
27
+ end
28
+
29
+ class GroupDoesNotExist < Error
30
+ attr_reader :name
31
+ def initialize(name)
32
+ @name = name
33
+ super("group '#{@name}' doesn't exist")
34
+ end
35
+ end
36
+
37
+ class GidNumberAlreadyExists < Error
38
+ attr_reader :number
39
+ def initialize(number)
40
+ @number = number
41
+ super("gid number '#{@number}' already exists")
42
+ end
43
+ end
44
+
45
+ class GidNumberDoesNotExist < Error
46
+ attr_reader :number
47
+ def initialize(number)
48
+ @number = number
49
+ super("gid number '#{@number}' doesn't exist")
50
+ end
51
+ end
52
+
53
+ class GroupDoesNotHaveSambaSID < Error
54
+ attr_reader :number
55
+ def initialize(number)
56
+ @number = number
57
+ super("sambaSID attribute doesn't exist for gid number '#{@number}'")
58
+ end
59
+ end
60
+
61
+ class CanNotChangePrimaryGroup < Error
62
+ attr_reader :group, :members
63
+ def initialize(group, members)
64
+ @group = group
65
+ @members = members
66
+ message = "cannot change primary group from '#{group}' to other group "
67
+ message << "due to no other belonged groups: #{members.join(', ')}"
68
+ super(message)
69
+ end
70
+ end
71
+
72
+ class PrimaryGroupCanNotBeDestroyed < Error
73
+ attr_reader :group, :members
74
+ def initialize(group, members)
75
+ @group = group
76
+ @members = members
77
+ message = "cannot destroy group '#{group}' due to members who belong "
78
+ message << "to the group as primary group: #{members.join(', ')}"
79
+ super(message)
80
+ end
81
+ end
82
+
83
+ class InvalidConfigurationFormatError < Error
84
+ attr_reader :file, :location, :detail
85
+ def initialize(file, location, detail)
86
+ @file = file
87
+ @location = location
88
+ @detail = detail
89
+ super("found invalid configuration format at #{@file}:#{@location}" +
90
+ ": #{@detail}")
91
+ end
92
+ end
93
+
94
+ class InvalidConfigurationValueError < Error
95
+ attr_reader :name, :value, :detail
96
+ def initialize(name, value, detail)
97
+ @name = name
98
+ @value = value
99
+ @detail = detail
100
+ super("the value of #{@name} '#{@value.inspect}' is invalid: #{@detail}")
101
+ end
102
+ end
103
+
104
+ class Base < ActiveLdap::Base
105
+ include Reloadable::Subclasses
106
+
107
+ class << self
108
+ def restart_nscd
109
+ nscd_working = system("/etc/init.d/nscd status >/dev/null 2>&1")
110
+ system("/etc/init.d/nscd stop >/dev/null 2>&1") if nscd_working
111
+ yield if block_given?
112
+ ensure
113
+ system("/etc/init.d/nscd start >/dev/null 2>&1") if nscd_working
114
+ end
115
+
116
+ private
117
+ def extract_ldap_mapping_options(options)
118
+ extracted_options = {}
119
+ ActiveLdap::Base::VALID_LDAP_MAPPING_OPTIONS.each do |key|
120
+ extracted_options[key] = options[key] if options.has_key?(key)
121
+ end
122
+ extracted_options
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,94 @@
1
+ require 'optparse'
2
+ require 'ostruct'
3
+
4
+ module ActiveSambaLdap
5
+ module Command
6
+ module_function
7
+ def parse_options(argv=nil)
8
+ argv ||= ARGV.dup
9
+ options = OpenStruct.new
10
+ configuration_files = default_configuration_files
11
+ opts = OptionParser.new do |opts|
12
+ yield(opts, options)
13
+
14
+ opts.separator ""
15
+ opts.separator "Common options:"
16
+
17
+ opts.on_tail("--config=CONFIG",
18
+ "Specify configuration file",
19
+ "Default configuration files:",
20
+ *configuration_files.collect {|x| " #{x}"}) do |file|
21
+ configuration_files << file
22
+ end
23
+
24
+ opts.on_tail("-h", "--help", "Show this message") do
25
+ puts opts
26
+ exit
27
+ end
28
+
29
+ opts.on_tail("--version", "Show version") do
30
+ puts VERSION
31
+ exit
32
+ end
33
+ end
34
+
35
+ begin
36
+ opts.parse!(argv)
37
+ rescue OptionParser::ParseError
38
+ $stderr.puts($!)
39
+ $stderr.puts(opts)
40
+ exit 1
41
+ end
42
+
43
+ read_configuration_files(configuration_files)
44
+
45
+ [argv, opts, options]
46
+ end
47
+
48
+ def read_password(prompt, input=$stdin, output=$stdout)
49
+ output.print prompt
50
+ system "/bin/stty -echo" if input.tty?
51
+ input.gets.chomp
52
+ ensure
53
+ system "/bin/stty echo" if input.tty?
54
+ output.puts
55
+ end
56
+
57
+ def default_configuration_files
58
+ configuration_files = File.join(File.dirname(__FILE__),
59
+ "configuration_files")
60
+ if File.exists?(configuration_files)
61
+ files = File.readlines(configuration_files).collect do |line|
62
+ line.strip
63
+ end.reject do |line|
64
+ line.empty? or /^#/ =~ line
65
+ end
66
+ else
67
+ files = [
68
+ "/etc/activesambaldap/config.yaml",
69
+ "/etc/activesambaldap/bind.yaml",
70
+ ]
71
+ end
72
+ begin
73
+ configuration_files_for_user = [
74
+ File.expand_path(File.join("~", ".activesambaldap.conf")),
75
+ File.expand_path(File.join("~", ".activesambaldap.bind")),
76
+ ]
77
+ files.concat(configuration_files_for_user)
78
+ rescue ArgumentError
79
+ end
80
+ files
81
+ end
82
+
83
+ def read_configuration_files(files)
84
+ return if files.empty?
85
+ Base.configurations = files.inject({}) do |result, file|
86
+ if File.readable?(file)
87
+ result.merge(Configuration.read(file))
88
+ else
89
+ result
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_samba_ldap/account'
2
+ require 'active_samba_ldap/computer_account'
3
+
4
+ module ActiveSambaLdap
5
+ class Computer < Base
6
+ include Reloadable::Subclasses
7
+
8
+ include Entry
9
+
10
+ include Account
11
+ include ComputerAccount
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ module ActiveSambaLdap
2
+ module ComputerAccount
3
+ NAME_RE = /\A#{Account::NAME_RE_SRC}\$\z/
4
+
5
+ def self.included(base)
6
+ super
7
+ base.extend(ClassMethods)
8
+ base.validates_format_of :uid, :with => NAME_RE
9
+ end
10
+
11
+ module ClassMethods
12
+ def valid_name?(name)
13
+ NAME_RE =~ name ? true : false
14
+ end
15
+
16
+ private
17
+ def default_prefix
18
+ configuration[:computers_suffix]
19
+ end
20
+ end
21
+
22
+ def remove_from_group(group)
23
+ group.computers.delete(self)
24
+ end
25
+
26
+ def default_gid_number
27
+ self.class.configuration[:default_computer_gid]
28
+ end
29
+
30
+ def created_group_name
31
+ super.sub(/\$$/, '')
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,322 @@
1
+ require 'socket'
2
+
3
+ module ActiveSambaLdap
4
+ module Configuration
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ class << self
10
+ def read(file)
11
+ require 'yaml'
12
+ require 'erb'
13
+ erb = ERB.new(File.read(file))
14
+ erb.filename = file
15
+ result = nil
16
+ begin
17
+ begin
18
+ result = YAML.load(erb.result)
19
+ unless result
20
+ raise InvalidConfigurationFormatError.new(file, "0",
21
+ "empty source")
22
+ end
23
+ rescue ArgumentError
24
+ if /syntax error on line (\d+), col (\d+): `(.*)'/ =~ $!.message
25
+ raise InvalidConfigurationFormatError.new(file, "#{$1}:#{$2}", $3)
26
+ else
27
+ raise
28
+ end
29
+ end
30
+ rescue InvalidConfigurationFormatError
31
+ raise
32
+ rescue Exception
33
+ file, location = $@.first.split(/:/, 2)
34
+ detail = "#{$!.class}: #{$!.message}"
35
+ raise InvalidConfigurationFormatError.new(file, location, detail)
36
+ end
37
+ result
38
+ end
39
+ end
40
+
41
+ module ClassMethods
42
+ class ValidHash < Hash
43
+ def [](name)
44
+ if Private.required_variables.include?(name) and !has_key?(name)
45
+ raise RequiredVariableIsNotSet.new(name)
46
+ end
47
+ super(name)
48
+ end
49
+ end
50
+
51
+ def merge_configuration(config)
52
+ config = config.symbolize_keys
53
+ config = (configurations["common"] || {}).symbolize_keys.merge(config)
54
+ ValidHash.new.merge(super(Private.new(config).merge))
55
+ end
56
+
57
+ def required_configuration_variables(*names)
58
+ config = configuration
59
+ if config.nil?
60
+ missing_variables = names
61
+ else
62
+ missing_variables = names.find_all do |name|
63
+ config[name.to_sym].nil?
64
+ end
65
+ end
66
+ unless missing_variables.empty?
67
+ raise RequiredVariablesAreNotSet.new(missing_variables)
68
+ end
69
+ end
70
+
71
+ class Private
72
+ VARIABLES = %w(base host port scope bind_dn
73
+ password method allow_anonymous
74
+
75
+ sid smb_conf samba_domain samba_netbios_name
76
+ password_hash_type
77
+
78
+ users_suffix groups_suffix computers_suffix
79
+ idmap_suffix
80
+
81
+ start_uid start_gid
82
+
83
+ user_login_shell user_home_directory
84
+ user_home_directory_mode
85
+ user_gecos user_home_unc user_profile
86
+ user_home_drive user_logon_script mail_domain
87
+
88
+ skeleton_directory
89
+
90
+ default_user_gid default_computer_gid
91
+ default_max_password_age)
92
+
93
+ class << self
94
+ def required_variables
95
+ @required_variables ||= compute_required_variables
96
+ end
97
+
98
+ def compute_required_variables
99
+ not_required_variables = %w(base ldap_scope)
100
+ (VARIABLES - public_methods - not_required_variables).collect do |x|
101
+ x.to_sym
102
+ end
103
+ end
104
+ end
105
+
106
+ def initialize(target)
107
+ @target = target.symbolize_keys
108
+ end
109
+
110
+ def merge
111
+ result = @target.dup
112
+ VARIABLES.each do |variable|
113
+ key = variable.to_sym
114
+ result[key] ||= send(variable) if respond_to?(variable)
115
+
116
+ normalize_method = "normalize_#{variable}"
117
+ if respond_to?(normalize_method)
118
+ result[key] = __send__(normalize_method, result[key])
119
+ end
120
+
121
+ validate_method = "validate_#{variable}"
122
+ if respond_to?(validate_method)
123
+ __send__(validate_method, result[key])
124
+ end
125
+ end
126
+ result
127
+ end
128
+
129
+ def [](name)
130
+ @target[name.to_sym] || (respond_to?(name) ? send(name) : nil)
131
+ end
132
+
133
+ def sid
134
+ result = `net getlocalsid`
135
+ if $?.success?
136
+ result.chomp.gsub(/\G[^:]+:\s*/, '')
137
+ else
138
+ nil
139
+ end
140
+ end
141
+
142
+ def smb_conf
143
+ %w(/etc/samba/smb.conf /usr/local/etc/samba/smb.conf).each do |guess|
144
+ return guess if File.exist?(guess)
145
+ end
146
+ nil
147
+ end
148
+
149
+ def samba_domain
150
+ _smb_conf = self["smb_conf"]
151
+ if _smb_conf
152
+ File.open(_smb_conf) do |f|
153
+ f.read.grep(/^\s*[^#;]/).each do |line|
154
+ if /^\s*workgroup\s*=\s*(\S+)\s*$/i =~ line
155
+ return $1.upcase
156
+ end
157
+ end
158
+ end
159
+ else
160
+ nil
161
+ end
162
+ end
163
+
164
+ def samba_netbios_name
165
+ netbios_name = nil
166
+ _smb_conf = self["smb_conf"]
167
+ if _smb_conf
168
+ File.open(_smb_conf) do |f|
169
+ f.read.grep(/^\s*[^#;]/).each do |line|
170
+ if /^\s*netbios\s*name\s*=\s*(.+)\s*$/i =~ line
171
+ netbios_name = $1
172
+ break
173
+ end
174
+ end
175
+ end
176
+ end
177
+ netbios_name ||= Socket.gethostname
178
+ netbios_name ? netbios_name.upcase : nil
179
+ end
180
+
181
+ def host
182
+ "localhost"
183
+ end
184
+
185
+ def port
186
+ 389
187
+ end
188
+
189
+ def allow_anonymous
190
+ false
191
+ end
192
+
193
+ def method
194
+ :plain
195
+ end
196
+
197
+ def users_suffix
198
+ retrieve_value_from_smb_conf(/ldap\s+user\s+suffix/i) || "ou=Users"
199
+ end
200
+
201
+ def groups_suffix
202
+ retrieve_value_from_smb_conf(/ldap\s+group\s+suffix/i) || "ou=Groups"
203
+ end
204
+
205
+ def computers_suffix
206
+ retrieve_value_from_smb_conf(/ldap\s+machine\s+suffix/i) ||
207
+ "ou=Computers"
208
+ end
209
+
210
+ def idmap_suffix
211
+ retrieve_value_from_smb_conf(/ldap\s+idmap\s+suffix/i) || "ou=Idmap"
212
+ end
213
+
214
+ def start_uid
215
+ 10000
216
+ end
217
+
218
+ def start_gid
219
+ 10000
220
+ end
221
+
222
+ def default_user_gid
223
+ rid = ActiveSambaLdap::SambaGroup::DOMAIN_USERS_RID
224
+ ActiveSambaLdap::SambaGroup.rid2gid(rid)
225
+ end
226
+
227
+ def default_computer_gid
228
+ rid = ActiveSambaLdap::SambaGroup::DOMAIN_COMPUTERS_RID
229
+ ActiveSambaLdap::SambaGroup.rid2gid(rid)
230
+ end
231
+
232
+ def skeleton_directory
233
+ "/etc/skel"
234
+ end
235
+
236
+ def user_home_unc
237
+ netbios_name = self["samba_netbios_name"]
238
+ netbios_name ? "\\\\#{netbios_name}\\%U" : nil
239
+ end
240
+
241
+ def user_profile
242
+ netbios_name = self["samba_netbios_name"]
243
+ netbios_name ? "\\\\#{netbios_name}\\profiles\\%U" : nil
244
+ end
245
+
246
+ def user_home_directory
247
+ "/home/%U"
248
+ end
249
+
250
+ def user_home_directory_mode
251
+ 0755
252
+ end
253
+
254
+ def normalize_user_home_directory_mode(mode)
255
+ if mode
256
+ Integer(mode)
257
+ else
258
+ nil
259
+ end
260
+ rescue ArgumentError
261
+ raise InvalidConfigurationValueError.new("user_home_directory",
262
+ mode, $!.message)
263
+ end
264
+
265
+ def user_login_shell
266
+ "/bin/false"
267
+ end
268
+
269
+ def user_home_drive
270
+ "H:"
271
+ end
272
+
273
+ def user_logon_script
274
+ "logon.bat"
275
+ end
276
+
277
+ def user_gecos
278
+ nil
279
+ end
280
+
281
+ def bind_dn
282
+ nil
283
+ end
284
+
285
+ def password_hash_type
286
+ :ssha
287
+ end
288
+
289
+ def normalize_password_hash_type(type)
290
+ type.to_s.downcase.to_sym
291
+ end
292
+
293
+ AVAILABLE_HASH_TYPES = [:crypt, :md5, :smd5, :sha, :ssha]
294
+ def validate_password_hash_type(type)
295
+ unless AVAILABLE_HASH_TYPES.include?(type)
296
+ types = AVAILABLE_HASH_TYPES.collect {|x| x.inspect}.join(", ")
297
+ raise InvalidConfigurationValueError.new("password_hash_type",
298
+ type,
299
+ "must be in #{types}")
300
+ end
301
+ end
302
+
303
+ private
304
+ def retrieve_value_from_smb_conf(key)
305
+ smb_conf = self['smb_conf']
306
+ if smb_conf and File.readable?(smb_conf)
307
+ line = File.read(smb_conf).grep(key).reject do |l|
308
+ /^\s*[#;]/ =~ l
309
+ end.first
310
+ if line
311
+ line.split(/=/, 2)[1].strip
312
+ else
313
+ nil
314
+ end
315
+ else
316
+ nil
317
+ end
318
+ end
319
+ end
320
+ end
321
+ end
322
+ end
@@ -0,0 +1,17 @@
1
+ module ActiveSambaLdap
2
+ class Dc < Base
3
+ include Reloadable::Subclasses
4
+
5
+ class << self
6
+ def ldap_mapping(options={})
7
+ default_options = {
8
+ :dn_attribute => "dc",
9
+ :prefix => "",
10
+ :classes => ["top", "dcObject", "organization"],
11
+ }
12
+ options = default_options.merge(options)
13
+ super(options)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,80 @@
1
+ module ActiveSambaLdap
2
+ module Entry
3
+ def self.included(base)
4
+ super
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ def create(attributes=nil)
10
+ pool = nil
11
+ number_key = nil
12
+ ensure_ou((attributes || {})[dn_attribute.to_sym])
13
+ entry = super do |entry|
14
+ options = attributes || {}
15
+ options, pool, number_key = prepare_create_options(entry, options)
16
+ entry.fill_default_values(options)
17
+ yield entry if block_given?
18
+ end
19
+ if entry.errors.empty? and pool
20
+ pool[number_key] = Integer(entry[number_key]).succ
21
+ unless pool.save
22
+ pool.each do |key, value|
23
+ entry.add("pool: #{key}", value)
24
+ end
25
+ end
26
+ end
27
+ entry
28
+ end
29
+
30
+ private
31
+ def ensure_ou(dn)
32
+ return if dn.nil?
33
+ dn_value, ou = dn.split(/,/, 2)
34
+ return if ou.nil?
35
+ prefixes = [prefix]
36
+ ou.split(/\s*,\s*/).reverse_each do |entry|
37
+ name, value = entry.split(/\s*=\s*/, 2).collect {|x| x.strip}
38
+ raise ArgumentError, "#{ou} must be only ou" if name != "ou"
39
+ ou_class = Class.new(ActiveSambaLdap::Ou)
40
+ ou_class.ldap_mapping :prefix => prefixes.join(',')
41
+ prefixes.unshift(entry)
42
+ next if ou_class.exists?(value)
43
+ ou = ou_class.new(value)
44
+ ou.save!
45
+ end
46
+ end
47
+
48
+ def prepare_create_options_for_number(key, entry, options)
49
+ options = {key => entry[key]}.merge(options)
50
+ number, pool = ensure_number(key, options)
51
+ [options.merge(key => number), pool, key]
52
+ end
53
+
54
+ def ensure_number(key, options)
55
+ number = options[key]
56
+ pool = nil
57
+ unless number
58
+ pool = ensure_pool(options)
59
+ number = pool.send("find_available_#{key}", self)
60
+ end
61
+ [number, pool]
62
+ end
63
+
64
+ def ensure_pool(options)
65
+ pool = options[:pool]
66
+ unless pool
67
+ pool_class = options[:pool_class]
68
+ unless pool_class
69
+ pool_class = Class.new(UnixIdPool)
70
+ pool_class.ldap_mapping
71
+ end
72
+ samba_domain = options[:samba_domain]
73
+ samba_domain ||= pool_class.configuration[:samba_domain]
74
+ pool = options[:pool] = pool_class.find(samba_domain)
75
+ end
76
+ pool
77
+ end
78
+ end
79
+ end
80
+ end