需要帮助改进小型C程序

时间:2011-06-09 09:23:57

标签: c bash shell file-permissions setuid

我想以root用户身份启动一个bash脚本(读取:bash not sh脚本),而不是用户调用它,但是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的方式,所以你们有什么建议?有什么我应该改进的吗?

谢谢..

1 个答案:

答案 0 :(得分:2)

if(file_mode >> 6 != 567) {

魔术数据不好。请改用S_I*位掩码。

system(command);

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