设置Perl脚本的有效组ID

5
我有文件权限问题,希望解决此问题而不必让所有内容都可写。我正在将文件写入NetApp SAN。我要写入的目录由“devel”用户拥有,并具有“devel”组的组可写权限(0775)。我写入的用户名在“username”和“devel”组中。问题似乎是SAN只检查第一个组,因此我被拒绝了权限。如果我使用“newgrp”或“sg”命令将我的组更改为“devel”,那么我就能够写入该目录。尝试进行写入的脚本是用Perl编写的,但它是通过ssh和一些bash脚本从另一台机器远程启动的。我无法将目标目录更改为“username”组,因为还有其他开发人员,他们在不同的组中(但我们都共享“devel”组)。

我不能让Perl脚本本身设置setgid,因为我们在不同的环境(开发、测试、qa、生产等)中运行,具有相应的组,并且我不想在那个级别上管理文件权限位。

我无法在Perl脚本内部使用POSIX的setgid函数,因为它不以root身份启动(而且我永远无法获取root权限),所以我会收到权限被拒绝的错误。将$)$(分配给相应组也会得到相同的结果。

我无法使用bash中的newgrp命令,因为newgrp没有任何参数,它只会启动一个新的交互式shell(在新的shell退出后执行任何后续命令)。

我也无法使用newgrp启动一个新的shell并从那里生成Perl脚本,因为Perl脚本是通过ssh连接在远程机器上执行的。该脚本将在我的默认组下获得远程机器上的“新”shell,而不是通过newgrp在本地机器上设置的组。

我无法使用sg命令,因为它只接受单个参数。我引用完整的命令行,包括已知的参数。然而,我们通过ssh启动远程进程的方式包括在"$@" bash变量中传递本地参数。换句话说,我可以执行process startprocess stop,并且process脚本处理ssh命令,并使用"$@"传递我输入的任何本地参数。我尝试编写一个包装器,但发现我们使用各种有趣的本地参数形式,并且不愿意深入研究必需的引用和转义噩梦。

所以,我的问题是:是否有人知道从Perl或bash设置正在运行的进程的有效组ID的其他方法?sg是否有多参数形式?

1个回答

3
在你的Perl脚本顶部,你不能放置这个吗:
if ( 0+$( != DEVEL_GROUP_ID ) { # primary group isn't devel
  my(@reinvoke) = ($0, map {quotemeta} @ARGV);
  exec('/usr/bin/sg', 'devel', "@reinvoke");
  die("/usr/bin/sg not found!  Can't change group!");
}

也就是说,让Perl来调用sg所需的操作。

你的方法有效。我确实需要稍微修改一下,以便在执行过程中传播自定义环境变量:我在$0之前的@reinvoke中添加了"PERL5LIB=$ENV{PERL5LIB}"(和其他变量)。 - Andrew Barnett
一个你需要小心的事情:首先将变量的值通过 quotemeta 进行转义处理。 - Daniel Martin
我还发现X转发在更改有效组时会出问题。这个系统的一部分是一个perl-Tk GUI,它使用相同的框架代码来运行自己。我不得不编写一个异常来检查Tk代码,并且如果找到了Tk代码则不更改组。 - Andrew Barnett
关于引用变量的问题 - 我们已经有了一个帮助脚本来为框架设置命令行。它用于通过ssh将本地环境传输到远程机器。将其插入本地exec调用非常简单,并且它已经处理了引用环境变量的问题。 - Andrew Barnett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接