#!/usr/bin/env ruby require 'time' require 'fileutils' require 'active_samba_ldap' require 'active_samba_ldap/command' include ActiveSambaLdap::GetTextSupport argv, opts, options = ActiveSambaLdap::Command.parse_options do |opts, options| options.computer_account = false options.gecos = nil options.home_directory = nil options.move_home_directory = false # options.inactive_days = nil options.new_user_name = nil options.uid = nil options.allow_non_unique_uid_number = false options.gid = nil options.merge_groups = true options.supplementary_groups = nil options.shell = nil options.given_name = nil options.common_name = nil options.surname = nil options.expire_date = nil options.can_change_password = nil options.must_change_password = nil options.samba_home_path = nil options.samba_home_drive = nil options.samba_logon_script = nil options.samba_profile_path = nil options.samba_account_flags = nil options.enable = nil options.mail_addresses = nil options.mail_to_addresses = nil opts.banner += " USER_NAME" opts.on("-c", "--[no-]computer-account", _("is a Windows Workstation"), _("(otherwise, Windows user)"), "(#{options.computer_account})") {|options.computer_account|} opts.on("--gecos=GECOS", _("gecos")) {|options.gecos|} opts.on("-d", "--home-directory=HOME_DIR", _("home directory")) {|options.home_directory|} opts.on("-m", "--[no-]move-home-directory", _("move home directory"), "(#{options.move_home_directory})") do |bool| options.move_home_directory = bool end opts.on("-r", "--rename=NEW_NAME", _("new user name (cn and dn are updated)")) do |name| options.new_user_name = name end opts.on("-u", "--uid=UID", Integer, _("uid")) {|options.uid|} opts.on("--[no-]allow-non-unique-uid", _("uid can be non unique "), "(#{options.allow_non_unique_uid_number})") do |bool| options.allow_non_unique_uid_number = bool end opts.on("-g", "--gid=GID", "gid") {|options.gid|} opts.on("-G", "--groups=GID1,GID2,GID3", Array, _("supplementary groups (comma separated)")) do |groups| options.supplementary_groups = groups end opts.on("--[no-]merge-groups", _("replace supplementary groups "), "(#{!options.merge_groups})") {|options.merge_groups|} opts.on("-s", "--shell=SHELL", _("shell")) {|options.shell|} opts.on("--given-name=NAME", _("given name")) {|options.given_name|} opts.on("-N", "--common-name=NAME", _("common name")) {|options.common_name|} opts.on("-S", "--surname=NAME", _("surname")) {|options.surname|} opts.separator("") opts.separator(_("For samba accounts:")) opts.on("-e", "--expire-date=DATE", _("expire date")) do |date| options.expire_date = Time.parse(date) end opts.on("-C", "--[no-]can-change-password", _("can change password")) do |bool| options.can_change_password = bool end opts.on("-M", "--[no-]must-change-password", _("must change password")) do |bool| options.must_change_password = bool end opts.on("--samba-home-path=PATH", _("sambaHomePath"), _("(SMB home share, like '\\\\PDC\\user'")) do |path| options.samba_home_path = path end opts.on("--samba-home-drive=DRIVE", _("sambaHomeDrive"), _("(letter associated with home share, like 'H:')")) do |drive| options.samba_home_drive = drive end opts.on("--samba-logon-script=SCRIPT", _("sambaLogonScript"), _("(DOS script to execute on login)")) do |script| options.samba_logon_script = script end opts.on("--samba-profile-path=PATH", _("sambaProfilePath"), _("(profile directory, " \ "like '\\\\PDC\\profiles\\user')")) do |path| options.samba_profile_path = path end opts.on("--samba-account-flags=FLAGS", _("sambaAcctFlags"), _("(samba account control bits, " \ "like '[NDHTUMWSLXI]')")) {|options.samba_account_flags|} opts.on("-D", "--[no-]disable-user", _("disable this user")) do |bool| options.enable = !bool end opts.on("-E", "--[no-]enable-user", _("enable this user")) do |bool| options.enable = bool end # opts.on("--mail-addresses=ADDRESS1,ADDRESS2,ADDRESS3", # Array, # _("mailAddresses (comma separated)")) {|options.mail_addresses|} # opts.on("--mail-to-addresses=ADDRESS1,ADDRESS2,ADDRESS3", # Array, # _("mailToAddresses (forward address)"), # _("(comma separated)")) do |addresses| # options.mail_to_addresses = addresses # end end name = nil if argv.size == 1 name = argv.first else $stderr.puts opts exit 1 end ActiveSambaLdap::Base.setup_connection("update") class User < ActiveSambaLdap::User ldap_mapping end class Computer < ActiveSambaLdap::Computer ldap_mapping end class Group < ActiveSambaLdap::Group ldap_mapping end options.computer_account = true if /\$$/ =~ name if options.computer_account member_class = Computer member_type = _("computer") name = name.chomp("$") + "$" else member_class = User member_type = _("user") end unless member_class.exists?(name) $stderr.puts(_("%s doesn't exist: %s") % [member_type, name]) exit 1 end member = member_class.find(name) unless Process.uid.zero? password = ActiveSambaLdap::Command.read_password(_("Enter your password: ")) begin member.bind(password) rescue ActiveLdap::AuthenticationError $stderr.puts(_("password doesn't match.")) exit 1 end member.remove_connection end if options.uid begin member.change_uid_number(options.uid, options.allow_non_unique_uid_number) rescue ActiveSambaLdap::UidNumberAlreadyExists $stderr.puts $!.message exit 1 end end if options.gid begin member.primary_group = Group.find_by_name_or_gid_number(options.gid) rescue ActiveSambaLdap::Error $stderr.puts $!.message exit 1 end end if options.shell member.login_shell = options.shell end if options.gecos member.gecos = options.gecos member.description = options.gecos member.display_name = options.gecos end if options.home_directory if options.move_home_directory and !File.exist?(options.home_directory) FileUtils.mv(member.home_directory, options.home_directory) end member.home_directory = options.home_directory end if options.common_name member.cn = options.common_name end if options.surname member.sn = options.surname end if options.given_name member.given_name = options.given_name end if options.mail_addresses raise _("not implemented.") end if options.mail_to_addresses raise _("not implemented.") end if options.supplementary_groups member.groups = [] unless options.merge_groups member.groups = options.supplementary_groups.collect do |group| begin Group.find_by_name_or_gid_number(group) rescue ActiveSambaLdap::GidNumberDoesNotExist $stderr.puts $! exit 1 end end end if options.expire_date member.samba_kickoff_time = options.expire_date.to_i.to_s end if options.samba_account_flags member.samba_acct_flags = options.samba_account_flags end unless options.can_change_password.nil? if options.can_change_password member.enable_password_change else member.disable_password_change end end unless options.must_change_password.nil? if options.must_change_password member.enable_forcing_password_change else member.disable_forcing_password_change end end if options.samba_home_path member.samba_home_path = options.samba_home_path end if options.samba_home_drive member.samba_home_drive = options.samba_home_drive.sub(/([^:])$/, "\\1:") end if options.samba_logon_script member.samba_logon_script = options.samba_logon_script end if options.samba_profile_path member.samba_profile_path = options.samba_profile_path end unless options.enable.nil? if options.enable member.enable else member.disable end end member.save! if options.new_user_name if options.computer_account options.new_user_name = options.new_user_name.chomp("$") + "$" end if member_class.exists?(options.new_user_name) format = _("%s already exists: %s") $stderr.puts(format % [member_type, options.new_user_name]) exit 1 end new_member = member_class.new(options.new_user_name) new_member.cn = options.new_user_name new_member.attributes = member.attributes.reject do |key, value| %w(dn cn uid).include?(key) end new_member.save! member.groups.each do |group| if options.computer_account group.computers -= [member] group.computers << new_member else group.users -= [member] group.users << new_member end end member.destroy end ActiveSambaLdap::Base.restart_nscd ActiveSambaLdap::Base.clear_active_connections!