需求分析:

需要注意的是在这里第一次,这个人是不是QT系列文章,它是关于Web的,之所以写这篇文章。这是因为碍着Web相关开发时间,而且往往涉及linux与底层指令处理。例如,创建一个文件夹,删除一个文件夹,或者是运行一个自己定义的脚本。关于PHP怎样调用、运行Linux的底层命令。曾经也研究过,基本上实现了自己须要的功能,可是有些地方一直没有弄明确。今天又偶然碰到了,趁着这个机会向大家描写叙述一下一步一步应该怎样实现,并最后附上相关C代码。

原理实现:

首先,一般搭建的Web网站都是採用Apache或Nginx。因此当使用php运行linux的命令的时候。在linux端体现出的时Apache或Nginx用户的身份来运行的。通常情况下基于安全考虑。Apache或Nginx在linux端的默认用户是不具有非常高的权限的,比方删除、创建等。因此我们必须通过一种方式。为其赋予一定的权限。

在我曾经写过的文章中,我採用了一种方法,即将Apache或Nginx的默认用户改动了,给那个用户赋予了非常高的权限。尽管达到了我的目的,可是恰恰造成了最大的隐患,即:webserver默认用户权限设置过大,非常easy受到来自外界的攻击,甚至不用外界。我自己在php端运行一个命令能将我整个网站删除掉。而在linux端对此基本没有不论什么防御能力。基于此。我们提出一种方式。在linux端不改动webserver默认用户的权限,而是当运行命令时由我们来自己控制这条命令应当具有何种用户的运行权限。或者root用户,或者普通用户全然由我们传递的參数决定。

其次,基于上面的阐述,基本实现思路为:接受php传递来的username和passwd的參数,在linux端新建一个进程。然后将该进程模拟为一个用户的身份。即设置该进程的用户实际、有效的用户ID和用户组ID。然后再运行某条命令,此时运行该命令的过程就好像username用户本身运行那条命令一样。username能运行的有效命令仅仅能在自己的职权范围之内,比方:假设username是普通用户,则它无法通过运行命令删除其它用户或root用户的文件。

这样。在一定程度上实现了安全的可控性。

最后。依据上面提出的改变某个进程的实际、有效用户ID和用户组ID须要用到setuid()和setgid(),而关于这两个函数这里还有须要注意的地方。假设运行它的是特权用户。即root。则它能够随意设置自己的uid和gid。即能够模拟随意用户;而假设运行它的时普通用户,则它仅仅能设置自己的uid和gid,而不能设置为其他用户的,即无法模拟其他用户。为了解决问题就要用到linux的一些特性,即设置文件的用户标记位:s。使文件在运行时具有文件全部者的权限。这样,Apache或Nginx默认用户运行这个文件的时候就类似于该文件的全部者在运行它,而我们利用root用户创建该文件,就相当于root用户在运行该文件。此时setuid和setgid就能够将进程模拟为不论什么用户的身份了。

