#!/usr/bin/env ruby require 'time' require 'active_samba_ldap' require 'active_samba_ldap/command' include ActiveSambaLdap::GetTextSupport argv, opts, options = ActiveSambaLdap::Command.parse_options do |opts, options| options.ou = nil options.computer_account = false options.uid = nil options.gid = nil options.supplementary_groups = [] options.create_group = true options.home_directory = nil options.home_directory_mode = nil options.shell = nil options.comment = nil options.setup_home_directory = true options.skeleton_directory = nil options.time = 0 options.expire_date = nil options.can_change_password = nil options.must_change_password = nil options.samba_home_unc = nil options.samba_home_drive = nil options.samba_logon_script = nil options.samba_profile_path = nil options.samba_account_flags = nil options.common_name = nil options.given_name = nil options.surname = nil options.mail_addresses = nil options.mail_to_addresses = nil opts.banner += " USER_NAME" opts.on("-o", "--ou=OU", _("add the user in the organizational unit OU"), _("(relative to the user suffix)")) do |ou| if /^ou=/ =~ ou options.ou = ou else options.ou = "ou=#{ou}" end end opts.on("-c", "--[no-]computer-account", _("is a Windows Workstation"), _("(otherwise, Windows user)"), "(#{options.computer_account})") {|options.computer_account|} opts.on("-u", "--uid=UID", Integer, _("uid")) {|options.uid|} 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-]create-group", _("create a group for the user"), "(#{options.create_group})") {|options.create_group|} opts.on("-c", "--comment=COMMENT", _("set the GECOS field for the new user account")) {|options.comment|} opts.on("-s", "--shell=SHELL", _("shell")) {|options.shell|} opts.on("-G", "--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.on("-d", "--home-directory=HOME_DIR", _("home directory")) {|options.home_directory|} opts.on("--home-directory-mode=MODE", _("permission of home directory")) {|options.home_directory_mode|} opts.on("--[no-]setup-home-directory", _("setup home directory"), "(#{options.setup_home_directory})") {|options.setup_home_directory|} opts.on("-k", "--skel=DIR", "--skeleton-directory=DIR", _("skeleton directory")) {|options.skeleton_directory|} opts.on("--time=TIME", Integer, _("wait TIME seconds before exiting"), "(#{options.time})") {|options.time|} 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=UNC", _("sambaHomePath"), _("(SMB home share, like '\\\\PDC\\user'")) do |unc| options.samba_home_unc = unc 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("--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 unless Process.uid.zero? $stderr.puts(_("need root authority.")) exit 1 end ActiveSambaLdap::Base.establish_connection("update") class User < ActiveSambaLdap::User ldap_mapping end class Computer < ActiveSambaLdap::Computer ldap_mapping end class Group < ActiveSambaLdap::Group ldap_mapping end class UnixIdPool < ActiveSambaLdap::UnixIdPool ldap_mapping end if options.computer_account member_class = Computer member_type = _("computer") name = name.chomp("$") + "$" else member_class = User member_type = _("user") end unless member_class.valid_name?(name) $stderr.puts(_("illegal %s name: %s") % [name, member_type]) exit 1 end if member_class.exists?(name) $stderr.puts(_("%s already exists: %s") % [member_type, name]) exit 1 end create_options = { :uid => [name, options.ou].compact.join(","), :uid_number => options.uid, :gid_number => options.gid, :create_group => options.create_group, :group_class => Group, :home_directory => options.home_directory, :login_shell => options.shell, :given_name => options.given_name, :cn => options.common_name, :sn => options.surname, :gecos => options.comment, :samba_acct_flags => options.samba_account_flags, } if !create_options[:cn] and options.given_name and options.surname create_options[:cn] = "#{options.given_name} #{options.surname}" end if options.computer_account create_options[:description] = "Computer" create_options[:gecos] ||= "Computer" else create_options.merge!(:can_change_password => options.can_change_password, :must_change_password => options.must_change_password, :user_logon_script => options.samba_logon_script, :user_home_unc => options.samba_home_unc, :user_home_drive => options.samba_home_drive, :user_profile => options.samba_profile_path) if options.expire_date create_options[:samba_kickoff_time] = options.expire_date.to_i.to_s end end member = nil begin member = member_class.create(create_options) rescue ActiveSambaLdap::UidNumberAlreadyExists $stderr.puts(_("UID already exists: %s") % uid_number) exit 1 rescue ActiveSambaLdap::GidNumberDoesNotExist, ActiveSambaLdap::GroupDoesNotExist, ActiveSambaLdap::GroupDoesNotHaveSambaSID $stderr.puts $! exit 1 end unless member.errors.empty? member.errors.each_full do |message| $stderr.puts(message) end exit 1 end if options.setup_home_directory begin setup_options = { :mode => options.home_directory_mode, :skeleton_directory => options.skeleton_directory, } member.setup_home_directory(setup_options) rescue SystemCallError $stderr.puts $! exit 1 end end [member.gid_number, *options.supplementary_groups].each do |group| group = Group.find_by_name_or_gid_number(group) if options.computer_account group.computers << member else group.users << member end end ActiveSambaLdap::Base.restart_nscd ActiveSambaLdap::Base.clear_active_connections!