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.
- 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
|