如何通过多个 sudo 和 su 命令找到原始用户?

2024-10-24 08:50:00
admin
原创
254
摘要:问题描述:当通过 sudo 或 su 运行脚本时,我想获取原始用户。无论多个sudo或su彼此内部运行,特别是,这都应该发生sudo su -。解决方案 1:结果:使用who am i | awk '{print $1}'OR,logname因为没有其他方法可以保证。以自我...

问题描述:

当通过 sudo 或 su 运行脚本时,我想获取原始用户。无论多个sudosu彼此内部运行,特别是,这都应该发生sudo su -


解决方案 1:

结果:

使用who am i | awk '{print $1}'OR,logname因为没有其他方法可以保证。

以自我身份登录:

evan> echo $USER
evan
evan> echo $SUDO_USER

evan> echo $LOGNAME
evan
evan> whoami
evan
evan> who am i | awk '{print $1}'
evan
evan> logname
evan
evan>

正常 sudo:

evan> sudo -s
root> echo $USER
root
root> echo $SUDO_USER
evan
root> echo $LOGNAME
root
root> whoami
root
root> who am i | awk '{print $1}'
evan
root> logname
evan
root>

sudo su-:

evan> sudo su -
[root ]# echo $USER
root
[root ]# echo $SUDO_USER

[root ]# echo $LOGNAME
root
[root ]# whoami
root
[root ]# who am i | awk '{print $1}'
evan
[root ]# logname
evan
[root ]#

sudo su -; su tom :

evan> sudo su -
[root ]# su tom
tom$ echo $USER
tom
tom$ echo $SUDO_USER

tom$ echo $LOGNAME
tom
tom$ whoami
tom
tom$ who am i | awk '{print $1}'
evan
tom$ logname
evan
tom$

解决方案 2:

没有完美的答案。更改用户 ID 时,通常不会保留原始用户 ID,因此信息会丢失。某些程序(例如logname和)who -m实施了一种黑客攻击,它们会检查哪个终端连接到stdin,然后检查哪个用户登录了该终端。

这种解决方案通常有效,但并非万无一失,当然不应被视为安全。例如,想象一下如果who输出以下内容:

tom     pts/0        2011-07-03 19:18 (1.2.3.4)
joe     pts/1        2011-07-03 19:10 (5.6.7.8)

tom用于su获取 root 权限,并运行您的程序。如果STDIN没有重定向,则类似这样的程序logname将输出tom。如果它被重定向(例如从文件重定向),如下所示:

logname < /some/file

那么结果就是“ no login name”,因为输入不是终端。不过,更有趣的是,用户可以冒充其他登录用户。由于 Joe 登录的是 pts/1,Tom 可以通过运行以下命令假装是 Joe:

logname < /dev/pts1

现在,它表示,joe尽管 tom 是运行该命令的人。换句话说,如果你在任何类型的安全角色中使用这种机制,那你就疯了。

解决方案 3:

这是ksh我在 HP-UX 上编写的一个函数。我不知道它Bash在 Linux 中会如何工作。其思路是,进程sudo以原始用户身份运行,子进程是目标用户。通过循环返回父进程,我们可以找到原始进程的用户。

#
# The options of ps require UNIX_STD=2003.  I am setting it
# in a subshell to avoid having it pollute the parent's namespace.
#
function findUser
{
    thisPID=$$
    origUser=$(whoami)
    thisUser=$origUser
    while [ "$thisUser" = "$origUser" ]
    do
        ( export UNIX_STD=2003; ps -p$thisPID -ouser,ppid,pid,comm ) | grep $thisPID | read thisUser myPPid myPid myComm
        thisPID=$myPPid
    done
    if [ "$thisUser" = "root" ]
    then
        thisUser=$origUser
    fi
    if [ "$#" -gt "0" ]
    then
        echo $origUser--$thisUser--$myComm
    else
        echo $thisUser
    fi
    return 0
}

我知道最初的问题是很久以前的,但人们(比如我)仍在询问,这看起来是一个提出解决方案的好地方。

解决方案 4:

