activesambaldap 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/NEWS.en +9 -0
- data/NEWS.ja +10 -0
- data/README.en +310 -0
- data/README.ja +307 -0
- data/Rakefile +95 -0
- data/bin/asl-groupadd +70 -0
- data/bin/asl-groupdel +58 -0
- data/bin/asl-groupmod +133 -0
- data/bin/asl-groupshow +31 -0
- data/bin/asl-passwd +99 -0
- data/bin/asl-populate +96 -0
- data/bin/asl-purge +24 -0
- data/bin/asl-samba-computeradd +94 -0
- data/bin/asl-samba-groupadd +55 -0
- data/bin/asl-samba-groupdel +53 -0
- data/bin/asl-samba-groupmod +98 -0
- data/bin/asl-samba-useradd +98 -0
- data/bin/asl-samba-userdel +47 -0
- data/bin/asl-samba-usermod +92 -0
- data/bin/asl-useradd +263 -0
- data/bin/asl-userdel +75 -0
- data/bin/asl-usermod +335 -0
- data/bin/asl-usershow +31 -0
- data/lib/active_samba_ldap/account.rb +199 -0
- data/lib/active_samba_ldap/base.rb +126 -0
- data/lib/active_samba_ldap/command.rb +94 -0
- data/lib/active_samba_ldap/computer.rb +13 -0
- data/lib/active_samba_ldap/computer_account.rb +34 -0
- data/lib/active_samba_ldap/configuration.rb +322 -0
- data/lib/active_samba_ldap/dc.rb +17 -0
- data/lib/active_samba_ldap/entry.rb +80 -0
- data/lib/active_samba_ldap/group.rb +182 -0
- data/lib/active_samba_ldap/idmap.rb +17 -0
- data/lib/active_samba_ldap/ou.rb +18 -0
- data/lib/active_samba_ldap/populate.rb +254 -0
- data/lib/active_samba_ldap/samba_account.rb +200 -0
- data/lib/active_samba_ldap/samba_computer.rb +20 -0
- data/lib/active_samba_ldap/samba_group.rb +126 -0
- data/lib/active_samba_ldap/samba_user.rb +39 -0
- data/lib/active_samba_ldap/unix_id_pool.rb +41 -0
- data/lib/active_samba_ldap/user.rb +14 -0
- data/lib/active_samba_ldap/user_account.rb +30 -0
- data/lib/active_samba_ldap/version.rb +3 -0
- data/lib/active_samba_ldap.rb +29 -0
- data/lib/samba/encrypt.rb +86 -0
- data/misc/rd2html.rb +42 -0
- data/rails/plugin/active_samba_ldap/README +30 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/scaffold_asl_generator.rb +28 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/computer.rb +3 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/dc.rb +3 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/group.rb +3 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/idmap.rb +3 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/ldap.yml +24 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/ou.rb +3 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_controller.rb +12 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_helper.rb +2 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_index.rhtml +17 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_populate.rhtml +15 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/samba_purge.rhtml +10 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/unix_id_pool.rb +3 -0
- data/rails/plugin/active_samba_ldap/generators/scaffold_asl/templates/user.rb +3 -0
- data/rails/plugin/active_samba_ldap/init.rb +6 -0
- data/test/asl-test-utils.rb +276 -0
- data/test/command.rb +64 -0
- data/test/config.yaml.sample +17 -0
- data/test/run-test.rb +18 -0
- data/test/test-unit-ext/always-show-result.rb +28 -0
- data/test/test-unit-ext/priority.rb +159 -0
- data/test/test-unit-ext.rb +2 -0
- data/test/test_asl_groupadd.rb +69 -0
- data/test/test_asl_groupdel.rb +88 -0
- data/test/test_asl_groupmod.rb +256 -0
- data/test/test_asl_groupshow.rb +21 -0
- data/test/test_asl_passwd.rb +125 -0
- data/test/test_asl_populate.rb +92 -0
- data/test/test_asl_purge.rb +21 -0
- data/test/test_asl_useradd.rb +710 -0
- data/test/test_asl_userdel.rb +73 -0
- data/test/test_asl_usermod.rb +541 -0
- data/test/test_asl_usershow.rb +27 -0
- data/test/test_group.rb +21 -0
- data/test/test_password.rb +51 -0
- data/test/test_samba_encrypt.rb +36 -0
- data/test/test_user_home_directory.rb +43 -0
- 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,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
|