activesambaldap 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,182 @@
1
+ require 'English'
2
+
3
+ require 'active_samba_ldap/entry'
4
+
5
+ module ActiveSambaLdap
6
+ class Group < Base
7
+ include Reloadable::Subclasses
8
+
9
+ include Entry
10
+
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
181
+ end
182
+ end
@@ -0,0 +1,17 @@
1
+ module ActiveSambaLdap
2
+ class Idmap < Base
3
+ include Reloadable::Subclasses
4
+
5
+ class << self
6
+ def ldap_mapping(options={})
7
+ default_options = {
8
+ :dn_attribute => "sambaSID",
9
+ :prefix => configuration[:idmap_suffix],
10
+ :classes => ["top", "sambaIdmapEntry"],
11
+ }
12
+ options = default_options.merge(options)
13
+ super options
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module ActiveSambaLdap
2
+ class Ou < Base
3
+ include Reloadable::Subclasses
4
+
5
+ class << self
6
+ def ldap_mapping(options={})
7
+ default_options = {
8
+ :dn_attribute => "ou",
9
+ :prefix => "",
10
+ :classes => ["top", "organizationalUnit"],
11
+ :scope => :sub,
12
+ }
13
+ options = default_options.merge(options)
14
+ super(options)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,254 @@
1
+ module ActiveSambaLdap
2
+ module Populate
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def populate(options={})
9
+ Private.new(self, options).populate
10
+ end
11
+
12
+ def purge(options={})
13
+ self.delete_all(nil, {:scope => :sub}.merge(options))
14
+ end
15
+
16
+ class Private
17
+ def initialize(base, options)
18
+ @base = base
19
+ @options = options.dup
20
+ end
21
+
22
+ def populate
23
+ init_classes
24
+ init_options
25
+
26
+ entries = []
27
+ entries.concat(ensure_base)
28
+ entries.concat(ensure_group_base)
29
+ entries.concat(ensure_user_base)
30
+ entries.concat(ensure_computer_base)
31
+ entries.concat(ensure_idmap_base)
32
+ entries.concat(make_groups)
33
+ entries.concat(make_users)
34
+ entries.concat(make_pool)
35
+
36
+ [entries, @options]
37
+ end
38
+
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)
43
+ @options[:idmap_class] = idmap_class = Class.new(Idmap)
44
+ @options[:unix_id_pool_class] = id_pool_class = Class.new(UnixIdPool)
45
+
46
+ user_class.ldap_mapping
47
+ group_class.ldap_mapping
48
+ computer_class.ldap_mapping
49
+ idmap_class.ldap_mapping
50
+ id_pool_class.ldap_mapping
51
+
52
+ user_class.set_associated_class(:primary_group, group_class)
53
+ computer_class.set_associated_class(:primary_group, group_class)
54
+ user_class.set_associated_class(:groups, group_class)
55
+ computer_class.set_associated_class(:groups, group_class)
56
+
57
+ group_class.set_associated_class(:users, user_class)
58
+ group_class.set_associated_class(:computers, computer_class)
59
+ group_class.set_associated_class(:primary_users, user_class)
60
+ group_class.set_associated_class(:primary_computers, computer_class)
61
+ end
62
+
63
+ def user_class
64
+ @options[:user_class]
65
+ end
66
+
67
+ def group_class
68
+ @options[:group_class]
69
+ end
70
+
71
+ def computer_class
72
+ @options[:computer_class]
73
+ end
74
+
75
+ def idmap_class
76
+ @options[:idmap_class]
77
+ end
78
+
79
+ def init_options
80
+ config = @base.configuration
81
+ @options[:start_uid] ||= Integer(config[:start_uid])
82
+ @options[:start_gid] ||= Integer(config[:start_gid])
83
+ @options[:administrator] ||= user_class::DOMAIN_ADMIN_NAME
84
+ @options[:administrator_uid] ||=
85
+ user_class.rid2uid(user_class::DOMAIN_ADMIN_RID)
86
+ @options[:administrator_gid] ||=
87
+ group_class.rid2gid(group_class::DOMAIN_ADMINS_RID)
88
+ @options[:guest] ||= user_class::DOMAIN_GUEST_NAME
89
+ @options[:guest_uid] ||=
90
+ user_class.rid2uid(user_class::DOMAIN_GUEST_RID)
91
+ @options[:guest_gid] ||=
92
+ group_class.rid2gid(group_class::DOMAIN_GUESTS_RID)
93
+ @options[:default_user_gid] ||= config[:default_user_gid]
94
+ @options[:default_computer_gid] ||= config[:default_computer_gid]
95
+ end
96
+
97
+ def ensure_container_base(dn, target_name, klass, ignore_base=false)
98
+ entries = []
99
+ suffixes = []
100
+ dn.split(/,/).reverse_each do |suffix|
101
+ name, value = suffix.split(/=/, 2)
102
+ next unless name == target_name
103
+ container_class = Class.new(klass)
104
+ prefix = suffixes.reverse.join(",")
105
+ suffixes << suffix
106
+ if ignore_base
107
+ container_class.ldap_mapping :prefix => "", :scope => :base
108
+ container_class.base = prefix
109
+ else
110
+ container_class.ldap_mapping :prefix => prefix, :scope => :base
111
+ end
112
+ next if container_class.exists?(value, :prefix => suffix)
113
+ container = container_class.new(value)
114
+ yield(container) if block_given?
115
+ container.save!
116
+ entries << container
117
+ end
118
+ entries
119
+ end
120
+
121
+ def ensure_base
122
+ ensure_container_base(@base.base, "dc", Dc, true) do |dc|
123
+ dc.o = dc.dc
124
+ end
125
+ end
126
+
127
+ def ensure_ou_base(dn)
128
+ ensure_container_base(dn, "ou", Ou)
129
+ end
130
+
131
+ def ensure_user_base
132
+ ensure_ou_base(user_class.prefix)
133
+ end
134
+
135
+ def ensure_group_base
136
+ ensure_ou_base(group_class.prefix)
137
+ end
138
+
139
+ def ensure_computer_base
140
+ ensure_ou_base(computer_class.prefix)
141
+ end
142
+
143
+ def ensure_idmap_base
144
+ ensure_ou_base(idmap_class.prefix)
145
+ end
146
+
147
+ def make_user(user_class, name, uid, group)
148
+ if user_class.exists?(name)
149
+ user = user_class.find(name)
150
+ group = nil
151
+ else
152
+ user = user_class.new(name)
153
+ user.fill_default_values(:uid_number => uid, :group => group)
154
+ user.save!
155
+ group.users << user
156
+ end
157
+ [user, group]
158
+ end
159
+
160
+ def make_users
161
+ user_class = @options[:user_class]
162
+ group_class = @options[:group_class]
163
+ entries = []
164
+ [
165
+ [@options[:administrator], @options[:administrator_uid],
166
+ @options[:administrator_gid]],
167
+ [@options[:guest], @options[:guest_uid], @options[:guest_gid]],
168
+ ].each do |name, uid, gid|
169
+ user, group = make_user(user_class, name, uid,
170
+ group_class.find_by_gid_number(gid))
171
+ entries << user
172
+ if group
173
+ old_group = entries.find do |entry|
174
+ entry.is_a?(group_class) and entry.cn == group.cn
175
+ end
176
+ index = entries.index(old_group)
177
+ if index
178
+ entries[index] = group
179
+ else
180
+ entries << group
181
+ end
182
+ end
183
+ end
184
+ entries
185
+ end
186
+
187
+ def make_group(group_class, name, gid, description=nil, type=nil)
188
+ if group_class.exists?(name)
189
+ group = group_class.find(name)
190
+ else
191
+ group = group_class.new(name)
192
+ group.change_type(type || "domain")
193
+ group.display_name = name
194
+ group.description = name || description
195
+ group.change_gid_number(gid)
196
+
197
+ group.save!
198
+ end
199
+ group
200
+ end
201
+
202
+ def make_groups
203
+ entries = []
204
+ [
205
+ ["Domain Admins", @options[:administrator_gid],
206
+ "Netbios Domain Administrators"],
207
+ ["Domain Users", @options[:default_user_gid],
208
+ "Netbios Domain Users"],
209
+ ["Domain Guests", @options[:guest_gid],
210
+ "Netbios Domain Guest Users"],
211
+ ["Domain Computers", @options[:default_computer_gid],
212
+ "Netbios Domain Computers"],
213
+ ["Administrators", nil, nil, "builtin",
214
+ group_class::LOCAL_ADMINS_RID],
215
+ ["Users", nil, nil, "builtin", group_class::LOCAL_USERS_RID],
216
+ ["Guests", nil, nil, "builtin", group_class::LOCAL_GUESTS_RID],
217
+ ["Power Users", nil, nil, "builtin",
218
+ group_class::LOCAL_POWER_USERS_RID],
219
+ ["Account Operators", nil, nil, "builtin",
220
+ group_class::LOCAL_ACCOUNT_OPERATORS_RID],
221
+ ["System Operators", nil, nil, "builtin",
222
+ group_class::LOCAL_SYSTEM_OPERATORS_RID],
223
+ ["Print Operators", nil, nil, "builtin",
224
+ group_class::LOCAL_PRINT_OPERATORS_RID],
225
+ ["Backup Operators", nil, nil, "builtin",
226
+ group_class::LOCAL_BACKUP_OPERATORS_RID],
227
+ ["Replicators", nil, nil, "builtin",
228
+ group_class::LOCAL_REPLICATORS_RID],
229
+ ].each do |name, gid, description, type, rid|
230
+ gid ||= group_class.rid2gid(rid)
231
+ entries << make_group(group_class, name, gid, description, type)
232
+ end
233
+ entries
234
+ end
235
+
236
+ def make_pool
237
+ config = @base.configuration
238
+ klass = @options[:unix_id_pool_class]
239
+ name = config[:samba_domain]
240
+ if klass.exists?(name)
241
+ pool = klass.find(name)
242
+ else
243
+ pool = klass.new(name)
244
+ pool.samba_sid = config[:sid]
245
+ pool.uid_number = @options[:start_uid]
246
+ pool.gid_number = @options[:start_gid]
247
+ pool.save!
248
+ end
249
+ [pool]
250
+ end
251
+ end
252
+ end
253
+ end
254
+ end
@@ -0,0 +1,200 @@
1
+ module ActiveSambaLdap
2
+ module SambaAccount
3
+ def self.included(base)
4
+ super
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ # from source/include/rpc_misc.c in Samba
9
+ DOMAIN_ADMIN_RID = 0x000001F4
10
+ DOMAIN_GUEST_RID = 0x000001F5
11
+
12
+ # from source/rpc_server/srv_util.c in Samba
13
+ DOMAIN_ADMIN_NAME = "Administrator"
14
+ DOMAIN_GUEST_NAME = "Guest"
15
+
16
+ WELL_KNOWN_RIDS = []
17
+ WELL_KNOWN_NAMES = []
18
+ constants.each do |name|
19
+ case name
20
+ when /_RID$/
21
+ WELL_KNOWN_RIDS << const_get(name)
22
+ when /_NAME$/
23
+ WELL_KNOWN_NAMES << const_get(name)
24
+ end
25
+ end
26
+
27
+ FAR_FUTURE_TIME = Time.parse("2050/01/01").to_i.to_s
28
+ ACCOUNT_FLAGS_RE = /\A\[([NDHTUMWSLXI ]+)\]\z/
29
+
30
+ module ClassMethods
31
+ def uid2rid(uid)
32
+ uid = Integer(uid)
33
+ if WELL_KNOWN_RIDS.include?(uid)
34
+ uid
35
+ else
36
+ 2 * uid + 1000
37
+ end
38
+ end
39
+
40
+ def rid2uid(rid)
41
+ rid = Integer(rid)
42
+ if WELL_KNOWN_RIDS.include?(rid)
43
+ rid
44
+ else
45
+ (Integer(rid) - 1000) / 2
46
+ end
47
+ end
48
+
49
+ def start_rid
50
+ uid2rid(start_uid)
51
+ end
52
+
53
+ private
54
+ def default_classes
55
+ super + ["sambaSamAccount"]
56
+ end
57
+
58
+ def primary_group_options(options)
59
+ super.merge(:extend => PrimaryGroupProxy)
60
+ end
61
+
62
+ module PrimaryGroupProxy
63
+ def replace(entry)
64
+ super
65
+ if @target
66
+ if @target.samba_sid.to_s.empty?
67
+ raise GroupDoesNotHaveSambaSID.new(@target.gid_number)
68
+ end
69
+ @owner.samba_primary_group_sid = @target.samba_sid
70
+ else
71
+ @owner.samba_primary_group_sid = nil
72
+ end
73
+ entry
74
+ end
75
+ end
76
+ end
77
+
78
+ def fill_default_values(options={})
79
+ super
80
+
81
+ self.samba_logon_time ||= "0"
82
+ self.samba_logoff_time ||= FAR_FUTURE_TIME
83
+ self.samba_kickoff_time ||= nil
84
+
85
+ password = options[:password]
86
+ change_samba_password(password) if password
87
+ self.samba_lm_password ||= "XXX"
88
+ self.samba_nt_password ||= "XXX"
89
+ self.samba_pwd_last_set ||= "0"
90
+
91
+ account_flags_is_not_set = samba_acct_flags.nil?
92
+ self.samba_acct_flags ||= default_account_flags
93
+
94
+ can_change_password = options[:can_change_password]
95
+ if can_change_password
96
+ self.enable_password_change
97
+ elsif account_flags_is_not_set or can_change_password == false
98
+ self.disable_password_change
99
+ end
100
+
101
+ must_change_password = options[:must_change_password]
102
+ if must_change_password
103
+ self.enable_forcing_password_change
104
+ elsif account_flags_is_not_set or must_change_password == false
105
+ self.disable_forcing_password_change
106
+ end
107
+
108
+ enable_account = options[:enable]
109
+ if enable_account
110
+ self.enable
111
+ elsif account_flags_is_not_set or enable_account == false
112
+ self.disable
113
+ end
114
+
115
+ self
116
+ end
117
+
118
+ def change_uid_number(uid, allow_non_unique=false)
119
+ super
120
+ rid = self.class.uid2rid(uid_number.to_s)
121
+ change_sid(rid, allow_non_unique)
122
+ end
123
+
124
+ def change_uid_number_by_rid(rid, allow_non_unique=false)
125
+ change_uid_number(self.class.rid2uid(rid), allow_non_unique)
126
+ end
127
+
128
+ def change_sid(rid, allow_non_unique=false)
129
+ sid = "#{self.class.configuration[:sid]}-#{rid}"
130
+ # check_unique_sid_number(sid) unless allow_non_unique
131
+ self.samba_sid = sid
132
+ end
133
+
134
+ def rid
135
+ Integer(samba_sid.split(/-/).last)
136
+ end
137
+
138
+ def change_samba_password(password)
139
+ self.samba_lm_password = Samba::Encrypt.lm_hash(password)
140
+ self.samba_nt_password = Samba::Encrypt.ntlm_hash(password)
141
+ self.samba_pwd_last_set = Time.now.to_i.to_s
142
+ end
143
+
144
+ def enable_password_change
145
+ self.samba_pwd_can_change = "0"
146
+ end
147
+
148
+ def disable_password_change
149
+ self.samba_pwd_can_change = FAR_FUTURE_TIME
150
+ end
151
+
152
+ def can_change_password?
153
+ samba_pwd_can_change.nil? or
154
+ Time.at(samba_pwd_can_change.to_i) <= Time.now
155
+ end
156
+
157
+ def enable_forcing_password_change
158
+ self.samba_pwd_must_change = "0"
159
+ if /X/ =~ samba_acct_flags.to_s
160
+ self.samba_acct_flags = samba_acct_flags.sub(/X/, '')
161
+ end
162
+ if samba_pwd_last_set.to_i.zero?
163
+ self.samba_pwd_last_set = FAR_FUTURE_TIME
164
+ end
165
+ end
166
+
167
+ def disable_forcing_password_change
168
+ self.samba_pwd_must_change = FAR_FUTURE_TIME
169
+ end
170
+
171
+ def must_change_password?
172
+ !(/X/ =~ samba_acct_flags.to_s or
173
+ samba_pwd_must_change.nil? or
174
+ Time.at(samba_pwd_must_change.to_i) > Time.now)
175
+ end
176
+
177
+ def enable
178
+ if /D/ =~ samba_acct_flags.to_s
179
+ self.samba_acct_flags = samba_acct_flags.gsub(/D/, '')
180
+ end
181
+ end
182
+
183
+ def disable
184
+ flags = ""
185
+ if ACCOUNT_FLAGS_RE =~ samba_acct_flags.to_s
186
+ flags = $1
187
+ return if /D/ =~ flags
188
+ end
189
+ self.samba_acct_flags = "[D#{flags}]"
190
+ end
191
+
192
+ def enabled?
193
+ !disabled?
194
+ end
195
+
196
+ def disabled?
197
+ (/D/ =~ samba_acct_flags.to_s) ? true : false
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,20 @@
1
+ require 'active_samba_ldap/account'
2
+ require 'active_samba_ldap/user_account'
3
+ require 'active_samba_ldap/samba_account'
4
+
5
+ module ActiveSambaLdap
6
+ class SambaComputer < Base
7
+ include Reloadable::Subclasses
8
+
9
+ include Entry
10
+
11
+ include Account
12
+ include ComputerAccount
13
+ include SambaAccount
14
+
15
+ private
16
+ def default_account_flags
17
+ "[W]"
18
+ end
19
+ end
20
+ end