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