capset 和capget 分别用来设置和获取进程权限:
int capget(cap_user_header_t hdrp, cap_user_data_t datap);
int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
相关的宏和数据结构
#define _LINUX_CAPABILITY_VERSION_1 0x19980330
#define _LINUX_CAPABILITY_U32S_1 1
#define _LINUX_CAPABILITY_VERSION_2 0x20071026
#define _LINUX_CAPABILITY_U32S_2 2
typedef struct __user_cap_header_struct {
__u32 version;
int pid;
} *cap_user_header_t;
typedef struct __user_cap_data_struct {
__u32 effective;
__u32 permitted;
__u32 inheritable;
} *cap_user_data_t;
例子:
#undef _POSIX_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/capability.h>
#include <errno.h>
int main()
{
struct __user_cap_header_struct cap_header;
struct __user_cap_data_struct cap_data;
cap_header.pid = getpid() ;
cap_header.version = _LINUX_CAPABILITY_VERSION_1;
if( capget(&cap_header, &cap_data) < 0)
{
printf("%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("capheader: %x %d\n", cap_header.version, cap_header.pid);
printf("capdata: %x %x %x\n", cap_data.effective, cap_data.permitted, cap_data.inheritable);
__u32 cap_mask = 0;
cap_mask |= (1 << CAP_NET_BIND_SERVICE);
cap_data.effective = cap_mask;//类似于权限的集合
cap_data.permitted = cap_mask;//0001000000
cap_data.inheritable = 0;//子进程不继承特权
if( capset(&cap_header, &cap_data) < 0)
{
printf("%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("%d\n", capget(&cap_header, &cap_data));
printf("capheader: %x %d\n", cap_header.version, cap_header.pid);
printf("capdata: %x %x %x\n", cap_data.effective, cap_data.permitted, cap_data.inheritable);
return 0;
}
---》必须以root权限或者sudo才能执行:
普通用户:
capheader: 19980330 6092
capdata: 0 0 0
Operation not permitted
root:
capheader: 19980330 6098
capdata: ffffffff ffffffff 0
0
capheader: 19980330 6098
capdata: 400 400 0