需求分析:

需要注意的是在这里第一次,这个人是不是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 directory
username = 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 system if(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 usergroup
setuid( (int)(stpasswd->pw_uid)); //Set current user
chdir(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用户看是否能删除

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaG91cWQyMDEy/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

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

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

总结:

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

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

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

【夸QT十一】外来物品:通用脚本帮助Web运行基础Linux命令的更多相关文章

  1. 万能脚本助Web执行底层Linux命令

    需求分析: 这里先要说明的是,这一篇不是QT系列的文章,而是关于Web的,之所以要写这篇,是因为以前做Web相关开发的时候,经常涉及到与linux底层命令打交道,比如说创建一个目录,删除一个目录,或者 ...

  2. 吻逗死(windows)系统下自动部署脚本(for java spring*)及linux命令行工具

    转载请注明出处:https://www.cnblogs.com/funnyzpc/p/10051647.html (^^)(^^)自動部署腳本原本在上個公司就在使用,由於近期同事需要手動部署一個Spr ...

  3. 一个shell脚本,让你的linux命令行酷炫起来

    可调用如下函数达到echo出来带颜色的文字.._echo_error() { echo -ne "\033[31;1m $1\033[0m\n";}_echo_ok() { ech ...

  4. 《Linux命令行与shell脚本编程大全》第十一章 构建基本脚本

    11.1使用多个命令 $date;who   //  命令列表,加入分号就可以,这样会依次执行.参见5.2.1节 注意区分$(date;who),这个是进程列表,会生成一个子shell来执行 Shel ...

  5. Linux上java程序的jar包启动通用脚本(稳定用过)

    Linux上java程序的jar包启动通用脚本如下: #! /bin/sh export LANG="zh_CN.GBK" SERVICE_NAME=` .sh` SCRIPT_N ...

  6. sql server编写通用脚本自动检查两个不同服务器的新旧数据库的表结构差异

    问题:工作过程中,不管是什么项目,伴随着项目不断升级版本,对应的项目数据库业务版本也不断升级,数据库出现新增表.修改表.删除表.新增字段.修改字段.删除字段等变化,如果人工检查,数据库表和字段比较多的 ...

  7. sql server编写通用脚本自动统计各表数据量心得

    工作过程中,如果一个数据库的表比较多,手工编写统计脚本就会比较繁琐,于是摸索出自动生成各表统计数据量脚本的通用方法,直接上代码: /* 脚本来源:https://www.cnblogs.com/zha ...

  8. Qt容器类之三:通用算法

    在<QtAlgorithm>头文件中,Qt提供了一些全局的模板函数,这些函数是可以使用在容器上的十分常用的算法.我们可以在任何提供了STL风格迭代器的容器类上用这些算法,包括QList.Q ...

  9. Linux下shell通用脚本启动jar(微服务)

    Linux下shell通用脚本启动jar(微服务) vim app_jar.sh #!/bin/bash #source /etc/profile # Auth:Liucx # Please chan ...

随机推荐

  1. NET5

    ASP.NET5(RC1) - 翻译 前言 ASP.NET 5 是一次令人惊叹的对于ASP.NET的创新革命. 他将构建目标瞄准了 .NET Core CLR, 同时ASP.NET又是对于云服务进行优 ...

  2. SilkTest Q&A 4

    Q31.如何在inc文件里面写函数? A31.在你在inc文件(例如demo.inc)里写好函数以后,你需要使用Use path/Use file来指定指定它们. 在SilkTest中->Opt ...

  3. 产生n不同随机数的算法

    昨天无聊,就模仿仙剑5外传中的卡牌游戏做了一个小游戏,结果在开发这个小游戏的时候,碰到了产生多个不同随机数的问题.我们知道,仙剑中的卡牌游戏是随机产生16张图片,并且这16张图片是两个一组的,因为只有 ...

  4. hibernate学习(二)

    hibernate 单向一对多映射 一.数据表设计 数据库名:hibernate5 数据表: ①表名:CUSTOMERS 字段: CUSTOMER_ID  CUSTOMER_NAME ②表名:ORDE ...

  5. 玩转Windows服务系列——命令行管理Windows服务

    原文:玩转Windows服务系列——命令行管理Windows服务 说到Windows服务的管理就不得不说通过命令行的方式管理Windows服务,因为无论是系统管理员,还是通过编程的方式调用cmd命令, ...

  6. STM32M CUBE实现printf打印调试信息以及实现单字节接收

    在写单片机程序时我们一般喜欢使用printf来通过串口打印调试信息,但这个函数是不能够直接使用的.必须做点对库函数的修改. 具体project下载地址: http://download.csdn.ne ...

  7. python爬行动物集合360联想词搜索

    想法和一些代码引用邸一幕python培训黄哥python爬虫联想词视频,但是太罗嗦.顺便整理,而到现在为止,360不傻.它已演变,用原来的方式,有些bug,这接着说. 正题例如以下: 语言:pytho ...

  8. 【iOS】Swift字符串截取方法的改进

    字符串截取方法是字符串处理中经常使用的基本方法.熟悉iOS的朋友都知道在基础类的NSString中有substringToIndex:,substringFromIndex:以及substringWi ...

  9. linux下安装QT过程

    说QT是linux下主要的图形开发工具一点都不过分,虽然诺基亚公司放弃Meego.遣散了Qt开发团队,但是它的各种商业.企业版本还是的到了很好的保护,linux下的开发工具集里还是经常看到它的身影,毕 ...

  10. [Cocos2d-x]随机数

    Cocos2d-x为我们提供了生成随机数的宏:CCRANDOM_0_1() 具体定义如下: /** @def CCRANDOM_0_1 returns a random float between 0 ...