实现代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pwd.h>
#include <math.h>
#include <time.h>//Usage: exefile   command    work_directory   username    password
int main(int argc, char *argv[])
{char *username = NULL;char *password = NULL;char *command  = NULL;char *workdir = NULL;struct passwd *stpasswd =  NULL;if(argc == 5) {command   = argv[1];workdir    = argv[2];  //work directoryusername  = argv[3];password  = argv[4];       }else{return 1;}//printf("username = %s\n",username);//printf("password = %s\n",password);//printf("workdir = %s\n",workdir);//printf("command = %s\n",command);int result = 0;//auth(username,password);    //Ensure the user is a legel user in the systemif(result == 0)  //auth successfully{    int kidstatus, deadpid;//! fork()克隆出一个全然同样的进程出来;它会复制当前进程的全部变量,就好像一个进程克隆出来还有一个一样//! fork()函数的返回值有三种情况:=0代表克隆出来的那个进程  >0代表“父”进程   <0 运行出错//! 这样的情况一般就是fork出来新的进程。【可选:进行身份切换】,然后利用它来运行execlp(),运行相关的命令pid_t kidpid = fork();if (kidpid == -1) {printf("fork error");return 1;}if (kidpid == 0) {       //! getpwnam():获取用户登录相关的信息//! 头文件:#include <pwd.h> #include <sys/types.h>stpasswd = getpwnam(username);                       //! setgid():设置实际用户组ID和有效用户组ID//! setuid():设置实际用户ID和有效用户ID//! chdir() : 改动当前文件夹//! 注意:假设是一个非特权用户,则它运行setgid和setuid仅仅能设置为自己的gid和uid。而不能设置其他不论什么数值//! 假设是一个特权用户(即:拥有root权限)。则能够利用setgid和setuid设置为随意数值,这也就是为什么终于//! 编译出来的文件要通过:chmod u+s 设置特权位setgid( (int)(stpasswd->pw_gid));   //Set current usergroupsetuid( (int)(stpasswd->pw_uid));   //Set current userchdir(workdir);                                         //change work directory//! int execlp(const char *file, const char *arg, ..., (char *)0);//! execlp()会从PATH环境变量所指的文件夹中查找符合參数file的文件名称,找到后便运行该文件,然后//! 将第二个參数以后的參数当作该文件的argv[0], argv[1] ...,最后一个參数必须用空指针(NULL)结束//! 以下的命令就是:/bin/bash -c command运行int rv = execlp("/bin/bash", "/bin/bash", "-c", command, NULL); fflush(stdout);            return rv;  }//! we only get here if we're the parent process.//! waitpid()堵塞等待子进程结束//! 函数原型:deadpid = waitpid(kidpid, &kidstatus, 0);if (deadpid == -1) {printf("error to fork a process!");return 1;}else{return 0;}}else{printf("Authenticate failed\n");return 1;  }}

最后。利用gcc编译该文件:gcc  test_exec.c  -o  test_exec;编译完毕后为它赋予权限:chmod 777 test_exec。然后设置用户标记位:s, chmod  u+s  test_exec

运行測试:

1. 利用root用户创建一个del_test文件。然后切换到普通用户。測试是否能删除;然后用我们的命令模拟root用户看是否能删除

2. 利用root用户创建一个del_test的文件。切换到zhangsan用户。利用命令模拟lisi用户,看可以删除

通过以上,我们能够看出,利用该命令我们能够模拟不论什么用户的身份。相当于不论什么权限都是由你自己控制,在一定程度上保证了安全性。

总结:

对似懂非懂的知识点一定要明确其原理,不然始终不知道应该怎样来做。

加油!这段时间的网盘开发没有涉及太多挑战性怪东西,预期UDT科研。

版权声明:本文博主原创文章,博客,未经同意不得转载。

转载于:https://www.cnblogs.com/blfshiye/p/4851376.html

【夸QT十一】外来物品:通用脚本帮助Web运行基础Linux命令相关推荐

  1. Linux命令行与shell脚本编程大全学习(linux命令行部分)

    第一章 初识Linux shell 第二章 走进shell 第三章 基本的bash shell命令 cd pwd:显示出shell当前目录 ls -F -R -l *和?和[ ]和[ a - i ]和 ...

  2. 《Linux命令行与shell脚本大全》笔记

    初识Linux Shell 什么是Linux Linux可划分为以下四部分: Linux内核 GNU工具 图形化桌面环境 应用软件 深入探究Linux内核 内核主要负责以下四种功能: 系统内存管理 软 ...

  3. shell脚本编程之使用结构化命令

    技术交流QQ群:1027579432,欢迎你的加入! 本教程使用Linux发行版Centos7.0系统,请您注意~ 1.使用多个命令 shell脚本的关键之处在于输入多个命令并处理每个命令的结果,甚至 ...

  4. Qt Creator建立一个通用项目

    Qt Creator建立一个通用项目 建立一个通用项目 导入通用项目 处理通用项目文件 指定文件 将标志转发到Clang代码模型 提供部署信息 创建运行配置 建立一个通用项目 通用项目支持使您可以将Q ...

  5. linux java启动脚本文件_不错的linux下通用的java程序启动脚本

    #!/bin/sh #该脚本为Linux下启动java程序的通用脚本.即可以作为开机自启动service脚本被调用, #也可以作为启动java程序的独立脚本来使用. # #Author: tudaxi ...

  6. PrimalScript通用脚本环境

    PrimalScript通用脚本环境 PrimalScript是我们世界一流的通用脚本环境(USE)的下一代.作为数据库.系统或web开发人员.网络管理员或最终用户开发人员,您必须同时使用各种语言.技 ...

  7. Windows下Qt打包:bat批处理脚本实现Qt自动打包

    Windows下Qt打包:新建文件夹,放入build下的可执行程序 xxx.exe,在cmd窗口中输入命令: windeployqt xxx.exe,自动抓取依赖库.点击运行exe,会提示还是缺少一些 ...

  8. 《Linux命令行与shell脚本编程大全》(第三版)读书笔记

    第一部分 Linux命令行 第三章.基本的bash shell命令 bash手册 man 命令 例子: man cat 空格翻页.回车下一行.左右键看右侧(左侧)内容.q退出 info info in ...

  9. 【Linux】《Linux命令行与shell脚本编程大全 (第4版) 》笔记-汇总 ( Chapter17-ChapterB )

    十七.创建函数 bash shell 提供了用户自定义函数功能,可以将 shell 脚本代码放入函数中封装起来. 函数是一个脚本代码块,你可以为其命名并在脚本中的任何位置重用它.每当需要在脚本中使用该 ...

最新文章

  1. linux kernel内存映射实例分析
  2. 一步步写一个符合Promise/A+规范的库 1
  3. java 不同数据类型之间的转换
  4. linux内核dentry结构学习
  5. C语言3中方法判断32还是64位机
  6. struct和typedef struct区别
  7. Linux进阶之路————scp指令介绍与演示
  8. 多线程,多进程使用场景
  9. Unity脚本中查找的几种方法优劣以及坑
  10. asa 防火墙拦截了https_Cisco ASA防火墙的URL过滤控制
  11. 心情整天都在郁闷浮云往事如云烟,撕心裂肺:伤感心情日志
  12. 价值170万美元的Flash漏洞 360Vulcan免费提交给Adobe修复
  13. Html移动端红包雨功能页面实现
  14. 陪着时光,走过羊肠阡陌
  15. 百度人脸识别实现方法
  16. 中学物理教学参考杂志社中学物理教学参考编辑部2022第9期目录
  17. 把时间当作朋友——第1章 醒悟
  18. 计算机光盘模式,Win7系统自带光盘刻录功能如何使用?
  19. 【王喆-推荐系统】(task2)用Spark进行特征处理(特征工程篇)
  20. keil 更改黑色背景详细步骤,设置代码风格,添加自动格式化插件

热门文章

  1. Struts2+Spring2.5+Hibernate3.1实现登陆示例
  2. DOM操作表格的各种属性[z]
  3. Python 列表(List)操作方法详解
  4. Android内存溢出分析
  5. 九度 题目1548:平面上的点
  6. youtube根据vedioId获取视频相关信息
  7. 经典PID控制算法用C语言实现!
  8. 贫血模型,充血模型(领域驱动设计)
  9. javaweb:servlet的多线程同步问题
  10. 第九课 特殊权限set_uid、stick_bit,软链接,硬链接