有时候为了系统安全,会将程序进行降权,但是当需要访问当前不允许访问的资源时,如何处理呢?那就是更改自己的用户ID或组ID,使新的ID具有合适的特权或访问权限,当处理完之后,再降低其特权,下面来介绍一下,如何在程序中动态修改程序的用户ID或组ID。

进程用户ID

首先,我们需要了解,一个进程相关联的ID有多少个,下面表格介绍:

ID 作用
实际用户ID 我们实际上是谁
实际组ID 我们实际上是谁
有效用户ID 用于文件访问权限检查
有效组ID 用于文件访问权限检查
附属组ID 用于文件访问权限检查
保存的设置用户ID 由exec()函数保存
保存的设置组ID 由exec()函数保存

另外,我们可以通过 getuid() 和 geteuid() 函数分别或者实际用户ID和有效用户ID,而设置用户ID我们是没有函数可以直接获取的。

动态更换用户ID

当我们在root用户下通过 chmod +s YourExe 命令给我们的可执行程序设置SUID位(“u+s”设置文件的用户ID位,“g+s”设置组ID位),这个时候,我们可以通过seteuid()函数暂时性的获得root权限。
“+s”设置的标志位含义是当执行此文件时,将进程的有效用户ID设置为文件所有者的用户ID

测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/prctl.h>
#include <sys/syscall.h>int main(int argc, char *argv[])
{int fd;unsigned char *dev_name = "/dev/input/event0";printf("uid = %d, gid = %d euid = %d\n", getuid(), getgid(), geteuid());fd = open(dev_name, O_RDONLY);if (fd < 0)printf("open %s error,errno %d\n", dev_name, errno);else {printf("open %s ok\n", dev_name);close(fd);}/* 参数0是root用户ID */seteuid(0);printf("uid = %d, gid = %d euid = %d\n", getuid(), getgid(), geteuid());fd = open(dev_name, O_RDONLY);if (fd < 0)printf("open %s error,errno %d\n", dev_name, errno);else {printf("open %s ok\n", dev_name);close(fd);}/* 参数2是当前实际用户ID */seteuid(2);printf("uid = %d, gid = %d euid = %d\n", getuid(), getgid(), geteuid());fd = open(dev_name, O_RDONLY);if (fd < 0)printf("open %s error,errno %d\n", dev_name, errno);else {printf("open %s ok\n", dev_name);close(fd);}
}

默认的,我们user是没有 /dev 目录下节点的读取权限的,当我们去打开该节点时,将会出现报错说没有权限,但是,这个时候,如果通过 seteuid() 函数将有效用户ID设置为 root 用户(ID = 0),则可以正常访问 /dev 目录下的节点,当访问结束后,再通过 seteuid() 函数还原即可,注意,是 seteuid() 函数而不是 setuid() 函数。

实际上,上面示例在user用户环境的的工作步骤如下:

  1. 程序文件由root用户拥有且在设置用户ID位已设置,在user用户空间运行的,所以用户ID信息如下:

    实际用户ID = 我们的用户ID
    有效用户ID = 我们的用户ID
    保存的设置用户ID = root

    所以第一次open /dev 节点将会出现没有权限。

  2. 当调用 seteuid(0) 之后,由于我们已经设置了用户ID位,所以这种行为是允许的,用户ID信息将变为以下:

    实际用户ID = 我们的用户ID(未改变)
    有效用户ID = root
    保存的设置用户ID = root(未改变)

    由于当前有效用户ID为root,所以可以正常访问 /dev 节点。

  3. 当调用 seteuid(2) 降权之后,用户ID信息将变为以下:

    实际用户ID = 我们的用户ID(未改变)
    有效用户ID = 我们的用户ID
    保存的设置用户ID = root(未改变)

    降权后访问 /dev 将会无权限。

通过上述的配置,我们可以动态修改用户 ID,但是程序得到了额外的权限,编写这种程序时谨慎处理。

参考

《UNIX环境高级编程第3版》

