一、最近在搞虚拟机,前端通过PHP发送命令过来,PHP通过proc_open进行与本地的C程序通信(PHP即发送参数给C程序,程序在后台运行)。C程序实现开启虚拟机、关闭虚拟机等操作。但是在执行的时候出现了问题,首先是PHP传递过来参数C程序启动后,无法在后台驻留执行,而是一闪而过,经大神指点,查找原因是因为C程序的权限问题。一般我们是在ROOT全下下编译程序,所以程序的权限是-RWXR-XR-X,PHP调用C程序是以apache的身份调用,我这里的身份是www-data用户作为apache用户来调用,所以在权限上有限制。
解决方法:1.首先我修改了C程序的文件权限。chmod777发现无效。原因不祥。
2.大神指点,要修改程序临时运行的权限,换句话说让www-data用户在执行C程序的时候是以ROOT权限去执行的,这样就可以了。采用chmod 4777 程序名 即可。
下边是一些关于 chmod u+s的说明:(摘自鸟哥)
文件的特殊权限SUID:设置后在相应的执行位(X位)上显示S。
基本的SUID有这样的权限和功能:
1.SUID 权限仅对二进制其程序有效
2.执行者对于改程序需要具有X的可执行权限
3本权限尽在执行该程序的过程中有效
4 执行者酱油该程序的所有者权限。
举例来说,LINUX系统中,所有帐号密码都是记录在/etc/shadow中,这个文件的访问权限为“-R------ root root ”,意思是这个文件仅有ROOT可读,且仅有ROOT可以强制写入,但我们发现我们以普通用户身份登录LINUX系统中时候,我们输入"passwd"命令看,一般用户也可以修改自己的密码。为什么普通用户还可以访问只有ROOT才可以访问的文件呢,这个就是因为SUID的功能了,普通用户对于passwd程序是可执行的具有X权限,而passwd的拥有者是root,普通用户在执行passwd的过程中会暂时获得ROOT权限,这样就是原理了。
我们就是要借助这个功能来实现我们的PHP调用C的过程中,以ROOT权限去执行C程序。
二、就是与虚拟机通信执行开关机命令是通过虚拟机自动生成的UNIX SOCKET本地文件进行通信,每次生成文件的时候,权限都会改变,所以在执行和虚拟机通信的相关程序下都要使用SUID的方式来运行,不然会出现通信失败,即因为C程序没有足够权限访问本地UNIX SOCKET文件,造成通信失败,也可以获取connect失败的错误代码,在errno中获取,再对照一下。进行错误定位。