1. 程式人生 > >為什麼執行ping命令時不需要root許可權? 怎樣讓程序具有root許可權?

為什麼執行ping命令時不需要root許可權? 怎樣讓程序具有root許可權?

     最近遇到一個問題, 需要讓普通使用者執行程式時具有root許可權, 怎麼辦呢?

     我們來看看ping, 它採用了raw socket, 需要root許可權, 但是, 我們平常執行root命令的時候, 沒有加sudo啊, 來探個究竟:

ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll `which ping`
-rwsr-xr-x 1 root root 44168 May  8  2014 /bin/ping*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 

     可以看到, 可執行程式二進位制檔案ping的owner是root, 且是rws的, 注意這個s

     APUE說:若檔案的所有者是超級使用者,而且設定了該檔案的設定使用者位(suid),然後該程式由一個程序執行時,則該程序具有超級使用者特權。

    所以, 我們來模仿ping的方式。 程式如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <arpa/inet.h>

int main()
{
	printf("main is running\n");

    int iSock, nRead, iProtocol;        
    char buffer[4096] = {0};
    char  *ethhead, *iphead, *tcphead, *udphead, *icmphead, *p;
	
	if((iSock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) < 0)
    {
        printf("create iSocket error, check root\n");  // 需要root許可權
        return 1;
    }
	        
	while(1) 
	{
		nRead = recvfrom(iSock, buffer, 2048, 0, NULL, NULL);  
		/*
			乙太網幀頭 14
			ip頭       20
			udp頭      8
			總共42位元組(最少)
		*/
		if(nRead < 42) 
		{
			printf("packet error\n");
			continue;
		}
	        	
		int n = 0XFF;
		char szVisBuf[1024] = {0};
		for(unsigned int i = 0; i < nRead; ++i)
		{
			char szTmp[3] = {0};
			sprintf(szTmp, "%02x", buffer[i]&n);
			strcat(szVisBuf, szTmp);
		}
			
		
		ethhead = buffer;
		p = ethhead;
		
		iphead = ethhead + 14;  
		p = iphead + 12;

		char szIps[128] = {0};
		snprintf(szIps, sizeof(szIps), "IP: %d.%d.%d.%d => %d.%d.%d.%d",
			p[0]&n, p[1]&n, p[2]&n, p[3]&n,
			p[4]&n, p[5]&n, p[6]&n, p[7]&n);
		iProtocol = (iphead + 9)[0];
		p = iphead + 20;
		
		
		unsigned int iDstPort = (p[2]<<8)&0xff00 | p[3]&n;
		switch(iProtocol)
		{
			case IPPROTO_UDP : 
				if(iDstPort == 8888)
				{
					printf("source port: %u,",(p[0]<<8)&0xff00 |  p[1]&n);
					printf("dest port: %u\n", iDstPort);
					
					printf("%s\n", szIps);	
					printf("%s\n", szVisBuf);
					printf("nRead is %d\n", nRead);	
					
				}
				break;
			case IPPROTO_RAW : 
				printf("raw\n");
				break;
			default:
				break;
		}
	}
}

       再看:

ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ g++ server.cpp 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ./a.out 
main is running
create iSocket error, check root
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll a.out 
-rwxrwxr-x 1 ubuntu ubuntu 9016 Mar  2 22:26 a.out*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ sudo chown root a.out 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ sudo chmod u+s a.out 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll a.out 
-rwsrwxr-x 1 root ubuntu 9016 Mar  2 22:26 a.out*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ./a.out 
main is running

       結果OK, 可見a.out程序具有了root許可權。

       由於程序具有了root許可權, 所以操作的時候, 一定要注意安全問題。