如果我们可以将进程生成层次结构排列成一棵树,那么我们就可以在该树的根部查找生成该进程的用户。幸运的是,该pstree命令为我们完成了这一安排。

pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1 | sed 's/[()]//g'

pstree将正在运行的进程显示为一棵树。树的根是 pid,这里给出为$$,在 bash 中,它将扩展为当前 shell 的进程 id。因此,该命令的第一部分列出了当前 shell 的所有祖先进程,格式有些奇怪。该命令的其余部分将丢弃这种奇怪的格式,以选出拥有最古老祖先进程的用户的名称。

与其他基于的答案相比,这里的主要改进pstree是输出中不包含多余的括号。

解决方案 5:

如何使用 logname(1) 获取用户的登录名?

解决方案 6:

在运行 的系统上systemd-logind,systemd API 提供了此信息。如果您想从 shell 脚本访问此信息,需要使用类似这样的脚本:

$ loginctl session-status \n  | (read session_id ignored; loginctl show-session -p User $session_id)
User=1000

session-status和 的show-ssession系统命令在loginctl没有参数的情况下有不同的行为:session-status使用当前会话,但show-ssession使用管理器。但是,使用show-session更适合脚本使用,因为它具有机器可读的输出。这就是为什么loginctl需要两次调用 的原因。

解决方案 7:

user1683793 的 findUser() 函数被移植bash并扩展,因此它也能返回存储在 NSS 库中的用户名。

#!/bin/bash

function findUser() {
    thisPID=$$
    origUser=$(whoami)
    thisUser=$origUser

    while [ "$thisUser" = "$origUser" ]
    do
        ARR=($(ps h -p$thisPID -ouser,ppid;))
        thisUser="${ARR[0]}"
        myPPid="${ARR[1]}"
        thisPID=$myPPid
    done

    getent passwd "$thisUser" | cut -d: -f1
}

user=$(findUser)
echo "logged in: $user"

解决方案 8:

返回并提供用户列表

根据用户 1683793 的回答

通过排除非 TTY 进程,我跳过了 root 作为登录发起者。我不确定在某些情况下这是否会排除太多

#!/bin/ksh
function findUserList
{
    typeset userList prevUser thisPID thisUser myPPid myPid myTTY myComm
    thisPID=$$                 # starting with this process-ID
    while [ "$thisPID" != 1 ]  # and cycling back to the origin
    do
        (  ps -p$thisPID -ouser,ppid,pid,tty,comm ) | grep $thisPID | read thisUser myPPid myPid myTTY myComm
        thisPID=$myPPid
        [[ $myComm =~ ^su ]] && continue        # su is always run by root -> skip it
        [[ $myTTY == '?' ]] && continue         # skip what is running somewhere in the background (without a terminal)
        if [[ $prevUser != $thisUser ]]; then   # we only want the change of user
                prevUser="$thisUser"            # keep the user for comparing
                userList="${userList:+$userList }$thisUser"  # and add the new user to the list
        fi
        #print "$thisPID=$thisUser: $userList -> $thisUser -> $myComm " >&2
    done
    print "$userList"
    return 0
}

logname或者who am i没有给我想要的答案,特别是在较长的列表中su user1,,,su user2`su user3`...

我知道最初的问题是很久以前的,但人们(比如我)仍在询问,这看起来是一个提出解决方案的好地方。

解决方案 9:

多次调用 ps 的替代方法:执行一次 pstree 调用

pstree -lu -s $$ | grep --max-count=1 -o '([^)]*)' | head -n 1

输出(以偶数身份登录时):(evan)

pstree 参数:

  • -l:长行(不缩短)

  • -u:显示用户何时更改为(用户名)

  • -s $$:显示此进程的父进程

grep -o使用和获取第一个用户变更(即登录)head

限制:命令可能不包含任何括号()(通常不包含)

解决方案 10:

您可以从控制终端的所有者处获取它。这是“whowasi”实用程序的旧 C 代码: http: //sivann.gr/software/whowasi.c

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2579  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1553  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   27  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   22  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   19  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用