-
-
[原创]如果你的php程序要在服务器上进行一些高权限的操作咋办?来吧我教你用管到
-
发表于: 2016-5-25 20:55 4506
-
php跟管道通信网上很少有,我探索了好几天
很多时候php需要在服务器上进行一些高权限的操作,比如网站后台管理启动停止Mysql服务,
显然这是很难用exec之类的函数实现的?而即使实现了,也很危险,容易被别人利用,因为exec它不知道你到底要做啥动作,那些命令都是字符串,不可能一个个排除。
这时你就得在服务器上运行一个管理员权限的程序,该程序建个管道,而php就跟该管道通信.
先看exe程序的源码,g_DataBuf是通信的数据,很重要
#include "stdafx.h"
#pragma warning(push)
#pragma warning(disable:4996)
#include<stdio.h>
#include <conio.h>
#include <stdlib.h>
#include<windows.h>
#define PIPE_SIZE 1024
LPTSTR g_pPipeName = L"\\\\.\\pipe\\phphelper";
char g_DataBuf[PIPE_SIZE]={0};//第一个字节为具体操作,第二个字节为0表示还有操作不能断开,为其他值表示当前可以断开连接
BOOL ProcCmd(HANDLE hpipe,char *pData);
//本程序为webserver上帮助php去执行一些权限操作的客户端。webserverhelp_S对应的服务端,执行本程序的命令
int _tmain(int argc, _TCHAR* argv[])//命令字符不超过8个
{
HANDLE hPipe;
PSECURITY_DESCRIPTOR psd;
BOOL fConnected;
DWORD dwRead;
psd = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
if(!psd)return -1;
if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
{
LocalFree((HLOCAL)psd);
return -1;
}
if (!SetSecurityDescriptorDacl(psd, TRUE, (PACL)NULL, FALSE))
{
LocalFree((HLOCAL)psd);
return -1;
}
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength =sizeof(SECURITY_ATTRIBUTES);
saAttr.lpSecurityDescriptor = psd;
saAttr.bInheritHandle = TRUE;
hPipe=CreateNamedPipe(g_pPipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
1, PIPE_SIZE, PIPE_SIZE, 1000, &saAttr);
LocalFree((HLOCAL)psd);
if (hPipe == INVALID_HANDLE_VALUE)
{
return -1;
}
fConnected=FALSE;
while(1)
{
if(_kbhit())//ESC退出
{
char ch;
ch=getch();
if(ch==27)break;
}
if(!fConnected)fConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (fConnected)
{
if(ReadFile(hPipe, g_DataBuf, PIPE_SIZE, &dwRead, 0))
{
ProcCmd(hPipe,g_DataBuf) ;
if(g_DataBuf[1]){DisconnectNamedPipe(hPipe);fConnected=FALSE;}
}
else DisconnectNamedPipe(hPipe);
}
else Sleep(200);//等0.1s
}
CloseHandle(hPipe);
return 0;
}
BOOL StopMysql()
{
char *pCmd="net stop mysql";
int reslt;
reslt=system(pCmd);
if(reslt==0)return true;
else return false;
}
BOOL StartMysql()
{
char *pCmd="net start mysql";
int reslt;
reslt=system(pCmd);
if(reslt==0)return true;
else return false;
}
BOOL ProcCmd(HANDLE hpipe,char *pData)
{
BOOL result;
DWORD cbWritten;
switch(pData[0])
{
case 1:
result=StopMysql();
break;
case 2:
result=StartMysql();
break;
default:
result=true;
break;
}
WriteFile(hpipe, (PVOID)&result, 1 ,&cbWritten,NULL);
FlushFileBuffers(hpipe);
return result;
}
#pragma warning(pop)
再看php这边的
$pipe =@fopen("//./pipe/phphelper", 'r+');
if($pipe==false)
{
$retdata[1]='打开管道失败';
return $retdata;
}
@fwrite($pipe,"\x1\x0");//stop
$datapp=@fread($pipe,1);
if($datapp!="\x1")
{
fclose($pipe);
$retdata[1]='停止Mysql服务失败';
return $retdata;
}
停止后进行其他操作
@fwrite($pipe,"\x2\x1");//start
$datapp=@fread($pipe,1);
if($datapp!="\x1")
{
fclose($pipe);
$retdata[1]='重启Mysql服务失败';
return $retdata;
}
fclose($pipe);
转载请注名幽叶无情
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课