[asl-commit] ActiveSambaLdap r1:
null at cozmixng.org
null at cozmixng.org
Fri Aug 3 22:30:38 EDT 2007
retro 2007-08-04 11:30:36 +0900 (Sat, 04 Aug 2007)
New Revision: 1
Added directories:
activesambaldap/
activesambaldap/branches/
activesambaldap/tags/
activesambaldap/trunk/
activesambaldap/trunk/bin/
activesambaldap/trunk/lib/
activesambaldap/trunk/lib/active_samba_ldap/
activesambaldap/trunk/lib/samba/
activesambaldap/trunk/test/
branchs/
tags/
trunk/
trunk/lib/
trunk/lib/webrick/
trunk/lib/webrick/httpservlet/
trunk/lib/webrick/httpstatus/
trunk/sample/
trunk/test/
Added files:
activesambaldap/trunk/README
activesambaldap/trunk/Rakefile
activesambaldap/trunk/bin/asl-groupadd
activesambaldap/trunk/bin/asl-groupdel
activesambaldap/trunk/bin/asl-groupmod
activesambaldap/trunk/bin/asl-groupshow
activesambaldap/trunk/bin/asl-passwd
activesambaldap/trunk/bin/asl-populate
activesambaldap/trunk/bin/asl-useradd
activesambaldap/trunk/bin/asl-userdel
activesambaldap/trunk/bin/asl-usermod
activesambaldap/trunk/bin/asl-usershow
activesambaldap/trunk/lib/active_samba_ldap.rb
activesambaldap/trunk/lib/active_samba_ldap/account.rb
activesambaldap/trunk/lib/active_samba_ldap/base.rb
activesambaldap/trunk/lib/active_samba_ldap/command.rb
activesambaldap/trunk/lib/active_samba_ldap/computer.rb
activesambaldap/trunk/lib/active_samba_ldap/dc.rb
activesambaldap/trunk/lib/active_samba_ldap/default_config.rb
activesambaldap/trunk/lib/active_samba_ldap/group.rb
activesambaldap/trunk/lib/active_samba_ldap/idmap.rb
activesambaldap/trunk/lib/active_samba_ldap/ou.rb
activesambaldap/trunk/lib/active_samba_ldap/populate.rb
activesambaldap/trunk/lib/active_samba_ldap/unix_id_pool.rb
activesambaldap/trunk/lib/active_samba_ldap/user.rb
activesambaldap/trunk/lib/active_samba_ldap/user_password.rb
activesambaldap/trunk/lib/active_samba_ldap/version.rb
activesambaldap/trunk/lib/samba/encrypt.rb
activesambaldap/trunk/test/asl_test_utils.rb
activesambaldap/trunk/test/command.rb
activesambaldap/trunk/test/command_support.rb
activesambaldap/trunk/test/run-test.rb
activesambaldap/trunk/test/test_asl_groupadd.rb
activesambaldap/trunk/test/test_asl_groupdel.rb
activesambaldap/trunk/test/test_asl_groupmod.rb
activesambaldap/trunk/test/test_asl_groupshow.rb
activesambaldap/trunk/test/test_asl_passwd.rb
activesambaldap/trunk/test/test_asl_populate.rb
activesambaldap/trunk/test/test_asl_useradd.rb
activesambaldap/trunk/test/test_asl_userdel.rb
activesambaldap/trunk/test/test_asl_usermod.rb
activesambaldap/trunk/test/test_asl_usershow.rb
activesambaldap/trunk/test/test_samba_encrypt.rb
activesambaldap/trunk/test/test_user_password.rb
svn-commit.tmp
trunk/lib/webrick/httpservlet/svnhandler.rb
trunk/lib/webrick/httpstatus/webdav.rb
trunk/sample/svnserver.rb
trunk/test/run-test.rb
trunk/test/test_propfind.rb
Log:
Added: activesambaldap/
Added: activesambaldap/branches/
Added: activesambaldap/tags/
Added: activesambaldap/trunk/
Added: activesambaldap/trunk/bin/
Added: activesambaldap/trunk/lib/
Added: activesambaldap/trunk/lib/active_samba_ldap/
Added: activesambaldap/trunk/lib/samba/
Added: activesambaldap/trunk/test/
Added: branchs/
Added: tags/
Added: trunk/
Added: trunk/lib/
Added: trunk/lib/webrick/
Added: trunk/lib/webrick/httpservlet/
Added: trunk/lib/webrick/httpstatus/
Added: trunk/sample/
Added: trunk/test/
Added: activesambaldap/trunk/test/test_asl_usermod.rb (+550 -0)
===================================================================
--- activesambaldap/trunk/test/test_asl_usermod.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_asl_usermod.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,550 @@
+require 'test/unit'
+require 'command_support'
+require 'asl_test_utils'
+require 'fileutils'
+require 'time'
+
+require 'active_samba_ldap'
+
+class AslUserModTest < Test::Unit::TestCase
+ include CommandSupport
+ include AslTestUtils
+
+ def setup
+ super
+ @asl_usermod = File.join(@bin_dir, "asl-usermod")
+ end
+
+ def test_not_exist_user
+ assert_equal([false, "user 'not-exist' doesn't exist.\n"],
+ run_asl_usermod("not-exist"))
+ end
+
+ def test_gecos
+ make_dummy_user do |user, password|
+ old_gecos = user.gecos(true)
+ new_gecos = "New gecos"
+ assert_not_equal(old_gecos, new_gecos)
+ args = ["--gecos", new_gecos]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_gecos, new_user.gecos(true))
+ assert_equal(new_gecos, new_user.description(true))
+ assert_equal(new_gecos, new_user.displayName(true))
+ end
+ end
+
+ def test_home_directory
+ make_dummy_user do |user, password|
+ old_home_directory = user.homeDirectory(true)
+ new_home_directory = "#{old_home_directory}.new"
+ args = ["--home-directory", new_home_directory]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_home_directory, new_user.homeDirectory(true))
+ end
+ end
+
+ def test_move_home_directory
+ make_dummy_user do |user, password|
+ begin
+ old_home_directory = user.homeDirectory(true)
+ new_home_directory = "#{old_home_directory}.new"
+ assert(!File.exist?(new_home_directory))
+ args = ["--home-directory", new_home_directory, "--move-home-directory"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_home_directory, new_user.homeDirectory(true))
+ assert(File.exist?(new_home_directory))
+ ensure
+ FileUtils.rm_rf(new_home_directory)
+ end
+ end
+ end
+
+ def test_rename
+ make_dummy_user do |user, password|
+ begin
+ old_uid = user.uid(true)
+ new_uid = "#{old_uid}-new"
+
+ new_user = @user_class.new(new_uid)
+ assert(!new_user.exists?)
+
+ args = ["--rename", new_uid]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ old_user = @user_class.new(old_uid)
+ assert(!old_user.exists?)
+ new_user = @user_class.new(new_uid)
+ assert(new_user.exists?)
+
+ assert_equal(new_uid, new_user.uid(true))
+ assert_equal(new_uid, new_user.cn(true))
+ ensure
+ new_user = @user_class.new(new_uid)
+ begin
+ new_user.destroy
+ rescue ActiveLDAP::DeleteError
+ end
+ end
+ end
+ end
+
+ def test_uid_number
+ make_dummy_user do |user, password|
+ old_uid_number = user.uidNumber(true)
+ old_samba_sid = user.sambaSID(true)
+ new_uid_number = old_uid_number.succ
+
+ old_rid = (2 * Integer(old_uid_number) + 1000).to_s
+ new_rid = (2 * Integer(new_uid_number) + 1000).to_s
+ new_samba_sid = old_samba_sid.sub(/#{Regexp.escape(old_rid)}$/, new_rid)
+
+ args = ["--uid", new_uid_number]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_uid_number, new_user.uidNumber(true))
+ assert_equal(new_samba_sid, new_user.sambaSID(true))
+ end
+ end
+
+ def test_uid_number_non_unique
+ make_dummy_user do |user, password|
+ old_uid_number = user.uidNumber(true)
+ new_uid_number = old_uid_number.succ
+ make_dummy_user(:name => "#{user.uid}2",
+ :uid_number => new_uid_number) do |user2, password2|
+ old_samba_sid = user.sambaSID(true)
+ old_rid = (2 * Integer(old_uid_number) + 1000).to_s
+ new_rid = (2 * Integer(new_uid_number) + 1000).to_s
+ new_samba_sid = old_samba_sid.sub(/#{Regexp.escape(old_rid)}$/, new_rid)
+
+ message = "uid number '#{new_uid_number}' already exists\n"
+ args = ["--uid", new_uid_number]
+ assert_asl_usermod_failed(user.uid, password, message, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(old_uid_number, new_user.uidNumber(true))
+ assert_equal(old_samba_sid, new_user.sambaSID(true))
+ end
+ end
+ end
+
+ def test_uid_number_allow_non_unique
+ make_dummy_user do |user, password|
+ old_uid_number = user.uidNumber(true)
+ new_uid_number = old_uid_number.succ
+ make_dummy_user(:name => "#{user.uid}2",
+ :uid_number => new_uid_number) do |user2, password2|
+ old_samba_sid = user.sambaSID(true)
+ old_rid = (2 * Integer(old_uid_number) + 1000).to_s
+ new_rid = (2 * Integer(new_uid_number) + 1000).to_s
+ new_samba_sid = old_samba_sid.sub(/#{Regexp.escape(old_rid)}$/, new_rid)
+
+ args = ["--uid", new_uid_number, "--allow-non-unique-uid"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_uid_number, new_user.uidNumber(true))
+ assert_equal(new_samba_sid, new_user.sambaSID(true))
+ end
+ end
+ end
+
+ def test_gid_number
+ make_dummy_group do |group|
+ make_dummy_user(:gid_number => group.gidNumber(true)) do |user, password|
+ make_dummy_group do |new_group|
+ args = ["--gid", new_group.gidNumber(true)]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_group.gidNumber(true), new_user.gidNumber(true))
+ assert_equal(new_group.sambaSID(true),
+ new_user.sambaPrimaryGroupSID(true))
+ end
+ end
+ end
+ end
+
+ def test_gid_number_not_exist
+ make_dummy_user do |user, password|
+ make_dummy_group do |group|
+ old_gid_number = user.gidNumber(true)
+ new_gid_number = group.gidNumber(true)
+ old_samba_primary_group_sid = user.sambaPrimaryGroupSID(true)
+
+ group.destroy
+ args = ["--gid", new_gid_number]
+ message = "gid number '#{new_gid_number}' doesn't exist\n"
+ assert_asl_usermod_failed(user.uid, password, message, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(old_gid_number, new_user.gidNumber(true))
+ assert_equal(old_samba_primary_group_sid,
+ new_user.sambaPrimaryGroupSID(true))
+ end
+ end
+ end
+
+ def test_groups
+ make_dummy_group do |group1|
+ make_dummy_group do |group2|
+ make_dummy_group do |group3|
+ new_gid_number1 = group1.gidNumber(true)
+ new_gid_number2 = group2.gidNumber(true)
+ new_gid_number3 = group3.gidNumber(true)
+ new_gid_numbers = [new_gid_number1, new_gid_number2, new_gid_number3]
+
+ make_dummy_user do |user, password|
+ old_gid_number = user.gidNumber(true)
+ old_groups = @group_class.find_all(:attribute => "memberUid",
+ :value => user.uid)
+
+ args = ["--groups", new_gid_numbers.join(",")]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+
+ new_user = @user_class.new(user.uid)
+ new_groups = @group_class.find_all(:attribute => "memberUid",
+ :value => new_user.uid)
+ assert_equal([group1.cn(true),
+ group2.cn(true),
+ group3.cn(true)].sort,
+ (new_groups - old_groups).sort)
+ end
+ end
+ end
+ end
+ end
+
+ def test_groups_no_merge
+ make_dummy_group do |group1|
+ make_dummy_group do |group2|
+ make_dummy_group do |group3|
+ new_gid_number1 = group1.gidNumber(true)
+ new_gid_number2 = group2.gidNumber(true)
+ new_gid_number3 = group3.gidNumber(true)
+ new_gid_numbers = [new_gid_number1, new_gid_number2, new_gid_number3]
+ make_dummy_user do |user, password|
+ old_gid_number = user.gidNumber(true)
+ old_groups = @group_class.find_all(:attribute => "memberUid",
+ :value => user.uid)
+
+ args = ["--groups", new_gid_numbers[0]]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ new_groups = @group_class.find_all(:attribute => "memberUid",
+ :value => new_user.uid)
+ assert_equal([group1.cn(true)].sort,
+ (new_groups - old_groups).sort)
+
+
+ args = ["--groups", new_gid_numbers[1..-1].join(","),
+ "--no-merge-groups"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ new_groups = @group_class.find_all(:attribute => "memberUid",
+ :value => new_user.uid)
+ assert_equal([group2.cn(true), group3.cn(true)].sort,
+ new_groups.sort)
+ end
+ end
+ end
+ end
+ end
+
+ def test_groups_not_exist
+ make_dummy_group do |group1|
+ make_dummy_group do |group2|
+ new_gid_number1 = group1.gidNumber(true)
+ new_gid_number2 = group2.gidNumber(true)
+ new_gid_numbers = [new_gid_number1, new_gid_number2]
+
+ group1.destroy
+ group2.destroy
+
+ make_dummy_user do |user, password|
+ old_gid_number = user.gidNumber(true)
+
+ assert(!group1.exists?)
+
+ old_groups = @group_class.find_all(:attribute => "memberUid",
+ :value => user.uid)
+
+ args = ["--groups", new_gid_numbers.join(",")]
+ message = "gid number '#{new_gid_numbers[0]}' doesn't exist\n"
+ assert_asl_usermod_failed(user.uid, password, message, *args)
+
+ new_user = @user_class.new(user.uid)
+ new_groups = @group_class.find_all(:attribute => "memberUid",
+ :value => new_user.uid)
+ assert_equal(old_groups.sort, new_groups.sort)
+ end
+ end
+ end
+ end
+
+ def test_shell
+ make_dummy_user do |user, password|
+ old_shell = user.loginShell(true)
+ new_shell = "/bin/zsh"
+
+ assert_not_equal(old_shell, new_shell)
+
+ args = ["--shell", new_shell]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_shell, new_user.loginShell(true))
+ end
+ end
+
+ def test_canonical_name
+ make_dummy_user do |user, password|
+ old_cn = user.cn(true)
+ new_cn = "new-#{new_cn}"
+
+ args = ["--canonical-name", new_cn]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_cn, new_user.cn(true))
+ end
+ end
+
+ def test_surname
+ make_dummy_user do |user, password|
+ old_sn = user.sn(true)
+ new_sn = "new-#{old_sn}"
+
+ args = ["--surname", new_sn]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_sn, new_user.sn(true))
+ end
+ end
+
+ def test_given_name
+ make_dummy_user do |user, password|
+ old_given_name = user.givenName(true)
+ new_given_name = "new-#{old_given_name}"
+
+ args = ["--given-name", new_given_name]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_given_name, new_user.givenName(true))
+ end
+ end
+
+ def test_expire_date
+ make_dummy_user do |user, password|
+ old_expire_date = user.sambaKickoffTime(true)
+ new_expire_date = Time.now + 60 * 24
+
+ unless old_expire_date.nil?
+ assert_not_equal(Time.at(old_expire_date.to_i), new_expire_date)
+ end
+
+ args = ["--expire-date", new_expire_date.iso8601]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_expire_date.to_i.to_s, new_user.sambaKickoffTime(true))
+ end
+ end
+
+ def test_can_change_password
+ make_dummy_user do |user, password|
+ unless user.can_change_password?
+ args = ["--can-change-password"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(new_user.can_change_password?)
+ end
+
+ args = ["--no-can-change-password"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(!new_user.can_change_password?)
+
+ args = ["--can-change-password"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(new_user.can_change_password?)
+ end
+ end
+
+ def test_must_change_password
+ make_dummy_user do |user, password|
+ unless user.must_change_password?
+ args = ["--must-change-password"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(new_user.must_change_password?)
+ end
+
+ args = ["--no-must-change-password"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(!new_user.must_change_password?)
+
+ args = ["--must-change-password"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(new_user.must_change_password?)
+ end
+ end
+
+ def test_samba_home_path
+ make_dummy_user do |user, password|
+ old_samba_home_path = user.sambaHomePath(true)
+ new_samba_home_path = "//PDC/NEW-HOME"
+
+ assert_not_equal(old_samba_home_path, new_samba_home_path)
+
+ args = ["--samba-home-path", new_samba_home_path]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_samba_home_path, new_user.sambaHomePath(true))
+ end
+ end
+
+ def test_samba_home_drive
+ make_dummy_user do |user, password|
+ old_samba_home_drive = user.sambaHomeDrive(true)
+ new_samba_home_drive = "X:"
+
+ assert_not_equal(old_samba_home_drive, new_samba_home_drive)
+
+ args = ["--samba-home-drive", new_samba_home_drive]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_samba_home_drive, new_user.sambaHomeDrive(true))
+ end
+ end
+
+ def test_samba_logon_script
+ make_dummy_user do |user, password|
+ old_samba_logon_script = user.sambaLogonScript(true)
+ new_samba_logon_script = "\\\\PDC\\scripts\\logon-new.bat"
+
+ assert_not_equal(old_samba_logon_script, new_samba_logon_script)
+
+ args = ["--samba-logon-script", new_samba_logon_script]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_samba_logon_script, new_user.sambaLogonScript(true))
+ end
+ end
+
+ def test_samba_profile_path
+ make_dummy_user do |user, password|
+ old_samba_profile_path = user.sambaProfilePath(true)
+ new_samba_profile_path = "\\\\PDC\\profiles\\new-profile"
+
+ assert_not_equal(old_samba_profile_path, new_samba_profile_path)
+
+ args = ["--samba-profile-path", new_samba_profile_path]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_samba_profile_path, new_user.sambaProfilePath(true))
+ end
+ end
+
+ def test_samba_account_flags
+ make_dummy_user do |user, password|
+ old_samba_account_flags = user.sambaAcctFlags(true)
+ new_samba_account_flags = "[UX]"
+
+ assert_not_equal(old_samba_account_flags, new_samba_account_flags)
+
+ args = ["--samba-account-flags", new_samba_account_flags]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+
+ new_user = @user_class.new(user.uid)
+ assert_equal(new_samba_account_flags, new_user.sambaAcctFlags(true))
+ end
+ end
+
+ def test_enable
+ make_dummy_user do |user, password|
+ unless user.enabled?
+ args = ["--enable-user"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(new_user.enabled?)
+ assert(!new_user.disabled?)
+ end
+
+ args = ["--no-enable-user"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(!new_user.enabled?)
+ assert(new_user.disabled?)
+
+ args = ["--enable-user"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(new_user.enabled?)
+ assert(!new_user.disabled?)
+ end
+ end
+
+ def test_disable
+ make_dummy_user do |user, password|
+ unless user.disabled?
+ args = ["--disable-user"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(!new_user.enabled?)
+ assert(new_user.disabled?)
+ end
+
+ args = ["--no-disable-user"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(new_user.enabled?)
+ assert(!new_user.disabled?)
+
+ args = ["--disable-user"]
+ assert_asl_usermod_successfully(user.uid, password, *args)
+ new_user = @user_class.new(user.uid)
+ assert(!new_user.enabled?)
+ assert(new_user.disabled?)
+ end
+ end
+
+ private
+ def run_asl_usermod(*other_args, &block)
+ run_ruby(*[@asl_usermod, *other_args], &block)
+ end
+
+ def assert_asl_usermod_successfully(name, password, *args)
+ args << name
+ assert_equal([true, "Enter your password: \n"],
+ run_asl_usermod(*args) do |input, output|
+ output.puts password
+ output.puts password
+ end)
+ end
+
+ def assert_asl_usermod_failed(name, password, message, *args)
+ args << name
+ assert_equal([false, "Enter your password: \n#{message}"],
+ run_asl_usermod(*args) do |input, output|
+ output.puts password
+ output.puts password
+ end)
+ end
+end
Added: activesambaldap/trunk/lib/active_samba_ldap.rb (+37 -0)
===================================================================
--- activesambaldap/trunk/lib/active_samba_ldap.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/lib/active_samba_ldap.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,37 @@
+def require_gem_if_need(name, gem_name=nil, *options)
+ begin
+ require name
+ rescue LoadError
+ require 'rubygems'
+ gem_name ||= name
+ require_gem gem_name, *options
+ end
+end
+
+require_gem_if_need("active_record", "activerecord")
+
+require 'active_samba_ldap/version'
+begin
+ require "active_samba_ldap/config"
+rescue LoadError
+ require "active_samba_ldap/default_config"
+ module ActiveSambaLdap
+ class Config < DefaultConfig
+ end
+ end
+end
+
+require 'active_samba_ldap/base'
+require 'active_samba_ldap/populate'
+
+ActiveSambaLdap::Base.class_eval do
+ include ActiveSambaLdap::Populate
+end
+
+require 'active_samba_ldap/user'
+require 'active_samba_ldap/group'
+require 'active_samba_ldap/computer'
+require 'active_samba_ldap/idmap'
+require 'active_samba_ldap/unix_id_pool'
+require 'active_samba_ldap/ou'
+require 'active_samba_ldap/dc'
Added: activesambaldap/trunk/lib/active_samba_ldap/user_password.rb (+50 -0)
===================================================================
--- activesambaldap/trunk/lib/active_samba_ldap/user_password.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/lib/active_samba_ldap/user_password.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,50 @@
+require 'base64'
+require 'md5'
+require 'sha1'
+
+module ActiveSambaLdap
+ class UserPassword
+ class << self
+ def crypt(password, salt=nil)
+ salt ||= "$1$#{make_salt(8)}"
+ "{CRYPT}#{password.crypt(salt)}"
+ end
+
+ def md5(password)
+ "{MD5}#{Base64.encode64(MD5.md5(password).digest).chomp}"
+ end
+
+ def smd5(password, salt=nil)
+ if salt and salt.size != 4
+ raise ArgumentError.new("salt size must be == 4")
+ end
+ salt ||= make_salt(4)
+ md5_hash_with_salt = "#{MD5.md5(password + salt).digest}#{salt}"
+ "{SMD5}#{Base64.encode64(md5_hash_with_salt).chomp}"
+ end
+
+ def sha(password)
+ "{SHA}#{Base64.encode64(SHA1.sha1(password).digest).chomp}"
+ end
+
+ def ssha(password, salt=nil)
+ if salt and salt.size != 4
+ raise ArgumentError.new("salt size must be == 4")
+ end
+ salt ||= make_salt(4)
+ sha1_hash_with_salt = "#{SHA1.sha1(password + salt).digest}#{salt}"
+ "{SSHA}#{Base64.encode64(sha1_hash_with_salt).chomp}"
+ end
+
+ SALT_CHARS = ['.', '/', '0'..'9', 'A'..'Z', 'a'..'z'].collect do |x|
+ x.to_a
+ end.flatten
+
+ def make_salt(length)
+ salt = ""
+ length.times {salt << SALT_CHARS[rand(SALT_CHARS.length)]}
+ salt
+ end
+ end
+ end
+end
Added: activesambaldap/trunk/lib/active_samba_ldap/idmap.rb (+16 -0)
===================================================================
--- activesambaldap/trunk/lib/active_samba_ldap/idmap.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/lib/active_samba_ldap/idmap.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,16 @@
+module ActiveSambaLdap
+ class Idmap < Base
+ class << self
+ def ldap_mapping(options={})
+ Config.required_variables :idmap_prefix
+ default_options = {
+ :dnattr => "sambaSID",
+ :prefix => Config.idmap_prefix,
+ :classes => ["top", "sambaIdmapEntry"],
+ }
+ options = default_options.merge(options)
+ super options
+ end
+ end
+ end
+end
Added: activesambaldap/trunk/lib/active_samba_ldap/command.rb (+43 -0)
===================================================================
--- activesambaldap/trunk/lib/active_samba_ldap/command.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/lib/active_samba_ldap/command.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,43 @@
+require 'optparse'
+require 'ostruct'
+
+module ActiveSambaLdap
+ module Command
+ module_function
+ def parse_options(argv=nil)
+ argv ||= ARGV.dup
+ options = OpenStruct.new
+ opts = OptionParser.new do |opts|
+ yield(opts, options)
+
+ opts.separator ""
+ opts.separator "Common options:"
+
+ opts.on_tail("--config=CONFIG", "Specify configuration file") do |file|
+ DefaultConfig::FILES << file
+ end
+
+ opts.on_tail("-h", "--help", "Show this message") do
+ puts opts
+ exit
+ end
+
+ opts.on_tail("--version", "Show version") do
+ puts VERSION
+ exit
+ end
+ end
+ opts.parse!(argv)
+ [argv, opts, options]
+ end
+
+ def read_password(prompt, input=STDIN, output=STDOUT)
+ output.print prompt
+ system "/bin/stty -echo" if input.tty?
+ password = input.gets.chomp
+ system "/bin/stty echo" if input.tty?
+ output.puts
+ password
+ end
+ end
+end
Property changed: activesambaldap/trunk/bin/asl-groupshow (+0 -0)
___________________________________________________________________
Name: svn:executable
+
Added: activesambaldap/trunk/bin/asl-groupshow (+29 -0)
===================================================================
--- activesambaldap/trunk/bin/asl-groupshow 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/bin/asl-groupshow 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+
+require 'active_samba_ldap'
+require 'active_samba_ldap/command'
+
+argv, opts, options = ActiveSambaLdap::Command.parse_options do |opts, options|
+ opts.banner += " GROUP_NAME"
+end
+
+name = nil
+if argv.size == 1
+ name = argv.first
+else
+ puts opts
+ exit 1
+end
+
+ActiveSambaLdap::Base.establish_connection({}, true)
+
+class Group < ActiveSambaLdap::Group
+ ldap_mapping
+end
+
+group = Group.new(name)
+unless group.exists?
+ puts "group '#{name}' doesn't exist."
+ exit 1
+end
+puts group
Property changed: activesambaldap/trunk/bin/asl-groupdel (+0 -0)
___________________________________________________________________
Name: svn:executable
+
Added: activesambaldap/trunk/bin/asl-groupdel (+58 -0)
===================================================================
--- activesambaldap/trunk/bin/asl-groupdel 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/bin/asl-groupdel 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,58 @@
+#!/usr/bin/env ruby
+
+require 'active_samba_ldap'
+require 'active_samba_ldap/command'
+
+argv, opts, options = ActiveSambaLdap::Command.parse_options do |opts, options|
+ options.force = false
+
+ opts.banner += " GROUP_NAME"
+
+ opts.on("-f", "--[no-]force",
+ "force delete group (#{options.force})") {|options.force|}
+end
+
+name = nil
+if argv.size == 1
+ name = argv.first
+else
+ puts opts
+ exit 1
+end
+
+unless Process.uid.zero?
+ puts "need root authority."
+ exit 1
+end
+
+ActiveSambaLdap::Base.establish_connection({}, false)
+
+class Group < ActiveSambaLdap::Group
+ ldap_mapping
+end
+
+class User < ActiveSambaLdap::User
+ ldap_mapping
+end
+
+class Computer < ActiveSambaLdap::Computer
+ ldap_mapping
+end
+
+group = Group.new(name)
+unless group.exists?
+ puts "group '#{name}' doesn't exist."
+ exit 1
+end
+
+begin
+ group.destroy(:remove_members => true,
+ :force_change_primary_members => options.force)
+rescue ActiveSambaLdap::Error
+ puts $!
+ exit 1
+end
+
+ActiveSambaLdap::Base.restart_nscd
+
+ActiveSambaLdap::Base.close
Added: trunk/test/test_propfind.rb (+75 -0)
===================================================================
--- trunk/test/test_propfind.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ trunk/test/test_propfind.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,75 @@
+require "test/unit"
+
+require "stringio"
+require "webrick"
+require "webrick/httpservlet/svnhandler"
+
+class SvnServletPROPFINDTest < Test::Unit::TestCase
+ def handler
+ config = {:Logger => WEBrick::Log.new}
+ repos_path = "#{File.dirname(__FILE__)}/tmp/repos"
+ WEBrick::HTTPServlet::SvnHandler.new(config, repos_path)
+ end
+
+ def make_propfind_request_body(dav_props, svn_props)
+ default_dav_props = ["version-controlled-configuration",
+ "resourcetype"]
+ default_svn_props = ["baseline-relative-path",
+ "repository-uuid"],
+
+ dav_props = (dav_props || []) | default_dav_props
+ svn_props = (svn_props || []) | default_svn_props
+
+ dav_props = dav_props.collect {|prop| "<#{prop}/>"}.join("\n")
+ svn_ns = ' xmlns="http://subversion.tigris.org/xmlns/dav/"'
+ svn_props = svn_props.collect {|prop| "<#{prop}#{svn_ns}/>"}.join("\n")
+ <<-EOX
+<?xml version="1.0" encoding="utf-8"?>
+<propfind xmlns="DAV:">
+ <prop>
+#{dav_props}
+#{svn_props}
+ </prop>
+</propfind>
+EOX
+ end
+
+ def make_propfind_request(path, props=nil, depth=0)
+ props ||= {}
+ body = make_propfind_request_body(props[:dav], props[:svn])
+ depth = "Depth: #{depth}" if depth
+ header = <<-EOR
+PROPFIND #{path} HTTP/1.1
+Host: localhost:10080
+User-Agent: SVN/1.4.0 (r21228) neon/0.25.5
+Content-Length: #{body.length}
+Content-Type: text/xml
+#{depth}
+EOR
+ StringIO.new("#{header.strip}\r\n\r\n#{body}")
+ end
+
+ def propfind(path, props=nil, depth=0)
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
+ req.parse(make_propfind_request(path, props, depth))
+ res = WEBrick::HTTPResponse.new(WEBrick::Config::HTTP)
+ handler.do_PROPFIND(req, res)
+ res
+ end
+
+ def test_depth
+ assert_raises(WEBrick::HTTPStatus::Forbidden) do
+ propfind("/", nil, nil)
+ end
+ assert_raises(WEBrick::HTTPStatus::Forbidden) do
+ propfind("/", nil, "infinity")
+ end
+ assert_raises(WEBrick::HTTPStatus::BadRequest) do
+ propfind("/", nil, "NOT-A-NUMBER")
+ end
+
+ assert_nothing_raised do
+ propfind("/")
+ end
+ end
+end
Added: trunk/lib/webrick/httpservlet/svnhandler.rb (+40 -0)
===================================================================
--- trunk/lib/webrick/httpservlet/svnhandler.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ trunk/lib/webrick/httpservlet/svnhandler.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,40 @@
+require 'svn/repos'
+
+require 'webrick/httpstatus/webdav'
+require 'webrick/httpservlet/abstract'
+
+module WEBrick
+ module HTTPServlet
+ class SvnHandler < AbstractServlet
+ def initialize(server, repos_path, options={}, default={})
+ super(server, options)
+ @repos_path = File.expand_path(repos_path)
+ end
+
+ def do_PROPFIND(req, res)
+ depth = normalize_depth(req, res)
+ check_infinite_depth(req, res, depth)
+ end
+
+ private
+ def normalize_depth(req, res)
+ depth = req['Depth']
+ @logger.debug "propfind request depth=#{depth}"
+ depth = nil if depth == "infinity"
+ begin
+ depth = Integer(depth) if depth
+ rescue ArgumentError
+ res.body = "invalid Depth value: #{depth}"
+ raise HTTPStatus::BadRequest
+ end
+ depth
+ end
+
+ def check_infinite_depth(req, res, depth)
+ if depth.nil?
+ raise HTTPStatus::Forbidden
+ end
+ end
+ end
+ end
+end
Added: activesambaldap/trunk/test/test_asl_userdel.rb (+61 -0)
===================================================================
--- activesambaldap/trunk/test/test_asl_userdel.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_asl_userdel.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,61 @@
+require 'test/unit'
+require 'command_support'
+require 'fileutils'
+
+require 'active_samba_ldap'
+
+class AslUserDelTest < Test::Unit::TestCase
+ include CommandSupport
+ include AslTestUtils
+
+ def setup
+ super
+ @asl_userdel = File.join(@bin_dir, "asl-userdel")
+ end
+
+ def test_run_as_normal_user
+ assert_equal([false, "need root authority.\n"],
+ run_asl_userdel_as_normal_user("user-name"))
+ end
+
+ def test_not_exist_user
+ assert_equal([false, "user 'not-exist' doesn't exist.\n"],
+ run_asl_userdel("not-exist"))
+ end
+
+ def test_exist_user
+ make_dummy_user do |user, password|
+ assert(File.exist?(user.homeDirectory(true)))
+ assert_equal([true, ""], run_asl_userdel(user.uid))
+ assert(File.exist?(user.homeDirectory(true)))
+ end
+ end
+
+ def test_belong_to_group
+ make_dummy_user do |user, password|
+ assert(File.exist?(user.homeDirectory(true)))
+ make_dummy_group do |group|
+ group.add_member(user)
+ assert_equal([true, ""], run_asl_userdel(user.uid))
+ end
+ assert(File.exist?(user.homeDirectory(true)))
+ end
+ end
+
+ def test_remove_home_directory
+ make_dummy_user do |user, password|
+ assert(File.exist?(user.homeDirectory(true)))
+ assert_equal([true, ""], run_asl_userdel("-r", user.uid))
+ assert(!File.exist?(user.homeDirectory(true)))
+ end
+ end
+
+ private
+ def run_asl_userdel(*other_args, &block)
+ run_ruby_with_fakeroot(*[@asl_userdel, *other_args], &block)
+ end
+
+ def run_asl_userdel_as_normal_user(*other_args, &block)
+ run_ruby(*[@asl_userdel, *other_args], &block)
+ end
+end
Added: activesambaldap/trunk/test/test_asl_useradd.rb (+699 -0)
===================================================================
--- activesambaldap/trunk/test/test_asl_useradd.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_asl_useradd.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,699 @@
+require 'test/unit'
+require 'command_support'
+require 'asl_test_utils'
+require 'fileutils'
+require 'time'
+require 'tmpdir'
+
+require 'active_samba_ldap'
+
+class AslUserAddTest < Test::Unit::TestCase
+ include CommandSupport
+ include AslTestUtils
+
+ def setup
+ super
+ @asl_useradd = File.join(@bin_dir, "asl-useradd")
+ end
+
+ def test_run_as_normal_user
+ assert_equal([false, "need root authority.\n"],
+ run_asl_useradd_as_normal_user("user-name"))
+ assert_equal([false, "need root authority.\n"],
+ run_asl_useradd_as_normal_user("computer-name$",
+ "--computer-account"))
+ end
+
+ def test_exist_user
+ make_dummy_user do |user, password|
+ assert(@user_class.new(user.uid).exists?)
+ assert_equal([false, "user '#{user.uid}' already exists.\n"],
+ run_asl_useradd(user.uid(true)))
+ assert(@user_class.new(user.uid).exists?)
+ end
+ end
+
+ def test_exist_computer
+ make_dummy_computer do |computer, password|
+ uid = computer.uid(true)
+ assert(@computer_class.new(uid).exists?)
+ assert_equal([false, "computer '#{uid}' already exists.\n"],
+ run_asl_useradd(uid, "--computer-account"))
+ assert(@computer_class.new(uid).exists?)
+ end
+ end
+
+ def test_add_user
+ ensure_delete_user("test-user") do |uid,|
+ assert_asl_useradd_successfully(uid)
+ end
+ end
+
+ def test_add_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ assert_asl_useradd_successfully(uid, "--computer-account")
+ end
+
+ ensure_delete_computer("test-computer") do |uid,|
+ assert_asl_useradd_successfully(uid, "--computer-account")
+ end
+ end
+
+ def test_ou_user
+ ensure_delete_ou("SubOu") do |ou|
+ ou_class = Class.new(ActiveSambaLdap::Ou)
+ ou_class.ldap_mapping :prefix => @user_class.prefix
+ assert(!ou_class.new(ou).exists?)
+
+ ensure_delete_user("test-user") do |uid,|
+ user_class = Class.new(ActiveSambaLdap::User)
+ user_class.ldap_mapping :prefix => "ou=#{ou},#{@user_class.prefix}"
+ assert_raises(ActiveLDAP::ConnectionError) do
+ user_class.new(name)
+ end
+
+ assert_equal([true, ""], run_asl_useradd(uid, "--ou", ou))
+ user = user_class.new(uid)
+ assert(user.exists?)
+
+ assert_match(/\Auid=#{uid},ou=#{ou},/, user.dn)
+ end
+
+ assert(ou_class.new(ou).exists?)
+ end
+ end
+
+ def test_ou_computer
+ ensure_delete_ou("SubOu") do |ou|
+ ou_class = Class.new(ActiveSambaLdap::Ou)
+ ou_class.ldap_mapping :prefix => @computer_class.prefix
+ assert(!ou_class.new(ou).exists?)
+
+ ensure_delete_computer("test-computer$") do |uid,|
+ computer_class = Class.new(ActiveSambaLdap::Computer)
+ computer_class.ldap_mapping :prefix =>
+ "ou=#{ou},#{@computer_class.prefix}"
+ assert_raises(ActiveLDAP::ConnectionError) do
+ computer_class.new(name)
+ end
+
+ assert_equal([true, ""], run_asl_useradd(uid, "--computer-account",
+ "--ou", ou))
+ computer = computer_class.new(uid)
+ assert(computer.exists?)
+
+ assert_match(/\Auid=#{Regexp.escape(uid)},ou=#{ou},/, computer.dn)
+ end
+
+ assert(ou_class.new(ou).exists?)
+ end
+ end
+
+ def test_uid_number
+ ensure_delete_user("test-user") do |uid,|
+ uid_number = Integer(next_uid_number) + 10
+ assert_asl_useradd_successfully(uid, "--uid", uid_number)
+ user = @user_class.new(uid)
+ assert_equal(uid_number, user.uidNumber(true).to_i)
+ end
+
+ ensure_delete_computer("test-computer$") do |uid,|
+ uid_number = Integer(next_uid_number) + 10
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--uid", uid_number)
+ computer = @computer_class.new(uid)
+ assert_equal(uid_number, computer.uidNumber(true).to_i)
+ end
+ end
+
+ def test_gid_number
+ make_dummy_group("test-group") do |group|
+ gid_number = group.gidNumber(true)
+
+ ensure_delete_user("test-user") do |uid,|
+ assert_asl_useradd_successfully(uid, "--gid", gid_number)
+ user = @user_class.new(uid)
+ assert_equal(gid_number, user.gidNumber(true))
+ end
+
+ ensure_delete_computer("test-computer") do |uid,|
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--gid", gid_number)
+ computer = @computer_class.new(uid)
+ assert_equal(gid_number, computer.gidNumber(true))
+ end
+ end
+ end
+
+ def test_groups
+ make_dummy_group do |group1|
+ make_dummy_group do |group2|
+ make_dummy_group do |group3|
+ gid_numbers = [group1.gidNumber(true),
+ group2.gidNumber(true),
+ group3.gidNumber(true)]
+
+ ensure_delete_user("test-user") do |uid,|
+ args = ["--groups", gid_numbers.join(",")]
+ assert_asl_useradd_successfully(uid, *args)
+
+ user = @user_class.new(uid)
+ primary_group = @group_class.find(:attribute => "gidNumber",
+ :value => user.gidNumber)
+ groups = @group_class.find_all(:attribute => "memberUid",
+ :value => uid)
+ assert_equal([primary_group,
+ group1.cn(true),
+ group2.cn(true),
+ group3.cn(true)].sort,
+ groups.sort)
+ end
+
+ ensure_delete_computer("test-computer$") do |uid,|
+ args = ["--computer-account", "--groups", gid_numbers.join(",")]
+ assert_asl_useradd_successfully(uid, *args)
+
+ computer = @computer_class.new(uid)
+ primary_group = @group_class.find(:attribute => "gidNumber",
+ :value => computer.gidNumber)
+ groups = @group_class.find_all(:attribute => "memberUid",
+ :value => uid)
+ assert_equal([primary_group,
+ group1.cn(true),
+ group2.cn(true),
+ group3.cn(true)].sort,
+ groups.sort)
+ end
+ end
+ end
+ end
+ end
+
+ def test_create_group_user
+ ensure_delete_group("test-user") do |gid,|
+ ensure_delete_user("test-user") do |uid,|
+ assert_equal(gid, uid)
+ assert(!@group_class.new(gid).exists?)
+ assert_asl_useradd_successfully(uid, "--create-group")
+ group = @group_class.new(gid)
+ assert(group.exists?)
+
+ user = @user_class.new(uid)
+ assert_equal(group.gidNumber, user.gidNumber)
+ end
+ end
+ end
+
+ def test_create_group_computer
+ ensure_delete_group("test-computer") do |gid,|
+ ensure_delete_computer("test-computer$") do |uid,|
+ assert_equal("#{gid}$", uid)
+ assert(!@group_class.new(gid).exists?)
+ assert_asl_useradd_successfully(uid, "--create-group",
+ "--computer-account")
+ group = @group_class.new(gid)
+ assert(group.exists?)
+
+ computer = @computer_class.new(uid)
+ assert_equal(group.gidNumber, computer.gidNumber)
+ end
+ end
+ end
+
+ def test_comment_user
+ ensure_delete_user("test-user") do |uid,|
+ gecos = "gecos for the user #{uid}"
+ assert_asl_useradd_successfully(uid, "--comment", gecos)
+ user = @user_class.new(uid)
+ assert_equal(gecos, user.gecos(true))
+ end
+ end
+
+ def test_comment_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ gecos = "gecos for the computer #{uid}"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--comment", gecos)
+ computer = @computer_class.new(uid)
+ assert_equal(gecos, computer.gecos(true))
+ end
+ end
+
+ def test_shell_user
+ ensure_delete_user("test-user") do |uid,|
+ shell = "/bin/zsh"
+ assert_asl_useradd_successfully(uid, "--shell", shell)
+ user = @user_class.new(uid)
+ assert_equal(shell, user.loginShell(true))
+ end
+ end
+
+ def test_shell_computer
+ ensure_delete_computer("test-computer") do |uid,|
+ shell = "/bin/zsh"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--shell", shell)
+ computer = @computer_class.new(uid)
+ assert_equal(shell, computer.loginShell(true))
+ end
+ end
+
+ def test_canonical_name_user
+ ensure_delete_user("test-user") do |uid,|
+ cn = "John Kennedy"
+ assert_asl_useradd_successfully(uid, "--canonical-name", cn)
+ user = @user_class.new(uid)
+ assert_equal(uid, user.givenName(true))
+ assert_equal(uid, user.surname(true))
+ assert_equal(cn, user.cn(true))
+ end
+ end
+
+ def test_canonical_name_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ cn = "A computer"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--canonical-name", cn)
+ computer = @computer_class.new(uid)
+ assert_equal(uid, computer.givenName(true))
+ assert_equal(uid, computer.surname(true))
+ assert_equal(cn, computer.cn(true))
+ end
+ end
+
+ def test_given_name_user
+ ensure_delete_user("test-user") do |uid,|
+ given_name = "John"
+ assert_asl_useradd_successfully(uid, "--given-name", given_name)
+ user = @user_class.new(uid)
+ assert_equal(given_name, user.givenName(true))
+ assert_equal(uid, user.cn(true))
+ end
+ end
+
+ def test_given_name_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ given_name = "John"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--given-name", given_name)
+ computer = @computer_class.new(uid)
+ assert_equal(given_name, computer.givenName(true))
+ assert_equal(uid, computer.cn(true))
+ end
+ end
+
+ def test_surname_user
+ ensure_delete_user("test-user") do |uid,|
+ surname = "Kennedy"
+ assert_asl_useradd_successfully(uid, "--surname", surname)
+ user = @user_class.new(uid)
+ assert_equal(surname, user.surname(true))
+ assert_equal(uid, user.cn(true))
+ end
+ end
+
+ def test_surname_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ surname = "Kennedy"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--surname", surname)
+ computer = @computer_class.new(uid)
+ assert_equal(surname, computer.surname(true))
+ assert_equal(uid, computer.cn(true))
+ end
+ end
+
+ def test_given_name_and_surname_user
+ ensure_delete_user("test-user") do |uid,|
+ given_name = "John"
+ surname = "Kennedy"
+ assert_asl_useradd_successfully(uid,
+ "--given-name", given_name,
+ "--surname", surname)
+ user = @user_class.new(uid)
+ assert_equal(given_name, user.givenName(true))
+ assert_equal(surname, user.surname(true))
+ assert_equal("#{given_name} #{surname}", user.cn(true))
+ end
+ end
+
+ def test_given_name_and_surname_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ given_name = "John"
+ surname = "Kennedy"
+ assert_asl_useradd_successfully(uid,
+ "--computer-account",
+ "--given-name", given_name,
+ "--surname", surname)
+ computer = @computer_class.new(uid)
+ assert_equal(given_name, computer.givenName(true))
+ assert_equal(surname, computer.surname(true))
+ assert_equal("#{given_name} #{surname}", computer.cn(true))
+ end
+ end
+
+ def test_home_directory_user
+ ensure_delete_user("test-user") do |uid,|
+ home_directory = "/tmp/#{File.basename(__FILE__)}.#{Process.pid}"
+ begin
+ assert_asl_useradd_successfully(uid,
+ "--home-directory", home_directory,
+ "--setup-home-directory")
+ assert(File.exist?(home_directory))
+ ensure
+ FileUtils.rm_rf(home_directory)
+ end
+ end
+ end
+
+ def test_home_directory_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ home_directory = "/tmp/#{File.basename(__FILE__)}.#{Process.pid}"
+ begin
+ assert_asl_useradd_successfully(uid,
+ "--computer-account",
+ "--home-directory", home_directory,
+ "--setup-home-directory")
+ assert(File.exist?(home_directory))
+ ensure
+ FileUtils.rm_rf(home_directory)
+ end
+ end
+ end
+
+ def test_skeleton_directory
+ home_directory = File.join(Dir.tmpdir,
+ "#{File.basename(__FILE__)}.#{Process.pid}")
+ skeleton_directory = "#{home_directory}.skel"
+ begin
+ normal_file = "hello"
+ dot_file = ".hello"
+ deep_file = File.join("dir", "hello")
+ FileUtils.touch([normal_file, dot_file, deep_file].collect do |f|
+ target = File.join(skeleton_directory, f)
+ FileUtils.mkdir_p(File.dirname(target))
+ target
+ end)
+
+ ensure_delete_user("test-user") do |uid,|
+ assert_asl_useradd_successfully(uid,
+ "--home-directory", home_directory,
+ "--skeleton-directory",
+ skeleton_directory,
+ "--setup-home-directory")
+ assert(File.exist?(home_directory))
+ assert(File.exist?(File.join(home_directory, normal_file)))
+ assert(File.exist?(File.join(home_directory, dot_file)))
+ assert(File.exist?(File.join(home_directory, deep_file)))
+ end
+
+ ensure_delete_computer("test-computer$") do |uid,|
+ assert_asl_useradd_successfully(uid,
+ "--computer-account",
+ "--home-directory", home_directory,
+ "--skeleton-directory",
+ skeleton_directory,
+ "--setup-home-directory")
+ assert(File.exist?(home_directory))
+ assert(File.exist?(File.join(home_directory, normal_file)))
+ assert(File.exist?(File.join(home_directory, dot_file)))
+ assert(File.exist?(File.join(home_directory, deep_file)))
+ end
+ ensure
+ FileUtils.rm_rf([home_directory, skeleton_directory])
+ end
+ end
+
+ def test_expire_date_user
+ ensure_delete_user("test-user") do |uid,|
+ expire_date = Time.now + 60 * 24
+ assert_asl_useradd_successfully(uid, "--expire-date", expire_date.iso8601)
+ user = @user_class.new(uid)
+ assert_equal(expire_date.to_i.to_s, user.sambaKickoffTime(true))
+ end
+ end
+
+ def test_expire_date_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ expire_date = Time.now + 60 * 24
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--expire-date", expire_date.iso8601)
+ computer = @computer_class.new(uid)
+ assert_nil(computer.sambaKickoffTime(true))
+ end
+ end
+
+ def test_can_change_password_user
+ ensure_delete_user("test-user") do |uid,|
+ assert_asl_useradd_successfully(uid, "--can-change-password")
+ user = @user_class.new(uid)
+ assert(user.can_change_password?)
+ end
+ end
+
+ def test_can_change_password_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ ensure_delete_computer("test-computer2$") do |uid2,|
+ assert_asl_useradd_successfully(uid, "--computer-account")
+ assert_asl_useradd_successfully(uid2, "--computer-account",
+ "--can-change-password")
+ computer = @computer_class.new(uid)
+ computer2 = @computer_class.new(uid2)
+ assert_equal(computer.can_change_password?,
+ computer2.can_change_password?)
+ end
+ end
+ end
+
+ def test_no_can_change_password_user
+ ensure_delete_user("test-user") do |uid,|
+ assert_asl_useradd_successfully(uid, "--no-can-change-password")
+ user = @user_class.new(uid)
+ assert(!user.can_change_password?)
+ end
+ end
+
+ def test_no_can_change_password_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ ensure_delete_computer("test-computer2$") do |uid2,|
+ assert_asl_useradd_successfully(uid, "--computer-account")
+ assert_asl_useradd_successfully(uid2, "--computer-account",
+ "--no-can-change-password")
+ computer = @computer_class.new(uid)
+ computer2 = @computer_class.new(uid2)
+ assert_equal(computer.can_change_password?,
+ computer2.can_change_password?)
+ end
+ end
+ end
+
+ def test_must_change_password_user
+ ensure_delete_user("test-user") do |uid,|
+ assert_asl_useradd_successfully(uid, "--must-change-password")
+ user = @user_class.new(uid)
+ assert(user.must_change_password?)
+ end
+ end
+
+ def test_must_change_password_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ ensure_delete_computer("test-computer2$") do |uid2,|
+ assert_asl_useradd_successfully(uid, "--computer-account")
+ assert_asl_useradd_successfully(uid2, "--computer-account",
+ "--must-change-password")
+ computer = @computer_class.new(uid)
+ computer2 = @computer_class.new(uid2)
+ assert_equal(computer.must_change_password?,
+ computer2.must_change_password?)
+ end
+ end
+ end
+
+ def test_no_must_change_password_user
+ ensure_delete_user("test-user") do |uid,|
+ assert_asl_useradd_successfully(uid, "--no-must-change-password")
+ user = @user_class.new(uid)
+ assert(!user.must_change_password?)
+ end
+ end
+
+ def test_no_must_change_password_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ ensure_delete_computer("test-computer2$") do |uid2,|
+ assert_asl_useradd_successfully(uid, "--computer-account")
+ assert_asl_useradd_successfully(uid2, "--computer-account",
+ "--no-must-change-password")
+ computer = @computer_class.new(uid)
+ computer2 = @computer_class.new(uid2)
+ assert_equal(computer.must_change_password?,
+ computer2.must_change_password?)
+ end
+ end
+ end
+
+ def test_samba_home_path_user
+ ensure_delete_user("test-user") do |uid,|
+ home_path = "\\\\ANYWHERE\\here\\%U"
+ assert_asl_useradd_successfully(uid, "--samba-home-path", home_path)
+ user = @user_class.new(uid)
+ assert_equal(home_path.gsub(/%U/, uid), user.sambaHomePath(true))
+ end
+ end
+
+ def test_samba_home_path_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ home_path = "\\\\ANYWHERE\\here\\%U"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--samba-home-path", home_path)
+ computer = @computer_class.new(uid)
+ assert_nil(computer.sambaHomePath(true))
+ end
+ end
+
+ def test_samba_home_drive_user
+ ensure_delete_user("test-user") do |uid,|
+ home_drive = "X:"
+ assert_asl_useradd_successfully(uid, "--samba-home-drive", home_drive)
+ user = @user_class.new(uid)
+ assert_equal(home_drive, user.sambaHomeDrive(true))
+ end
+ end
+
+ def test_samba_home_drive_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ home_drive = "X:"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--samba-home-drive", home_drive)
+ computer = @computer_class.new(uid)
+ assert_nil(computer.sambaHomeDrive(true))
+ end
+ end
+
+ def test_samba_home_drive_abbrev_user
+ ensure_delete_user("test-user") do |uid,|
+ home_drive = "X"
+ assert_asl_useradd_successfully(uid, "--samba-home-drive", home_drive)
+ user = @user_class.new(uid)
+ assert_equal("#{home_drive}:", user.sambaHomeDrive(true))
+ end
+ end
+
+ def test_samba_home_drive_abbrev_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ home_drive = "X"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--samba-home-drive", home_drive)
+ computer = @computer_class.new(uid)
+ assert_nil(computer.sambaHomeDrive(true))
+ end
+ end
+
+ def test_samba_logon_script_user
+ ensure_delete_user("test-user") do |uid,|
+ script = "%U-logon.bat"
+ assert_asl_useradd_successfully(uid, "--samba-logon-script", script)
+ user = @user_class.new(uid)
+ assert_equal(script.gsub(/%U/, uid), user.sambaLogonScript(true))
+ end
+ end
+
+ def test_samba_logon_script_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ script = "%U-logon.bat"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--samba-logon-script", script)
+ computer = @computer_class.new(uid)
+ assert_nil(computer.sambaLogonScript(true))
+ end
+ end
+
+ def test_samba_profile_path_user
+ ensure_delete_user("test-user") do |uid,|
+ profile = "\\\\ANYWHERE\\profiles\\profile-%U"
+ assert_asl_useradd_successfully(uid, "--samba-profile-path", profile)
+ user = @user_class.new(uid)
+ assert_equal(profile.gsub(/%U/, uid), user.sambaProfilePath(true))
+ end
+ end
+
+ def test_samba_profile_path_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ profile = "\\\\ANYWHERE\\profiles\\profile-%U"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--samba-profile-path", profile)
+ computer = @computer_class.new(uid)
+ assert_nil(computer.sambaProfilePath(true))
+ end
+ end
+
+ def test_samba_account_flags_user
+ ensure_delete_user("test-user") do |uid,|
+ flags = "[UX]"
+ assert_asl_useradd_successfully(uid, "--samba-account-flags", flags)
+ user = @user_class.new(uid)
+ assert_equal(flags, user.sambaAcctFlags(true))
+ end
+ end
+
+ def test_samba_account_flags_computer
+ ensure_delete_computer("test-computer$") do |uid,|
+ flags = "[WX]"
+ assert_asl_useradd_successfully(uid, "--computer-account",
+ "--samba-account-flags", flags)
+ computer = @computer_class.new(uid)
+ assert_equal(flags, computer.sambaAcctFlags(true))
+ end
+ end
+
+ private
+ def run_asl_useradd(*other_args, &block)
+ other_args = prepare_args(other_args)
+ run_ruby_with_fakeroot(*[@asl_useradd, *other_args], &block)
+ end
+
+ def run_asl_useradd_as_normal_user(*other_args, &block)
+ other_args = prepare_args(other_args)
+ run_ruby(*[@asl_useradd, *other_args], &block)
+ end
+
+ def prepare_args(args)
+ args = args.dup
+ if args.grep(/\A--(no-)?setup-home-directory\z/).empty?
+ args << "--no-setup-home-directory"
+ end
+ if args.grep(/\A--(no-)?create-group\z/).empty?
+ args << "--no-create-group"
+ end
+ args
+ end
+
+ def assert_asl_useradd_successfully(name, *args)
+ _wrap_assertion do
+ if args.grep(/\A--computer-account\z/).empty?
+ member_class = @user_class
+ else
+ name = name.sub(/\$*\z/, '') + "$"
+ member_class = @computer_class
+ end
+ assert(!member_class.new(name).exists?)
+ args << name
+ assert_equal([true, ""], run_asl_useradd(*args))
+ assert(member_class.new(name).exists?)
+ end
+ end
+
+ def assert_asl_useradd_failed(name, message, *args)
+ _wrap_assertion do
+ if args.grep(/\A--computer-account\z/).empty?
+ member_class = @user_class
+ else
+ name = name.sub(/\$*\z/, '') + "$"
+ member_class = @computer_class
+ end
+ assert(!member_class.new(name).exists?)
+ args << name
+ assert_equal([false, message], run_asl_useradd(*args))
+ assert(!member_class.new(name).exists?)
+ end
+ end
+end
Property changed: activesambaldap/trunk/bin/asl-groupadd (+0 -0)
___________________________________________________________________
Name: svn:executable
+
Added: activesambaldap/trunk/bin/asl-groupadd (+62 -0)
===================================================================
--- activesambaldap/trunk/bin/asl-groupadd 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/bin/asl-groupadd 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,62 @@
+#!/usr/bin/env ruby
+
+require 'active_samba_ldap'
+require 'active_samba_ldap/command'
+
+argv, opts, options = ActiveSambaLdap::Command.parse_options do |opts, options|
+ options.gid = nil
+ options.group_type = "domain"
+ options.print_gid_number = false
+
+ opts.banner += " GROUP_NAME"
+
+ opts.on("-g", "--gid=GID", Integer, "GID number") {|options.gid|}
+ opts.on("-t", "--type=TYPE",
+ "group type (#{options.group_type})") {|options.group_type|}
+ opts.on("-p", "--[no-]print-gid-number",
+ "print the gid number to stdout",
+ "(#{options.print_gid_number})") {|options.print_gid_number|}
+end
+
+name = nil
+if argv.size == 1
+ name = argv.first
+else
+ puts opts
+ exit 1
+end
+
+unless Process.uid.zero?
+ puts "need root authority."
+ exit 1
+end
+
+ActiveSambaLdap::Base.establish_connection({}, true)
+
+class Group < ActiveSambaLdap::Group
+ ldap_mapping
+end
+
+class UnixIdPool < ActiveSambaLdap::UnixIdPool
+ ldap_mapping
+end
+
+if Group.exists?(name)
+ puts "group '#{name}' already exists."
+ exit 1
+end
+
+create_options = {
+ :gid_number => options.gid,
+ :pool_class => UnixIdPool,
+ :group_type => options.group_type,
+}
+group = Group.create(name, create_options)
+
+if options.print_gid_number
+ puts group.gidNumber(true)
+end
+
+ActiveSambaLdap::Base.restart_nscd
+
+ActiveSambaLdap::Base.close
Added: activesambaldap/trunk/test/test_asl_populate.rb (+105 -0)
===================================================================
--- activesambaldap/trunk/test/test_asl_populate.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_asl_populate.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,105 @@
+require 'test/unit'
+require 'command_support'
+require 'asl_test_utils'
+require 'fileutils'
+require 'time'
+
+require 'active_samba_ldap'
+
+class AslPopulateTest < Test::Unit::TestCase
+ include CommandSupport
+ include AslTestUtils
+
+ def setup
+ super
+ @asl_populate = File.join(@bin_dir, "asl-populate")
+ end
+
+ def test_run_as_normal_user
+ assert_equal([false, "need root authority.\n"],
+ run_asl_populate_as_normal_user)
+ end
+
+ def test_populate
+ ActiveSambaLdap::Base.destroy_all
+ assert_equal([], ActiveSambaLdap::Base.search)
+ assert_asl_populate_successfully("Administrator")
+ base = ActiveSambaLdap::Base.base
+
+ results = ActiveSambaLdap::Base.search
+
+ users_prefix = ActiveSambaLdap::Config.users_prefix
+ groups_prefix = ActiveSambaLdap::Config.groups_prefix
+ computers_prefix = ActiveSambaLdap::Config.computers_prefix
+ idmap_prefix = ActiveSambaLdap::Config.idmap_prefix
+ domain = ActiveSambaLdap::Config.samba_domain
+ assert_equal([
+ nil,
+ users_prefix,
+ groups_prefix,
+ computers_prefix,
+ idmap_prefix,
+ "sambaDomainName=#{domain}",
+ "uid=Administrator,#{users_prefix}",
+ "uid=Guest,#{users_prefix}",
+ "cn=Users,#{groups_prefix}",
+ "cn=Account Operators,#{groups_prefix}",
+ "cn=Administrators,#{groups_prefix}",
+ "cn=Backup Operators,#{groups_prefix}",
+ "cn=Domain Admins,#{groups_prefix}",
+ "cn=Domain Computers,#{groups_prefix}",
+ "cn=Domain Guests,#{groups_prefix}",
+ "cn=Domain Users,#{groups_prefix}",
+ "cn=Guests,#{groups_prefix}",
+ "cn=Power Users,#{groups_prefix}",
+ "cn=Print Operators,#{groups_prefix}",
+ "cn=Replicators,#{groups_prefix}",
+ "cn=System Operators,#{groups_prefix}",
+ ].collect {|x| [x, base].compact.join(",")}.sort,
+ results.collect {|result| result["dn"][0]}.sort)
+ end
+
+ def test_wrong_password
+ ActiveSambaLdap::Base.destroy_all
+ assert_asl_populate_miss_match_password
+ end
+
+ private
+ def run_asl_populate(*other_args, &block)
+ run_ruby_with_fakeroot(*[@asl_populate, *other_args], &block)
+ end
+
+ def run_asl_populate_as_normal_user(*other_args, &block)
+ run_ruby(*[@asl_populate, *other_args], &block)
+ end
+
+ def assert_asl_populate_successfully(password, name=nil, *args)
+ name ||= ActiveSambaLdap::User::DOMAIN_ADMIN_NAME
+ assert_equal([true,
+ [
+ "Password for #{name}: ",
+ "Retype password for #{name}: ",
+ ].join("\n") + "\n",
+ ],
+ run_asl_populate(*args) do |input, output|
+ output.puts(password)
+ output.puts(password)
+ end)
+ end
+
+ def assert_asl_populate_miss_match_password(name=nil, *args)
+ name ||= ActiveSambaLdap::User::DOMAIN_ADMIN_NAME
+ password = "password"
+ assert_equal([false,
+ [
+ "Password for #{name}: ",
+ "Retype password for #{name}: ",
+ "Passwords don't match.",
+ ].join("\n") + "\n",
+ ],
+ run_asl_populate(*args) do |input, output|
+ output.puts(password)
+ output.puts(password + password.reverse)
+ end)
+ end
+end
Added: activesambaldap/trunk/test/test_asl_groupshow.rb (+31 -0)
===================================================================
--- activesambaldap/trunk/test/test_asl_groupshow.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_asl_groupshow.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,31 @@
+require 'test/unit'
+require 'command_support'
+require 'fileutils'
+
+require 'active_samba_ldap'
+
+class AslGroupShowTest < Test::Unit::TestCase
+ include CommandSupport
+ include AslTestUtils
+
+ def setup
+ super
+ @asl_groupshow = File.join(@bin_dir, "asl-groupshow")
+ end
+
+ def test_exist_group
+ make_dummy_group do |group|
+ assert_equal([true, group.to_s], run_asl_groupshow(group.cn(true)))
+ end
+ end
+
+ def test_not_exist_group
+ assert_equal([false, "group 'not-exist' doesn't exist.\n"],
+ run_asl_groupshow("not-exist"))
+ end
+
+ private
+ def run_asl_groupshow(*other_args, &block)
+ run_ruby(*[@asl_groupshow, *other_args], &block)
+ end
+end
Added: activesambaldap/trunk/lib/active_samba_ldap/group.rb (+309 -0)
===================================================================
--- activesambaldap/trunk/lib/active_samba_ldap/group.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/lib/active_samba_ldap/group.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,309 @@
+require 'English'
+
+module ActiveSambaLdap
+ class Group < Base
+ # from source/include/rpc_misc.c in Samba
+ DOMAIN_ADMINS_RID = 0x00000200
+ DOMAIN_USERS_RID = 0x00000201
+ DOMAIN_GUESTS_RID = 0x00000202
+ DOMAIN_COMPUTERS_RID = 0x00000203
+
+ LOCAL_ADMINS_RID = 0x00000220
+ LOCAL_USERS_RID = 0x00000221
+ LOCAL_GUESTS_RID = 0x00000222
+ LOCAL_POWER_USERS_RID = 0x00000223
+
+ LOCAL_ACCOUNT_OPERATORS_RID = 0x00000224
+ LOCAL_SYSTEM_OPERATORS_RID = 0x00000225
+ LOCAL_PRINT_OPERATORS_RID = 0x00000226
+ LOCAL_BACKUP_OPERATORS_RID = 0x00000227
+
+ LOCAL_REPLICATORS_RID = 0x00000228
+
+
+ # from source/rpc_server/srv_util.c in Samba
+ DOMAIN_ADMINS_NAME = "Domain Administrators"
+ DOMAIN_USERS_NAME = "Domain Users"
+ DOMAIN_GUESTS_NAME = "Domain Guests"
+ DOMAIN_COMPUTERS_NAME = "Domain Computers"
+
+
+ WELL_KNOWN_RIDS = []
+ WELL_KNOWN_NAMES = []
+ constants.each do |name|
+ case name
+ when /_RID$/
+ WELL_KNOWN_RIDS << const_get(name)
+ when /_NAME$/
+ WELL_KNOWN_NAMES << const_get(name)
+ end
+ end
+
+
+ # from source/librpc/idl/lsa.idl in Samba
+ TYPES = {
+ "domain" => 2,
+ "local" => 4,
+ "builtin" => 5,
+ }
+
+ class << self
+ def ldap_mapping(options={})
+ Config.required_variables :groups_prefix
+ default_options = {
+ :dnattr => "cn",
+ :prefix => Config.groups_prefix,
+ :classes => ["posixGroup", "sambaGroupMapping"],
+
+ :member_local_key => "memberUid",
+ :user_member_class_name => "User",
+ :computer_member_class_name => "Computer",
+
+ :primary_member_foreign_key => "gidNumber",
+ :primary_member_local_key => "gidNumber",
+ :primary_user_member_class_name => "User",
+ :primary_computer_member_class_name => "Computer",
+ }
+ options = default_options.merge(options)
+ super options
+ init_associations(options)
+ end
+
+ def create(name, options={})
+ group = new(name)
+ gid_number, pool = ensure_gid_number(options)
+ group.change_gid_number(gid_number)
+ group.change_type(options[:group_type] || "domain")
+ group.description = options[:description] || name
+ group.displayName = options[:display_name] || name
+ if group.save and pool
+ pool.gidNumber = Integer(group.gidNumber(true)).succ
+ pool.save!
+ end
+ group
+ end
+
+ def destroy(name, options={})
+ new(name).destroy(options)
+ end
+
+ def find_by_name_or_gid_number(key)
+ group = nil
+ begin
+ gid_number = Integer(key)
+ group = find_by_gid_number(gid_number)
+ raise GidNumberDoesNotExist.new(gid_number) if group.nil?
+ rescue ArgumentError
+ group = new(key)
+ raise GroupDoesNotExist.new(key) unless group.exists?
+ end
+ group
+ end
+
+ def find_by_gid_number(number)
+ options = {:objects => true}
+ attribute = "gidNumber"
+ value = Integer(number).to_s
+ if Base::OLD_ACTIVE_LDAP
+ options[:attribute] = attribute
+ options[:value] = value
+ else
+ options[:filter] = "(#{attribute}=#{value})"
+ end
+ find(options)
+ end
+
+ def gid2rid(gid)
+ gid = Integer(gid)
+ if WELL_KNOWN_RIDS.include?(gid)
+ gid
+ else
+ 2 * gid + 1001
+ end
+ end
+
+ def rid2gid(rid)
+ rid = Integer(rid)
+ if WELL_KNOWN_RIDS.include?(rid)
+ rid
+ else
+ (rid - 1001) / 2
+ end
+ end
+
+ def start_gid
+ ActiveSambaLdap::Config.required_variables :start_gid
+ Integer(ActiveSambaLdap::Config.start_gid)
+ end
+
+ def start_rid
+ gid2rid(start_gid)
+ end
+
+ def find_available_gid_number(pool)
+ gid_number = pool.gidNumber(true) || start_gid
+
+ 100.times do |i|
+ if find(:attribute => "gidNumber", :value => gid_number).nil?
+ return gid_number
+ end
+ gid_number = gid_number.succ
+ end
+
+ nil
+ end
+
+ private
+ def init_associations(options)
+ association_options = {}
+ options.each do |key, value|
+ case key.to_s
+ when /^((?:primary_)?(?:(?:user|computer)_)?member)_/
+ association_options[$1] ||= {}
+ association_options[$1][$POSTMATCH.to_sym] = value
+ end
+ end
+
+ member_opts = association_options["member"] || {}
+ user_member_opts = association_options["user_member"] || {}
+ computer_member_opts = association_options["computer_member"] || {}
+ has_many :user_members, member_opts.merge(user_member_opts)
+ has_many :computer_members,
+ member_opts.merge(computer_member_opts)
+
+ primary_member_opts = association_options["primary_member"] || {}
+ primary_user_member_opts =
+ association_options["primary_user_member"] || {}
+ primary_computer_member_opts =
+ association_options["primary_computer_member"] || {}
+ belongs_to :primary_user_members,
+ primary_member_opts.merge(primary_user_member_opts)
+ belongs_to :primary_computer_members,
+ primary_member_opts.merge(primary_computer_member_opts)
+ end
+
+ def ensure_gid_number(options)
+ gid_number = options[:gid_number]
+ pool = nil
+ unless gid_number
+ pool_class = options[:pool_class] || Class.new(UnixIdPool)
+ pool = pool_class.new(options[:samba_domain] || Config[:samba_domain])
+ gid_number = find_available_gid_number(pool)
+ end
+ [gid_number, pool]
+ end
+ end
+
+ def members(*args)
+ user_members(*args) + computer_members(*args)
+ end
+
+ def primary_members(*args)
+ primary_user_members(*args) + primary_computer_members(*args)
+ end
+
+ def change_gid_number(gid, allow_non_unique=false)
+ check_unique_gid_number(gid) unless allow_non_unique
+ rid = self.class.gid2rid(gid)
+ self.gidNumber = gid.to_s
+ change_sid(rid, allow_non_unique)
+ end
+
+ def change_gid_number_by_rid(rid, allow_non_unique=false)
+ change_uid_number(self.class.rid2gid(rid), allow_non_unique)
+ end
+
+ def change_sid(rid, allow_non_unique=false)
+ sid = "#{ActiveSambaLdap::Config.sid}-#{rid}"
+ # check_unique_sid_number(sid) unless allow_non_unique
+ self.sambaSID = sid
+ end
+
+ def rid
+ Integer(sambaSID(true).split(/-/).last)
+ end
+
+ def change_type(type)
+ normalized_type = type.to_s.downcase
+ if TYPES.has_key?(normalized_type)
+ type = TYPES[normalized_type]
+ elsif TYPES.values.include?(type.to_i)
+ # pass
+ else
+ raise ArgumentError, "invalid type: #{type}"
+ end
+ self.sambaGroupType = type.to_s
+ end
+
+ def remove_member(member_or_uid)
+ uid = ensure_uid(member_or_uid)
+ new_memberUid = memberUid.dup
+ unless new_memberUid.reject! {|_uid| uid == _uid}.nil?
+ self.memberUid = new_memberUid
+ save!
+ end
+ end
+
+ def add_member(member_or_uid)
+ uid = ensure_uid(member_or_uid)
+ unless memberUid.find {|_uid| uid == _uid}
+ self.memberUid = (memberUid + [uid]).sort
+ save!
+ end
+ end
+
+ def destroy(options={})
+ if options[:remove_members]
+ if options[:force_change_primary_members]
+ change_primary_members(options)
+ end
+ pr_members = primary_members
+ unless pr_members.empty?
+ raise PrimaryGroupCanNotBeDestroyed.new(cn(true), pr_members)
+ end
+ members(true).each do |member|
+ remove_member(member)
+ end
+ end
+ super()
+ end
+
+ private
+ def ensure_uid(member_or_uid)
+ if member_or_uid.is_a?(String)
+ member_or_uid
+ else
+ member_or_uid.uid(true)
+ end
+ end
+
+ def check_unique_gid_number(gid_number)
+ ActiveSambaLdap::Base.restart_nscd do
+ if self.class.find_by_gid_number(Integer(gid_number))
+ raise GidNumberAlreadyExists.new(gid_number)
+ end
+ end
+ end
+
+ def change_primary_members(options={})
+ name = cn(true)
+
+ pr_members = primary_members(true)
+ cannot_removed_members = []
+ pr_members.each do |member|
+ if (member.groups - [name]).empty?
+ cannot_removed_members << member.uid(true)
+ end
+ end
+ unless cannot_removed_members.empty?
+ raise CanNotChangePrimaryGroup.new(name, cannot_removed_members)
+ end
+
+ pr_members.each do |member|
+ new_group = member.groups(true).find {|gr| gr.cn != name}
+ member.change_group(new_group.gidNumber(true))
+ member.save!
+ end
+ end
+ end
+end
Added: activesambaldap/trunk/lib/active_samba_ldap/account.rb (+297 -0)
===================================================================
--- activesambaldap/trunk/lib/active_samba_ldap/account.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/lib/active_samba_ldap/account.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,297 @@
+require 'time'
+require 'fileutils'
+require 'English'
+
+require 'active_samba_ldap/user_password'
+
+module ActiveSambaLdap
+ module Account
+ def self.included(base)
+ super
+ base.extend(ClassMethods)
+ base.class_eval(<<-EOC, __FILE__, __LINE__ + 1)
+ cattr_accessor :group_class_name
+ cattr_writer :group_class
+ def self.group_class
+ @@group_class || super
+ end
+ EOC
+ end
+
+ # from source/include/rpc_misc.c in Samba
+ DOMAIN_ADMIN_RID = 0x000001F4
+ DOMAIN_GUEST_RID = 0x000001F5
+
+ # from source/rpc_server/srv_util.c in Samba
+ DOMAIN_ADMIN_NAME = "Administrator"
+ DOMAIN_GUEST_NAME = "Guest"
+
+ WELL_KNOWN_RIDS = []
+ WELL_KNOWN_NAMES = []
+ constants.each do |name|
+ case name
+ when /_RID$/
+ WELL_KNOWN_RIDS << const_get(name)
+ when /_NAME$/
+ WELL_KNOWN_NAMES << const_get(name)
+ end
+ end
+
+ FAR_FUTURE_TIME = Time.parse("2050/01/01").to_i.to_s
+ ACCOUNT_FLAGS_RE = /\A\[([NDHTUMWSLXI ]+)\]\z/
+ NAME_RE = /\A(?!\d)[\w @_\-\.]+\z/
+
+ module ClassMethods
+ def valid_name?(name)
+ NAME_RE =~ name ? true : false
+ end
+
+ def ldap_scope
+ LDAP::LDAP_SCOPE_SUBTREE
+ end
+
+ def group_class
+ group_class_name.split(/::/).inject(self) do |ret, name|
+ ret.const_get(name)
+ end
+ end
+
+ def find_by_uid_number(number)
+ options = {:objects => true}
+ attribute = "uidNumber"
+ value = Integer(number)
+ if Base::OLD_ACTIVE_LDAP
+ options[:attribute] = attribute
+ options[:value] = value
+ else
+ options[:filter] = "(#{attribute}=#{value})"
+ end
+ find(options)
+ end
+
+ def uid2rid(uid)
+ uid = Integer(uid)
+ if WELL_KNOWN_RIDS.include?(uid)
+ uid
+ else
+ 2 * uid + 1000
+ end
+ end
+
+ def rid2uid(rid)
+ rid = Integer(rid)
+ if WELL_KNOWN_RIDS.include?(rid)
+ rid
+ else
+ (Integer(rid) - 1000) / 2
+ end
+ end
+
+ def start_uid
+ ActiveSambaLdap::Config.required_variables :start_uid
+ Integer(ActiveSambaLdap::Config.start_uid)
+ end
+
+ def start_rid
+ uid2rid(start_uid)
+ end
+
+ def find_available_uid_number(pool)
+ uid_number = pool.uidNumber(true) || start_uid
+
+ 100.times do |i|
+ if find(:attribute => "uidNumber", :value => uid_number).nil?
+ return uid_number
+ end
+ uid_number = uid_number.succ
+ end
+
+ nil
+ end
+ end
+
+ def init(uid_number, gid_number)
+ self.cn = uid
+ self.sn = uid
+ self.gecos = uid
+ self.homeDirectory = substituted_value(:user_home) {"/nonexistent"}
+ self.loginShell = substituted_value(:user_login_shell) {"/bin/false"}
+ self.sambaHomePath = substituted_value(:user_samba_home)
+ self.sambaHomeDrive = substituted_value(:user_home_drive)
+ self.sambaProfilePath = substituted_value(:user_profile)
+ self.sambaLogonScript = substituted_value(:user_script)
+ self.sambaLogonTime = "0"
+ self.sambaLogoffTime = FAR_FUTURE_TIME
+ self.sambaKickoffTime = FAR_FUTURE_TIME
+ self.sambaAcctFlags = default_account_flags
+
+ self.change_uid_number(uid_number)
+ group = self.change_group(gid_number)
+
+ self.userPassword = "{crypt}x"
+ self.sambaLMPassword = "XXX"
+ self.sambaNTPassword = "XXX"
+ self.sambaPwdLastSet = "0"
+ self.enable_password_change
+ self.disable_forcing_password_change
+
+ self.disable
+
+ group
+ end
+
+ def destroy(options={})
+ if options[:removed_from_group]
+ groups(true).each do |group|
+ group.remove_member(self)
+ end
+ end
+ home_directory = homeDirectory(true)
+ super()
+ if !exists? and options[:remove_home_directory] and
+ File.directory?(home_directory)
+ if options[:remove_home_directory_interactive]
+ system("rm", "-r", "-i", home_directory)
+ else
+ FileUtils.rm_r(home_directory)
+ end
+ end
+ exists?
+ end
+
+ def change_uid_number(uid, allow_non_unique=false)
+ check_unique_uid_number(uid) unless allow_non_unique
+ rid = self.class.uid2rid(uid)
+ self.uidNumber = Integer(uid).to_s
+ change_sid(rid, allow_non_unique)
+ end
+
+ def change_uid_number_by_rid(rid, allow_non_unique=false)
+ change_uid_number(self.class.rid2uid(rid), allow_non_unique)
+ end
+
+ def change_sid(rid, allow_non_unique=false)
+ sid = "#{ActiveSambaLdap::Config.sid}-#{rid}"
+ # check_unique_sid_number(sid) unless allow_non_unique
+ self.sambaSID = sid
+ end
+
+ def rid
+ Integer(sambaSID(true).split(/-/).last)
+ end
+
+ def change_group(gid)
+ if self.class.group_class === gid
+ group = gid
+ else
+ group = self.class.group_class.find_by_name_or_gid_number(gid)
+ end
+ gid_number = group.gidNumber(true)
+ samba_sid = group.sambaSID(true)
+ if samba_sid.nil? or samba_sid.empty?
+ raise GroupDoesNotHaveSambaSID.new(gid_number)
+ end
+ if gidNumber(true)
+ old_gid = gidNumber(true)
+ old_group = self.class.group_class.find_by_name_or_gid_number(old_gid)
+ old_group.remove_member(self)
+ end
+ self.gidNumber = gid_number
+ self.sambaPrimaryGroupSID = samba_sid
+ group
+ end
+
+ def change_password(password)
+ self.userPassword = ActiveSambaLdap::UserPassword.ssha(password)
+ end
+
+ def change_samba_password(password)
+ self.sambaLMPassword = Samba::Encrypt.lm_hash(password)
+ self.sambaNTPassword = Samba::Encrypt.ntlm_hash(password)
+ self.sambaPwdLastSet = Time.now.to_i.to_s
+ end
+
+ def enable_password_change
+ self.sambaPwdCanChange = "0"
+ end
+
+ def disable_password_change
+ self.sambaPwdCanChange = FAR_FUTURE_TIME
+ end
+
+ def can_change_password?
+ sambaPwdCanChange(true).nil? or
+ Time.at(sambaPwdCanChange(true).to_i) <= Time.now
+ end
+
+ def enable_forcing_password_change
+ self.sambaPwdMustChange = "0"
+ if /X/ =~ sambaAcctFlags(true).to_s
+ self.sambaAcctFlags = sambaAcctFlags(true).sub(/X/, '')
+ end
+ if sambaPwdLastSet(true).to_i.zero?
+ self.sambaPwdLastSet = FAR_FUTURE_TIME
+ end
+ end
+
+ def disable_forcing_password_change
+ self.sambaPwdMustChange = FAR_FUTURE_TIME
+ end
+
+ def must_change_password?
+ !(/X/ =~ sambaAcctFlags(true).to_s or
+ sambaPwdMustChange(true).nil? or
+ Time.at(sambaPwdMustChange(true).to_i) > Time.now)
+ end
+
+ def enable
+ if /D/ =~ sambaAcctFlags(true).to_s
+ self.sambaAcctFlags = sambaAcctFlags(true).gsub(/D/, '')
+ end
+ end
+
+ def disable
+ flags = ""
+ if ACCOUNT_FLAGS_RE =~ sambaAcctFlags(true).to_s
+ flags = $1
+ return if /D/ =~ flags
+ end
+ self.sambaAcctFlags = "[D#{flags}]"
+ end
+
+ def enabled?
+ !disabled?
+ end
+
+ def disabled?
+ (/D/ =~ sambaAcctFlags(true).to_s) ? true : false
+ end
+
+ private
+ def check_unique_uid_number(uid_number)
+ ActiveSambaLdap::Base.restart_nscd do
+ if self.class.find_by_uid_number(uid_number)
+ raise UidNumberAlreadyExists.new(uid_number)
+ end
+ end
+ end
+
+ def substitute_template(template)
+ template.gsub(/%U/, uid(true))
+ end
+
+ def substituted_value(key)
+ if block_given?
+ value = ActiveSambaLdap::Config.__send__(key)
+ if value
+ substitute_template(value)
+ else
+ yield
+ end
+ else
+ ActiveSambaLdap::Config.required_variables key
+ substitute_template(ActiveSambaLdap::Config.__send__(key))
+ end
+ end
+ end
+end
Property changed: activesambaldap/trunk/bin/asl-groupmod (+0 -0)
___________________________________________________________________
Name: svn:executable
+
Added: activesambaldap/trunk/bin/asl-groupmod (+114 -0)
===================================================================
--- activesambaldap/trunk/bin/asl-groupmod 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/bin/asl-groupmod 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,114 @@
+#!/usr/bin/env ruby
+
+require 'active_samba_ldap'
+require 'active_samba_ldap/command'
+
+argv, opts, options = ActiveSambaLdap::Command.parse_options do |opts, options|
+ options.gid = nil
+ options.allow_non_unique_gid_number = false
+ options.new_group_name = nil
+ options.members_to_add = nil
+ options.members_to_delete = nil
+
+ opts.banner += " GROUP_NAME"
+
+ opts.on("-g", "--gid=GID", "gid") {|options.gid|}
+ opts.on("--[no-]allow-non-unique-gid",
+ "gid can be non unique " +
+ "(#{options.allow_non_unique_gid_number})") do |bool|
+ options.allow_non_unique_gid_number = bool
+ end
+ opts.on("-r", "--rename=NEW_NAME",
+ "new group name") {|options.new_group_name|}
+ opts.on("-m", "--add-members=MEMBER1,MEMBER2,MEBMER3", Array,
+ "add members (comma delimited)") {|options.members_to_add|}
+ opts.on("-d", "--delete-members=MEMBER1,MEMBER2,MEBMER3", Array,
+ "delete members (comma delimited)") {|options.members_to_delete|}
+end
+
+name = nil
+if argv.size == 1
+ name = argv.first
+else
+ puts opts
+ exit 1
+end
+
+unless Process.uid.zero?
+ puts "need root authority."
+ exit 1
+end
+
+ActiveSambaLdap::Base.establish_connection({}, false)
+
+class Group < ActiveSambaLdap::Group
+ ldap_mapping
+end
+
+class User < ActiveSambaLdap::User
+ ldap_mapping
+end
+
+class Computer < ActiveSambaLdap::Computer
+ ldap_mapping
+end
+
+group = Group.new(name)
+unless group.exists?
+ puts "group '#{name}' doesn't exist."
+ exit 1
+end
+
+if options.gid
+ begin
+ group.change_gid_number(options.gid, options.allow_non_unique_gid_number)
+ rescue ActiveSambaLdap::GidNumberAlreadyExists
+ puts $!.message
+ exit 1
+ end
+end
+
+if options.members_to_add and options.members_to_delete
+ duplicated_members = options.members_to_add & options.members_to_delete
+ unless duplicated_members.empty?
+ message = "there are duplicated members in adding and deleting members: "
+ message << duplicated_members.join(", ")
+ puts message
+ exit 1
+ end
+end
+
+if options.members_to_add
+ options.members_to_add.each do |member|
+ group.add_member(member)
+ end
+end
+
+if options.members_to_delete
+ options.members_to_delete.each do |member|
+ group.remove_member(member)
+ end
+end
+
+group.save!
+
+if options.new_group_name
+ new_group = Group.new(options.new_group_name)
+ if new_group.exists?
+ puts "group '#{options.new_group_name}' always exists."
+ exit 1
+ end
+
+ new_group.attributes = group.attributes.reject do |key, value|
+ %w(cn).include?(key)
+ end
+ new_group.save!
+ group.primary_members(true).each do |member|
+ member.change_group(new_group.gidNumber(true))
+ end
+ group.destroy(:remove_members => true)
+end
+
+ActiveSambaLdap::Base.restart_nscd
+
+ActiveSambaLdap::Base.close
Added: activesambaldap/trunk/test/test_samba_encrypt.rb (+34 -0)
===================================================================
--- activesambaldap/trunk/test/test_samba_encrypt.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_samba_encrypt.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,34 @@
+require 'test/unit'
+require 'stringio'
+
+require 'samba/encrypt'
+
+class SambaEncryptTest < Test::Unit::TestCase
+ def test_lm_hash
+ assert_equal("E52CAC67419A9A224A3B108F3FA6CB6D",
+ Samba::Encrypt.lm_hash("password"))
+ assert_equal("E52CAC67419A9A224A3B108F3FA6CB6D",
+ Samba::Encrypt.lm_hash("paSSWOrd"))
+ assert_equal("E0C510199CC66ABDE0C510199CC66ABD",
+ Samba::Encrypt.lm_hash("abcdefgabcdefg"))
+ assert_equal("FF3750BCC2B22412C2265B23734E0DAC",
+ Samba::Encrypt.lm_hash("SecREt01"))
+ begin
+ stderr = $stderr
+ $stderr = StringIO.new
+ assert_equal("E0C510199CC66ABDE0C510199CC66ABD",
+ Samba::Encrypt.lm_hash("abcdefgabcdefg" + "X"))
+ assert_equal("E0C510199CC66ABDE0C510199CC66ABD",
+ Samba::Encrypt.lm_hash("abcdefgabcdefg" + "X" * 100))
+ assert_equal("password is truncated to 14 characters\n" * 2,
+ $stderr.string)
+ ensure
+ $stderr = stderr
+ end
+ end
+
+ def test_ntlm_hash
+ assert_equal("8846F7EAEE8FB117AD06BDD830B7586C",
+ Samba::Encrypt.ntlm_hash("password"))
+ end
+end
Added: activesambaldap/trunk/test/asl_test_utils.rb (+162 -0)
===================================================================
--- activesambaldap/trunk/test/asl_test_utils.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/asl_test_utils.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,162 @@
+module AslTestUtils
+ def setup
+ super
+ ActiveSambaLdap::Base.establish_connection({}, false)
+
+ @user_class = Class.new(ActiveSambaLdap::User)
+ @user_class.ldap_mapping
+ @computer_class = Class.new(ActiveSambaLdap::Computer)
+ @computer_class.ldap_mapping
+ @group_class = Class.new(ActiveSambaLdap::Group)
+ @group_class.ldap_mapping
+
+ @user_class.group_class = @group_class
+ @computer_class.group_class = @group_class
+
+ @original_ldifs = ""
+ @user_index = 0
+ @computer_index = 0
+ @group_index = 0
+ begin
+ @original_ldifs = ActiveSambaLdap::Base.dump
+ ActiveSambaLdap::Base.destroy_all
+ ActiveSambaLdap::Base.populate
+ rescue ActiveLDAP::ConnectionError
+ end
+ end
+
+ def teardown
+ ActiveSambaLdap::Base.destroy_all
+ ActiveSambaLdap::Base.load(@original_ldifs)
+ ActiveSambaLdap::Base.close
+ super
+ end
+
+ def make_dummy_user(config={})
+ @user_index += 1
+ name = config[:name] || "test-user#{@user_index}"
+ home_directory = config[:home_directory] || "/tmp/#{name}-#{Process.pid}"
+ ensure_delete_user(name, home_directory) do
+ password = config[:password] || "password"
+ uid_number = config[:uid_number] || "100000#{@user_index}"
+ default_user_gid = ActiveSambaLdap::DefaultConfig.default_user_gid
+ gid_number = config[:gid_number] || default_user_gid
+ _wrap_assertion do
+ user = @user_class.new(name)
+ assert(!user.exists?)
+ user.init(uid_number, gid_number)
+ user.homeDirectory = home_directory
+ user.change_password(password)
+ user.change_samba_password(password)
+ user.save!
+ FileUtils.mkdir(home_directory)
+ assert(user.exists?)
+ yield(user, password)
+ end
+ end
+ end
+
+ def ensure_delete_user(uid, home=nil)
+ yield(uid, home)
+ ensure
+ FileUtils.rm_rf(home) if home
+ user = @user_class.new(uid)
+ if user.exists?
+ groups = @group_class.find_all(:attribute => "memberUid",
+ :value => user.uid)
+ groups.each do |group|
+ @group_class.new(group).remove_member(user)
+ end
+ user.destroy
+ end
+ end
+
+ def make_dummy_computer(config={})
+ @computer_index += 1
+ name = config[:name] || "test-computer#{@computer_index}$"
+ home_directory = config[:home_directory] || "/tmp/#{name}-#{Process.pid}"
+ ensure_delete_computer(name, home_directory) do |name, home_directory|
+ password = config[:password]
+ uid_number = config[:uid_number] || "100000#{@computer_index}"
+ default_computer_gid = ActiveSambaLdap::DefaultConfig.default_computer_gid
+ gid_number = config[:gid_number] || default_computer_gid
+ _wrap_assertion do
+ computer = @computer_class.new(name)
+ assert(!computer.exists?)
+ computer.init(uid_number, gid_number)
+ if password
+ computer.change_password(password)
+ computer.change_samba_password(password)
+ end
+ computer.save!
+ FileUtils.mkdir(home_directory)
+ assert(computer.exists?)
+ yield(computer, password)
+ end
+ end
+ end
+
+ def ensure_delete_computer(uid, home=nil)
+ yield(uid.sub(/\$+\z/, '') + "$", home)
+ ensure
+ FileUtils.rm_rf(home) if home
+ computer = @computer_class.new(uid)
+ if computer.exists?
+ groups = @group_class.find_all(:attribute => "memberUid",
+ :value => computer.uid)
+ groups.each do |group|
+ @group_class.new(group).remove_member(computer)
+ end
+ computer.destroy
+ end
+ end
+
+ def make_dummy_group(config={})
+ @group_index += 1
+ name = config[:name] || "test-group#{@group_index}"
+ ensure_delete_group(name) do
+ gid_number = config[:gid_number] || "200000#{@group_index}"
+ group_type = config[:group_type] || "domain"
+ _wrap_assertion do
+ group = @group_class.new(name)
+ assert(!group.exists?)
+ group.change_gid_number(gid_number)
+ group.change_type(group_type)
+ group.save!
+ assert(group.exists?)
+ yield(group)
+ end
+ end
+ end
+
+ def ensure_delete_group(name)
+ yield(name)
+ ensure
+ group = @group_class.new(name)
+ group.destroy if group.exists?
+ end
+
+ def ensure_delete_ou(ou)
+ yield(ou)
+ ensure
+ ou_class = Class.new(ActiveSambaLdap::Ou)
+ ou_class.ldap_mapping
+ ou_obj = ou_class.new(ou)
+ ou_obj.destroy if ou_obj.exists?
+ end
+
+ def pool
+ pool_class = Class.new(ActiveSambaLdap::UnixIdPool)
+ pool_class.ldap_mapping
+ ActiveSambaLdap::Config.required_variables :samba_domain
+ pool_class.new(ActiveSambaLdap::Config.samba_domain)
+ end
+
+ def next_uid_number
+ pool.uidNumber(true) || @user_class.start_uid
+ end
+
+ def next_gid_number
+ pool.gidNumber(true) || @group_class.start_gid
+ end
+end
Added: activesambaldap/trunk/lib/active_samba_ldap/base.rb (+379 -0)
===================================================================
--- activesambaldap/trunk/lib/active_samba_ldap/base.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/lib/active_samba_ldap/base.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,379 @@
+require_gem_if_need "activeldap", nil, ">= 0.8.0"
+
+module ActiveSambaLdap
+ class Error < StandardError
+ end
+
+ class RequiredVariableIsNotSet < Error
+ attr_reader :name
+ def initialize(name)
+ @name = name
+ super("required variable '#{name}' is not set")
+ end
+ end
+
+ class UidNumberAlreadyExists < Error
+ attr_reader :number
+ def initialize(number)
+ @number = number
+ super("uid number '#{@number}' already exists")
+ end
+ end
+
+ class GroupDoesNotExist < Error
+ attr_reader :name
+ def initialize(name)
+ @name = name
+ super("group '#{@name}' doesn't exist")
+ end
+ end
+
+ class GidNumberAlreadyExists < Error
+ attr_reader :number
+ def initialize(number)
+ @number = number
+ super("gid number '#{@number}' already exists")
+ end
+ end
+
+ class GidNumberDoesNotExist < Error
+ attr_reader :number
+ def initialize(number)
+ @number = number
+ super("gid number '#{@number}' doesn't exist")
+ end
+ end
+
+ class GroupDoesNotHaveSambaSID < Error
+ attr_reader :number
+ def initialize(number)
+ @number = number
+ super("sambaSID attribute doesn't exist for gid number '#{@number}'")
+ end
+ end
+
+ class CanNotChangePrimaryGroup < Error
+ attr_reader :group, :members
+ def initialize(group, members)
+ @group = group
+ @members = members
+ message = "cannot change primary group from '#{group}' to other group "
+ message << "due to no other belonged groups: #{members.join(', ')}"
+ super(message)
+ end
+ end
+
+ class PrimaryGroupCanNotBeDestroyed < Error
+ attr_reader :group, :members
+ def initialize(group, members)
+ @group = group
+ @members = members
+ message = "cannot destroy group '#{group}' due to members who belong "
+ message << "to the group as primary group: #{members.join(', ')}"
+ super(message)
+ end
+ end
+
+ class Base < ActiveLDAP::Base
+ include Reloadable::Subclasses
+
+ OLD_ACTIVE_LDAP = (ActiveLDAP::VERSION.split(/\./) <=> %w(0 8 0)) < 0
+
+ if OLD_ACTIVE_LDAP
+ class << ActiveLDAP::Base
+ def establish_connection(config={})
+ connect(config)
+ end
+ end
+
+ alias_method :save, :write
+
+ def initialize(val)
+ val = val.first if val.is_a?(Array) and val.size == 1
+ super(val)
+ end
+
+ def update_attribute(name, value)
+ if self.attribute_names.member?(name)
+ send(:attribute_method=, name, value)
+ end
+ save
+ end
+
+ def update_attributes(h)
+ self.attributes = h
+ save
+ end
+
+ alias_method :attribute_names, :attributes
+ def attributes
+ Marshal.load(Marshal.dump(@data))
+ end
+
+ def attributes=(h)
+ if h.respond_to?(:keys) and h.respond_to?(:[])
+ h.each_pair do |key, value|
+ key = key.to_s.downcase
+ if self.attribute_names.member?(key)
+ send(:attribute_method=, key, value)
+ end
+ end
+ end
+ end
+ end
+
+ class << self
+ def prefix
+ base.gsub(/,?#{Regexp.escape(self.ancestors[1].base)}\z/, '')
+ end
+
+ def instantiate(record)
+ object = allocate
+ object.instance_variable_set("@attributes", record)
+ object
+ end
+
+ def human_attribute_name(attribute_key_name)
+ attribute_key_name.humanize
+ end
+
+ def establish_connection(config={}, reference_only=true)
+ Config.init
+ Config.required_variables :suffix
+ default_config = {:base => Config.suffix}
+ if reference_only
+ Config.required_variables :reference_host, :reference_port
+ default_config[:host] = Config.reference_host
+ default_config[:port] = Config.reference_port
+ default_config[:bind_format] = Config.reference_bind_format
+ default_config[:user] = Config.reference_user
+ default_config[:password] = Config.reference_password
+ default_config[:method] = :tls if Config.reference_use_tls
+ default_config[:allow_anonymous] = Config.reference_allow_anonymous
+ else
+ Config.required_variables :update_host, :update_port
+ default_config[:host] = Config.update_host
+ default_config[:port] = Config.update_port
+ default_config[:bind_format] = Config.update_bind_format
+ default_config[:user] = Config.update_user
+ default_config[:password] = Config.update_password
+ default_config[:method] = :tls if Config.update_use_tls
+ default_config[:allow_anonymous] = Config.update_allow_anonymous
+ end
+ default_config.each do |key, value|
+ default_config.delete(key) if value.nil?
+ end
+ super(default_config.merge(config))
+ end
+
+ def destroy_all(config={})
+ targets = []
+ begin
+ targets = search(config).collect do |entry|
+ entry["dn"][0]
+ end.sort_by do |dn|
+ dn.reverse
+ end.reverse
+ rescue RuntimeError
+ end
+ return if targets.empty?
+
+ connection do |conn|
+ targets.each do |target|
+ conn.delete(target)
+ end
+ end
+ end
+
+ def dump(config={})
+ ldifs = []
+ search(config).each do |entry|
+ ldif = LDAP::LDIF.to_ldif("dn", entry.delete("dn"))
+ entry.each do |key, values|
+ ldif << LDAP::LDIF.to_ldif(key, values)
+ end
+ ldifs << ldif
+ end
+ ldifs.join("\n")
+ end
+
+ def load(ldifs)
+ connection do |conn|
+ ldifs.split(/(?:\r?\n){2,}/).each do |ldif|
+ LDAP::LDIF.parse_entry(ldif).send(conn)
+ end
+ end
+ end
+
+ def search(*args, &block)
+ super(*args, &block)
+ rescue RuntimeError
+ []
+ end
+
+ def exists?(dn_value)
+ new(dn_value).exists?
+ end
+
+ def restart_nscd
+ if system("/etc/init.d/nscd status >/dev/null 2>&1")
+ system("/etc/init.d/nscd stop >/dev/null 2>&1")
+ begin
+ yield if block_given?
+ ensure
+ system("/etc/init.d/nscd start >/dev/null 2>&1")
+ end
+ end
+ end
+ end
+
+ alias_method :respond_to_without_attributes?, :respond_to?
+
+ alias_method :validate_ldap, :validate
+ alias_method :save_ldap, :save
+ alias_method :destroy, :delete
+ alias_method :new_record?, :exists?
+
+ def save!
+ enforce_types
+ save_ldap
+ end
+
+ def save
+ create_or_update
+ end
+
+ def to_ldif
+ ldif = ::LDAP::LDIF.to_ldif("dn", [@dn.dup])
+ @data.sort_by do |key, values|
+ key
+ end.each do |key, values|
+ ldif << ::LDAP::LDIF.to_ldif(key, values.collect {|value| value.dup})
+ end
+
+ ldif
+ end
+ alias_method :to_s, :to_ldif
+
+ private
+ def create_or_update
+ begin
+ save!
+ true
+ rescue RuntimeError => e
+ if /^ActiveLDAP::/ =~ e.class.name
+ false
+ else
+ raise
+ end
+ end
+ end
+
+ def create
+ save
+ end
+
+ def update
+ save
+ end
+
+ include ActiveRecord::Validations
+ include ActiveRecord::Callbacks
+ end
+end
+
+require "ldap/ldif"
+
+class LDAP::Mod
+ unless instance_method(:to_s).arity.zero?
+ def to_s
+ inspect
+ end
+ end
+
+ if ActiveSambaLdap::Base::OLD_ACTIVE_LDAP
+ alias_method :_initialize, :initialize
+ def initialize(op, type, vals)
+ if (LDAP::VERSION.split(/\./).collect {|x| x.to_i} <=> [0, 9, 7]) <= 0
+ @op, @type, @vals = op, type, vals # to protect from GC
+ end
+ _initialize(op, type, vals)
+ end
+ end
+end
+
+if ActiveSambaLdap::Base::OLD_ACTIVE_LDAP
+ class LDAP::Schema2
+ def attr(sub, type, at)
+ return [] if sub.empty?
+ return [] if type.empty?
+ return [] if at.empty?
+
+ type = type.downcase # We're going case insensitive.
+
+ # Check already parsed options first
+ if @@attr_cache.has_key? sub \
+ and @@attr_cache[sub].has_key? type \
+ and @@attr_cache[sub][type].has_key? at
+ return @@attr_cache[sub][type][at].dup
+ end
+
+ # Initialize anything that is required
+ unless @@attr_cache.has_key? sub
+ @@attr_cache[sub] = {}
+ end
+
+ unless @@attr_cache[sub].has_key? type
+ @@attr_cache[sub][type] = {}
+ end
+
+ at = at.upcase
+ self[sub].each do |s|
+ line = nil
+ if type[0..0] =~ /[0-9]/
+ if s =~ /\(\s+(?i:#{type})\s+(?:[A-Z]|\))/
+ line = s
+ end
+ else
+ # support NAME 'dsa' or NAME ( 'das' 'dsa' ... )
+ if s =~ /NAME\s+(?:(?:\(.*'(?i:#{type})'.*?\))|(?:'(?i:#{type})'))\s+(?:[A-Z]|\))/
+ line = s
+ end
+ end
+ next if line.nil?
+
+ # I need to check, but I think some of these matchs
+ # overlap. I'll need to check these when I'm less sleepy.
+ multi = nil
+ case line
+ when /#{at}\s+[\)A-Z]/
+ @@attr_cache[sub][type][at] = ['TRUE']
+ return ['TRUE']
+ when /#{at}\s+'(.+?)'/
+ @@attr_cache[sub][type][at] = [$1]
+ return [$1]
+ when /#{at}\s+\((.+?)\)/
+ multi = $1
+ when /#{at}\s+\(([\w\d\s\.]+)\)/
+ multi = $1
+ when /#{at}\s+([\w\d\.]+)/
+ @@attr_cache[sub][type][at] = [$1]
+ return [$1]
+ end
+ next if multi.nil?
+ # Split up multiple matches
+ # if oc then it is sep'd by $
+ # if attr then bu spaces
+ if multi.match(/\$/)
+ @@attr_cache[sub][type][at] = multi.split("$").collect{|attr| attr.strip}
+ return @@attr_cache[sub][type][at].dup
+ elsif not multi.empty?
+ @@attr_cache[sub][type][at] = multi.gsub(/'/, '').split(' ').collect{|attr| attr.strip}
+ return @@attr_cache[sub][type][at].dup
+ end
+ end
+ @@attr_cache[sub][type][at] = []
+ return []
+ end
+ end
+end
Property changed: activesambaldap/trunk/bin/asl-usershow (+0 -0)
___________________________________________________________________
Name: svn:executable
+
Added: activesambaldap/trunk/bin/asl-usershow (+29 -0)
===================================================================
--- activesambaldap/trunk/bin/asl-usershow 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/bin/asl-usershow 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+
+require 'active_samba_ldap'
+require 'active_samba_ldap/command'
+
+argv, opts, options = ActiveSambaLdap::Command.parse_options do |opts, options|
+ opts.banner += " USER_NAME"
+end
+
+name = nil
+if argv.size == 1
+ name = argv.first
+else
+ puts opts
+ exit 1
+end
+
+ActiveSambaLdap::Base.establish_connection({}, true)
+
+class User < ActiveSambaLdap::User
+ ldap_mapping
+end
+
+user = User.new(name)
+unless user.exists?
+ puts "user '#{name}' doesn't exist."
+ exit 1
+end
+puts user
Property changed: trunk/sample/svnserver.rb (+0 -0)
___________________________________________________________________
Name: svn:executable
+
Added: trunk/sample/svnserver.rb (+18 -0)
===================================================================
--- trunk/sample/svnserver.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ trunk/sample/svnserver.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,18 @@
+#!/usr/bin/ruby
+
+if ARGV.size != 1
+ puts "USAGE: #{$0} repository_path"
+ exit 1
+end
+
+require 'webrick'
+require 'webrick/httpservlet/svnhandler'
+
+repos_path = ARGV.shift
+
+log = WEBrick::Log.new
+log.level = WEBrick::Log::DEBUG if $DEBUG
+server = WEBrick::HTTPServer.new({:Port => 10080, :Logger => log})
+server.mount("/", WEBrick::HTTPServlet::SvnHandler, repos_path)
+trap(:INT){server.shutdown}
+server.start
Added: activesambaldap/trunk/test/test_asl_usershow.rb (+31 -0)
===================================================================
--- activesambaldap/trunk/test/test_asl_usershow.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_asl_usershow.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,31 @@
+require 'test/unit'
+require 'command_support'
+require 'fileutils'
+
+require 'active_samba_ldap'
+
+class AslUserShowTest < Test::Unit::TestCase
+ include CommandSupport
+ include AslTestUtils
+
+ def setup
+ super
+ @asl_usershow = File.join(@bin_dir, "asl-usershow")
+ end
+
+ def test_exist_user
+ make_dummy_user do |user, password|
+ assert_equal([true, user.to_s], run_asl_usershow(user.uid(true)))
+ end
+ end
+
+ def test_not_exist_user
+ assert_equal([false, "user 'not-exist' doesn't exist.\n"],
+ run_asl_usershow("not-exist"))
+ end
+
+ private
+ def run_asl_usershow(*other_args, &block)
+ run_ruby(*[@asl_usershow, *other_args], &block)
+ end
+end
Added: activesambaldap/trunk/test/test_asl_passwd.rb (+139 -0)
===================================================================
--- activesambaldap/trunk/test/test_asl_passwd.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_asl_passwd.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,139 @@
+require 'test/unit'
+require 'command_support'
+require 'asl_test_utils'
+
+require 'active_samba_ldap'
+
+class AslPasswdTest < Test::Unit::TestCase
+ include CommandSupport
+ include AslTestUtils
+
+ def setup
+ super
+ @asl_passwd = File.join(@bin_dir, "asl-passwd")
+ end
+
+ def teardown
+ ActiveSambaLdap::Base.close
+ end
+
+ def test_unknown_user
+ assert_equal([false, "user 'unknown' doesn't exist.\n"],
+ run_asl_passwd("unknown"))
+ end
+
+ def test_change_password
+ make_dummy_user do |user, password|
+ new_password = "new#{password}"
+
+ assert_samba_password(user, password)
+
+ assert_change_password_successfully(user.uid(true),
+ password, new_password)
+
+ user = @user_class.new(user.uid(true))
+ assert_samba_password(user, new_password)
+
+ assert_change_password_with_wrong_current_password(user.uid(true),
+ password)
+
+ assert_change_password_successfully(user.uid(true),
+ new_password, password)
+ user = @user_class.new(user.uid(true))
+ assert_samba_password(user, password)
+ end
+ end
+
+ def test_change_password_only_unix
+ make_dummy_user do |user, password|
+ new_password = "new#{password}"
+ args = ["--no-samba-password"]
+
+ assert_samba_password(user, password)
+
+ assert_change_password_successfully(user.uid(true),
+ password, new_password,
+ *args)
+ user = @user_class.new(user.uid(true))
+ assert_samba_password(user, password)
+
+ assert_change_password_with_wrong_current_password(user.uid(true),
+ password, *args)
+
+ assert_change_password_successfully(user.uid(true),
+ new_password, password, *args)
+ user = @user_class.new(user.uid(true))
+ assert_samba_password(user, password)
+ end
+ end
+
+ def test_change_password_only_samba
+ make_dummy_user do |user, password|
+ new_password = "new#{password}"
+ args = ["--no-unix-password"]
+
+ assert_samba_password(user, password)
+
+ assert_change_password_successfully(user.uid(true),
+ password, new_password, *args)
+ user = @user_class.new(user.uid(true))
+ assert_samba_password(user, new_password)
+
+ assert_change_password_with_wrong_current_password(user.uid(true),
+ new_password, *args)
+
+ assert_change_password_successfully(user.uid(true), password, password,
+ *args)
+ user = @user_class.new(user.uid(true))
+ assert_samba_password(user, password)
+ end
+ end
+
+ private
+ def run_asl_passwd(*other_args, &block)
+ run_ruby(*[@asl_passwd, *other_args], &block)
+ end
+
+ def change_password(name, old_password, new_password, *args)
+ run_asl_passwd(name, *args) do |input, output|
+ output.puts(old_password)
+ output.puts(new_password)
+ output.puts(new_password)
+ output.flush
+ end
+ end
+
+ def assert_samba_password(user, password)
+ _wrap_assertion do
+ assert_equal(Samba::Encrypt.lm_hash(password),
+ user.sambaLMPassword(true))
+ assert_equal(Samba::Encrypt.ntlm_hash(password),
+ user.sambaNTPassword(true))
+ end
+ end
+
+ def assert_change_password_successfully(name, old_password, new_password,
+ *args)
+ assert_equal([true,
+ [
+ "Enter your current password: ",
+ "New password: ",
+ "Retype new password: ",
+ ].join("\n") + "\n",
+ ],
+ change_password(name, old_password, new_password, *args))
+ end
+
+ def assert_change_password_with_wrong_current_password(name, password, *args)
+ assert_equal([false,
+ [
+ "Enter your current password: ",
+ "password isn't match",
+ ].join("\n") + "\n",
+ ],
+ run_asl_passwd(name, *args) do |input, output|
+ output.puts(password)
+ output.flush
+ end)
+ end
+end
Added: activesambaldap/trunk/lib/active_samba_ldap/computer.rb (+35 -0)
===================================================================
--- activesambaldap/trunk/lib/active_samba_ldap/computer.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/lib/active_samba_ldap/computer.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,35 @@
+require 'active_samba_ldap/account'
+
+module ActiveSambaLdap
+ class Computer < Base
+ include Account
+ class << self
+ def ldap_mapping(options={})
+ Config.required_variables :computers_prefix
+ default_options = {
+ :dnattr => "uid",
+ :prefix => Config.computers_prefix,
+ :classes => ["top", "inetOrgPerson", "posixAccount",
+ "sambaSamAccount"],
+ :group_class_name => "Group",
+ :group_foreign_key => "memberUid",
+ }
+ options = default_options.merge(options)
+ super options
+ belongs_to :groups,
+ :class_name => options[:group_class_name],
+ :foreign_key => options[:group_foreign_key]
+ self.group_class_name = options[:group_class_name]
+ end
+
+ def valid_name?(name)
+ /\$\Z/ =~ name and User.valid_name?($PREMATCH)
+ end
+ end
+
+ private
+ def default_account_flags
+ "[W]"
+ end
+ end
+end
Property changed: activesambaldap/trunk/bin/asl-passwd (+0 -0)
___________________________________________________________________
Name: svn:executable
+
Added: activesambaldap/trunk/bin/asl-passwd (+91 -0)
===================================================================
--- activesambaldap/trunk/bin/asl-passwd 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/bin/asl-passwd 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,91 @@
+#!/usr/bin/env ruby
+
+require 'etc'
+
+require 'active_samba_ldap'
+require 'active_samba_ldap/command'
+
+argv, opts, options = ActiveSambaLdap::Command.parse_options do |opts, options|
+ options.update_samba_password = true
+ options.update_unix_password = true
+
+ opts.banner += " [USER_NAME]"
+
+ opts.on("-s", "--[no-]samba-password",
+ "update samba password (#{options.update_samba_password})") do |bool|
+ options.update_samba_password = bool
+ end
+
+ opts.on("-u", "--[no-]unix-password",
+ "update UNIX password (#{options.update_unix_password})") do |bool|
+ options.update_unix_password = bool
+ end
+end
+
+name = nil
+case argv.size
+when 0
+ name = Etc.getpwuid(Process.uid).name
+when 1
+ name = argv.first
+else
+ puts opts
+ exit 1
+end
+
+if !options.update_samba_password and !options.update_unix_password
+ puts "do nothing"
+ exit
+end
+
+ActiveSambaLdap::Base.establish_connection({}, true)
+
+class User < ActiveSambaLdap::User
+ ldap_mapping
+end
+
+user = User.new(name)
+unless user.exists?
+ puts "user '#{name}' doesn't exist."
+ exit 1
+end
+
+unless Process.uid.zero?
+ prompt = "Enter your current password: "
+ old_password = ActiveSambaLdap::Command.read_password(prompt)
+
+ ActiveSambaLdap::Base.close
+ begin
+ ActiveSambaLdap::Base.establish_connection({:bind_format => user.dn,
+ :password => old_password,
+ :allow_anonymous => false},
+ false)
+ rescue LDAP::InvalidCredentials
+ puts "password isn't match"
+ exit 1
+ end
+end
+
+password = ActiveSambaLdap::Command.read_password("New password: ")
+password2 = ActiveSambaLdap::Command.read_password("Retype new password: ")
+
+unless password == password2
+ puts "New passwords don't match."
+ exit 1
+end
+
+changed = false
+
+if options.update_unix_password
+ user.change_password(password)
+ changed = true
+end
+
+if options.update_samba_password
+ user.change_samba_password(password)
+ changed = true
+end
+
+user.save! if changed
+
+ActiveSambaLdap::Base.close
Added: activesambaldap/trunk/test/test_asl_groupmod.rb (+278 -0)
===================================================================
--- activesambaldap/trunk/test/test_asl_groupmod.rb 2006-11-10 00:40:39 -15:00 (rev 0)
+++ activesambaldap/trunk/test/test_asl_groupmod.rb 2007-08-04 11:30:36 +09:00 (rev 1)
@@ -0,0 +1,278 @@
+require 'test/unit'
+require 'command_support'
+require 'asl_test_utils'
+require 'fileutils'
+require 'time'
+
+require 'active_samba_ldap'
+
+class AslGroupModTest < Test::Unit::TestCase
+ include CommandSupport
+ include AslTestUtils
+
+ def setup
+ super
+ @asl_groupmod = File.join(@bin_dir, "asl-groupmod")
+ end
+
+ def test_not_exist_group
+ assert_equal([false, "group 'not-exist' doesn't exist.\n"],
+ run_asl_groupmod("not-exist"))
+ end
+
+ def test_rename
+ make_dummy_group do |group|
+ old_cn = group.cn(true)
+ new_cn = "#{old_cn}-new"
+ ensure_delete_group(new_cn) do
+ new_group = @group_class.new(new_cn)
+ assert(!new_group.exists?)
+
+ args = ["--rename", new_cn]
+ assert_asl_groupmod_successfully(group.cn(true), *args)
+
+ old_group = @group_class.new(old_cn)
+ assert(!old_group.exists?)
+ new_group = @group_class.new(new_cn)
+ assert(new_group.exists?)
+ end
+ end
+ end
+
+ def test_rename_with_members
+ make_dummy_user do |user1, password1|
+ make_dummy_user do |user2, password2|
+ make_dummy_group do |group|
+ group.add_member(user1)
+ group.add_member(user2)
+
+ old_cn = group.cn(true)
+ new_cn = "#{old_cn}-new"
+ ensure_delete_group(new_cn) do
+ new_group = @group_class.new(new_cn)
+ assert(!new_group.exists?)
+
+ args = ["--rename", new_cn]
+ assert_asl_groupmod_successfully(group.cn(true), *args)
+
+ old_group = @group_class.new(old_cn)
+ assert(!old_group.exists?)
+ new_group = @group_class.new(new_cn)
+ assert(new_group.exists?)
+
+ members = []
+ new_group.memberUid.each do |uid|
+ members.concat(@user_class.find_all(:attribute => "uid",
+ :value => uid))
+ end
+ assert_equal([user1.uid(true), user2.uid(true)].sort,
+ members.sort)
+ end
+ end
+ end
+ end
+ end
+
+ def test_rename_with_members_primary
+ make_dummy_user do |user1, password1|
+ make_dummy_user do |user2, password2|
+ make_dummy_group do |group|
+ user1.change_group(group)
+ user2.change_group(group)
+
+ old_cn = group.cn(true)
+ new_cn = "#{old_cn}-new"
+ ensure_delete_group(new_cn) do
+ new_group = @group_class.new(new_cn)
+ assert(!new_group.exists?)
+
+ args = ["--rename", new_cn]
+ assert_asl_groupmod_successfully(group.cn(true), *args)
+
+ old_group = @group_class.new(old_cn)
+ assert(!old_group.exists?)
+ new_group = @group_class.new(new_cn)
+ assert(new_group.exists?)
+
+ assert_equal(new_group.gidNumber, user1.gidNumber)
+ assert_equal(new_group.gidNumber, user2.gidNumber)
+ end
+ end
+ end
+ end
+ end
+
+ def test_gid_number
+ make_dummy_group do |group|
+ old_gid_number = group.gidNumber(true)
+ old_samba_sid = group.sambaSID(true)
+ new_gid_number = old_gid_number.succ
+
+ old_rid = (2 * Integer(old_gid_number) + 1001).to_s
+ new_rid = (2 * Integer(new_gid_number) + 1001).to_s
+ new_samba_sid = old_samba_sid.sub(/#{Regexp.escape(old_rid)}$/, new_rid)
+
+ args = ["--gid", new_gid_number]
+ assert_asl_groupmod_successfully(group.cn(true), *args)
+
+ new_group = @group_class.new(group.cn(true))
+ assert_equal(new_gid_number, new_group.gidNumber(true))
+ assert_equal(new_samba_sid, new_group.sambaSID(true))
+ end
+ end
+
+ def test_gid_number_non_unique
+ make_dummy_group do |group|
+ old_gid_number = group.gidNumber(true)
+ make_