【问题标题】:Need help improving a small C program [closed]需要帮助改进一个小型 C 程序 [关闭]
【发布时间】:2011-09-11 13:13:45
【问题描述】:

我想启动一个 bash 脚本(阅读:bash 不是 sh 脚本)作为 root 而不是用户调用它,但是 bash 忽略脚本上的 setuid,所以我选择编写一个非常小的脚本,它需要一个脚本/参数并使用 setuid set 调用它。

这很好用,我进一步验证脚本是否已设置 setuid、可执行和 setuid() 调用文件的所有者而不是 root,以避免对程序的任何滥用,我最终得到下面的程序..

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>

int main(int argc, char **argv)
{
  char *command;
  int i, file_owner, size = 0;
  struct stat status_buf;
  ushort file_mode;

  // Check argc
  if (argc < 2) {
    printf("Usage: %s <script> [arguments]\n", argv[0]);
    return 1;
  }

  // Make sure the script does exist
  if(fopen(argv[1], "r") == NULL) {
    printf("The file %s does not exist.\n", argv[1]);
    return 1;
  }

  // Get the attributes of the file
  stat(argv[1], &status_buf);

  // Get the permissions of the file
  file_mode = status_buf.st_mode;

  // Make sure it's executable and it's setuid
  if(file_mode >> 6 != 567) {
    printf("The file %s should be executable and should have setuid set, please chmod it 0106755.\n", argv[1]);
    return 1;
  }

  // Get the owner of the script
  file_owner = status_buf.st_uid;

  // setuid
  setuid(file_owner);

  // Generate the command
  for (i = 1; i < argc; i++) {
    size += strlen(argv[i]);
  }
  command = (char *) malloc( (size + argc + 11) * sizeof(char) );
  sprintf(command, "/bin/bash %s", argv[1]);
  if (argc > 2) {
    for (i = 2; i < argc; i++) {
      sprintf(command, "%s %s", command, argv[i]);
    }
  }

  // Execute the command
  system(command);

  // free memory
  free(command);

  return 0;
}

这个练习不仅是为了解决我的问题,也是一种深入了解 C 的方法,那么你们有什么建议呢?有什么需要改进的吗?

谢谢你..

【问题讨论】:

  • 抱歉,这不是代码审查网站。
  • ...codereview.stackexchange.com 是,不过。在那里试试。
  • 现代系统上 bash 和 sh 脚本的确切区​​别是什么?在大多数 Linux 上,sh 只是 bash 的链接/别名。
  • 哦,对不起,我会在那里发布问题......再次抱歉,伙计们
  • 我在codereview上发布了同样的问题codereview.stackexchange.com/questions/2883/…

标签: c bash shell file-permissions setuid


【解决方案1】:
if(file_mode >> 6 != 567) {

幻数不好。请改用S_I* 位掩码。

system(command);

你在 *nix;使用fork()exec*() 将消除之前在循环中执行的大部分杂技。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
  • 2014-08-31
  • 2016-11-24
  • 1970-01-01
  • 2014-09-22
  • 2012-12-21
  • 2011-03-17
相关资源
最近更新 更多