def run(options)
      @log_sink = StringIO.new
      @log = Logger.new(@log_sink)
      RightScale::Log.force_logger(@log)
      check_privileges if right_agent_running?

      username  = options.delete(:username)
      email     = options.delete(:email)
      uuid      = options.delete(:uuid)
      superuser = options.delete(:superuser)
      profile   = options.delete(:profile)
      force     = options.delete(:force)

      fail(1) if missing_argument(username, "USERNAME") || missing_argument(email, "EMAIL") || missing_argument(uuid, "UUID")

      # Fetch some information about the client's intentions and origin
      orig = ENV['SSH2_ORIGINAL_COMMAND'] || ENV['SSH_ORIGINAL_COMMAND']
      client_ip = ENV['SSH_CLIENT'].split(/\s+/).first if ENV.has_key?('SSH_CLIENT')


      if orig =~ SCP_COMMAND
        access = :scp
      elsif orig =~ SFTP_COMMAND
        access = :sftp
      elsif (orig != nil) && (!orig.empty?)
        access = :command
      else
        access = :shell
      end

      # Create user just-in-time; idempotent if user already exists
      # Note that username == chosen here, they just get used in two different contexts
      username = LoginUserManager.create_user(username, uuid, superuser ? true : false) do |chosen|
          puts "Creating your user profile (#{chosen}) on this machine." if (:shell == access)
      end

      create_audit_entry(email, username, access, orig, client_ip) if right_agent_running?
      chown_tty(username)

      # Note that when execing sudo we use the N-argument form of Kernel.exec,
      # which does not invoke a shell, but rather directly invokes the command specified
      # by argv[0] and uses argv[1..N] as the command line. This protects us against shell
      # escape characters and other badness.
      #
      # Unfortunately, this means that file globs and other 'useful' shell escape characters
      # do not get parsed.
      #
      # As a workaround, for non-interactive access types, we tell sudo to invoke a shell and
      # use the shell's '-c' argument to specify the command to run. We also use the -H
      # argument to sudo, which forces it to set HOME to the user's homedir. We attempt to
      # set some other environment variables to make the user feel more at home, but we
      # are at the mercy of sudo.
      #
      # For interactive logins, we don't need to perform any trickiness since our goal is
      # simply to get the user into a shell, with no command line args to parse.
      case access
      when :scp, :sftp, :command
        LoginUserManager.simulate_login(username)
        Kernel.exec('sudo', '-H', '-u', username, '/bin/sh', '-c', "cd $HOME ; #{orig}")
      when :shell
        if right_agent_running?
          display_motd
        else
          display_right_link_is_not_running_warning
        end
        Kernel.exec('sudo', '-i', '-u', username)
      end
    rescue SystemExit => e
      raise e
    rescue Exception => e
      fail(e)
    end
def run(options)
      @log_sink = StringIO.new
      @log = Logger.new(@log_sink)
      RightScale::Log.force_logger(@log)
      check_privileges if right_agent_running?

      username  = options.delete(:username)
      email     = options.delete(:email)
      uuid      = options.delete(:uuid)
      superuser = options.delete(:superuser)
      profile   = options.delete(:profile)
      force     = options.delete(:force)

      fail(1) if missing_argument(username, "USERNAME") || missing_argument(email, "EMAIL") || missing_argument(uuid, "UUID")

      # Fetch some information about the client's intentions and origin
      orig = ENV['SSH2_ORIGINAL_COMMAND'] || ENV['SSH_ORIGINAL_COMMAND']
      client_ip = ENV['SSH_CLIENT'].split(/\s+/).first if ENV.has_key?('SSH_CLIENT')


      if orig =~ SCP_COMMAND
        access = :scp
      elsif orig =~ SFTP_COMMAND
        access = :sftp
      elsif (orig != nil) && (!orig.empty?)
        access = :command
      else
        access = :shell
      end

      # Create user just-in-time; idempotent if user already exists
      # Note that username == chosen here, they just get used in two different contexts
      username = LoginUserManager.create_user(username, uuid, superuser ? true : false) do |chosen|
          puts "Creating your user profile (#{chosen}) on this machine." if (:shell == access)
      end

      create_audit_entry(email, username, access, orig, client_ip) if right_agent_running?
      chown_tty(username)

      # Note that when execing sudo we use the N-argument form of Kernel.exec,
      # which does not invoke a shell, but rather directly invokes the command specified
      # by argv[0] and uses argv[1..N] as the command line. This protects us against shell
      # escape characters and other badness.
      #
      # Unfortunately, this means that file globs and other 'useful' shell escape characters
      # do not get parsed.
      #
      # As a workaround, for non-interactive access types, we tell sudo to invoke a shell and
      # use the shell's '-c' argument to specify the command to run. We also use the -H
      # argument to sudo, which forces it to set HOME to the user's homedir. We attempt to
      # set some other environment variables to make the user feel more at home, but we
      # are at the mercy of sudo.
      #
      # For interactive logins, we don't need to perform any trickiness since our goal is
      # simply to get the user into a shell, with no command line args to parse.
      case access
      when :scp, :sftp, :command
        LoginUserManager.simulate_login(username)
        Kernel.exec('sudo', '-H', '-u', username, '/bin/sh', '-c', "cd $HOME ; #{orig}")
      when :shell
        if right_agent_running?
          display_motd
        else
          display_right_link_is_not_running_warning
        end
        Kernel.exec('sudo', '-i', '-u', username)
      end
    rescue SystemExit => e
      raise e
    rescue Exception => e
      fail(e)
    end
best-effort auditing, but try not to block user
 Manage individual user SSH logins

 === Parameters
 options(Hash):: Hash of options as defined in +parse_args+

 === Return
 true:: Always return true