Linux应用程序动态更改用户ID相关推荐

  1. 8.11 更改用户ID和组ID

    8.11 更改用户ID和组ID 在UNIX系统中,特权是基于用户和组ID的,当程序需要增加特权,或需要访问当前并不允许访问的资源时,我们就需要更换自己的用户ID或组ID. 一般而言,在设计应用程序的时 ...

  2. 微信小程序- css相比,wxss区别?小程序关联微信公众号如何确定用户的唯一性?微信小程序中的用户ID(openid和unionid)

    1 与css相比, wxss区别? 1) 响应式长度 rpx 2) 样式导入 3) 小程序不支持通配符* *{ width:100rpx; height:100rpx; } 2 小程序关联微信公众号如 ...

  3. 支付宝小程序获取php用户id,02支付宝小程序(基于知晓云)~如何获取用户ID

    一.引入SDK 初始化成功后 二.支付宝小程序管理平台,增加[获取会员信息功能] 否则如下错误 三.获取用户ID 1.在app.js增加用户注册功能并缓存用户信息 // 注册用户~到知晓云平台 fun ...

  4. 微信小程序中的用户ID(openid和unionid)

    前沿 做过微信开发的同学,多多少少都会涉及到用户的唯一标示的问题.由于微信牢牢把控着用户的信息,因此当你需要在微信平台中获取用户的标示信息,必然要通过微信的平台接口来获取(当然,你可以通过你自己的平台 ...

  5. linux更改用户的shell,Linux下通过shell更改用户密码

    echo "root:admin" | chpasswd root的密码改为admin pwconv 同步到shadow文件 newusers和chpasswd的用法 日期:200 ...

  6. 微信小程序动态更改标题栏_微信小程序实现动态设置页面标题的方法【附源码下载】...

    本文实例讲述了微信小程序实现动态设置页面标题的方法.分享给大家供大家参考,具体如下: 1.效果展示 2.关键代码 ① WXML文件 标题1 标题2 标题3 还原 ② JS文件 Page({ // 设置 ...

  7. cll创建的uniapp小程序动态更改manifest.json

    目录 1,前言 2,实现思路 3,实现代码 1,前言 事情的起因是这样的,项目是用cli搭建的uni-app小程序.申请了两个appid,一个用作开发人员调试使用,体验版和正式版都是dev环境.一个体 ...

  8. linux重命名用户名_如何在Linux中更改或重命名用户名和用户ID?

    linux重命名用户名 The problem is we want to change the already created user name or user id. As we know th ...

  9. linux中如何设置组id,linux 下设置用户ID 和 设置组ID 学习笔记

    因为某种原因 感觉心里一直有想把Unix有关文件权限编程这部份弄懂的想法,  所以第三遍看Unix高级编程第四章, 以前都是一眼带过, 根本没看吃透, 再次看感觉懂了蛮多的, 写下了以后复习用! 一: ...

最新文章

  1. python - django (auth 的使用)
  2. UA MATH565C 随机微分方程III Ito Isometry
  3. HttpClient4.5.2调用示例(转载+原创)
  4. C语言高级编程:i++ 或 ++i作为函数参数
  5. 手机客户端测试考虑的点
  6. AT4378-[AGC027D]ModuloMatrix【构造】
  7. Pytest fixture参数化params
  8. python列表功能默写_python基础学习——列表list的功能
  9. 恢复oracle数据步骤,通过数据泵expdp、impdp方式备份与还原/恢复 Oracle数据库(详细过程)-Oracle...
  10. 欧式二元期权的定价公式及实现
  11. fastadmin使用ECharts制作统计图
  12. c语言中的绝对值符号
  13. uni-app 应用换肤功能
  14. java lint_Android静态代码检查-Lint
  15. 用户画像:标签化就是数据的抽象能力
  16. 如何把照片做成视频?抖音爆款的图片视频切换教程,快速上手!
  17. 网络对大学生影响的调查研究报告
  18. 到底怎样才能学好Python
  19. 基于Java的SHA-1算法原生不调库实现
  20. WINDOWS 2000下如何获得用户登录名和密码

热门文章

  1. android app开发_如何雇用Android App开发人员
  2. C# 中使用TCP连接设置超时问题
  3. element的el-table-column循环渲染和自定义列
  4. I/O Request Packet
  5. 6-1 Numerical Summation of a Series (40分)
  6. 不同范数下的余弦定理_什么是绝对矩阵范数?
  7. 如何提高企业员工的企业文化,形成共同的理念价值观
  8. uboot引导vxworks6.9(T4240) 启动
  9. 5.2 创建个人中心页面-前端部分
  10. 一个故事讲解公钥私钥和数字签名,很深刻!