setuid函数

2024-04-14 22:32
文章标签 函数 setuid

本文主要是介绍setuid函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

setuid(设置真实的用户识别码)
相关函数
getuid,setreuid,seteuid,setfsuid
表头文件
#include<unistd.h>
定义函数
int setuid(uid_t uid)
函数说明
setuid()用来重新设置执行目前进程的用户识别码。不过,要让此函数有作用,其有效的用户识别码必须为0(root)。在Linux下,当root 使用setuid()来变换成其他用户识别码时,root权限会被抛弃,完全转换成该用户身份,也就是说,该进程往后将不再具有可setuid()的权 利,如果只是向暂时抛弃root 权限,稍后想重新取回权限,则必须使用seteuid()。
返回值
执行成功则返回0,失败则返回-1,错误代码存于errno。
附加说明
一般在编写具setuid root的程序时,为减少此类程序带来的系统安全风险,在使用完root权限后建议马上执行setuid(getuid());来抛弃root权限。此外,进程uid和euid不一致时Linux系统将不会产生core dump。


内核会给每个进程关联两个和进程ID无关的用户ID,一个是真实用户ID,还有一个是有效用户ID或者称为setuid(set user ID)。真实用户ID用于标识由谁为正在运行的进程负责。有效用户ID用于为新创建的文件分配所有权、检查文件访问许可,还用于通过kill系统调用向其 它进程发送信号时的许可检查。内核允许一个进程以调用exec一个setuid程序或者显式执行setuid系统调用的方式改变它的有效用户ID。 所谓setuid程序是指一个设置了许可模式字段中的setuid bit的可执行文件。当一个进程exec一个setuid程序的时候,内核会把进程表以及u区中的有效用户ID设置成该文件所有者的ID。为了区分这两个 字段,我们把进程表中的那个字段称作保存用户ID。可以通过一个例子来演示这两个字段的区别。 setuid系统调用的语法是 setuid(uid) ,其中,uid是新的用户ID,该系统调用的结果取决于有效用户ID的当前值。如果调用进程的有效用户ID是超级用户,内核会把进程表以及u区中的真实和 有效用户ID都设置成uid。如果调用进程的有效用户ID不是超级用户,仅当uid等于真实用户ID或保存用户ID时,内核才会把u区中的有效用户ID设 置成uid。否则,该系统调用将返回错误。一般来说,一个进程会在fork系统调用期间从父进程那儿继承它的真实和有效用户ID,这些数值即使经过 exec系统调用也会保持不变。 存储在u区中的有效用户ID是最近一次setuid系统调用或是exec一个setuid程序的结果;只有它会被用于文件访问许可。进程表中的保存用户 ID使得一个进程可以通过执行setuid系统调用把有效用户ID设置成它的值,以此来恢复最初的有效用户ID。

非root用户是不可能通过setuid或者seteuid取得其他权限(包括root权限)的,它只能恢复原来的权限。允许通过setuid或者seteuid取得root权限是非常危险的这样他就可以在程序的后边做任何想做的事了(包括kill掉你的系统)。只能通过exec一个设置了setuid位的可执行程序,来取得其他(程序文件所有者)权限(包括root权限)。例如用户执行su即可获得root权限(su的属主为root)。

-rwsr-xr-x 1 root root 27108 2008-11-23 /bin/su

注意其中的s,该标志即为setuid标志(文件除基本的r、w、x权限外,还有s)。出于安全,防止普通用户取得root权限后威胁系统安全,该权限只针对不可更改的可执行文件(不能执行自定义程序)

要想取得root权限就必须exec一个root所有的可执行文件(当然首先得有执行权限),而该程序由root所有,其安全就由root负责。所以非root用户就不可能以root身份运行属于root以外的程序。至于sudo之类的,是因为sudo本身里有setuid和exec调用(root用户允许的,给非root用户开了一个后门),通过sudo
取得root权限, 作为中介来exec所有程序。但也有限制,就是该用户是sudoers(后门的钥匙,root的亲戚才有,又是安全)!(现在流行靠关系、开后门,到时如果出问题,就该抱怨了:都是开后门惹的祸!)

su=super user
sudo是什么的缩写?super user ? ?(应为swicth user

还有非root权限用户,不能改变实际用户ID,而只能改变有效用户ID,包括通过exec一个setuid程序。
只有root用户进程才能更改实际用户ID。这样普通用户进程就不能通过改变实际用户ID,然后再通过setuid,设置有效用户ID为实际用户ID,进而取得与该实际用户ID对应的权限了(包括root)。正如上面说过的:
允许通过setuid或者seteuid取得root权限是非常危险的

对于文件访问权限的验证是根据有效用户ID。有些文件只有root用户才有读写或者执行的权力,对于这些文件,普通用户程序就需要以root权限(进程的有效用户ID为0)来访问。

举个例子:
sudo vim /etc/sudoers
====================以下分析错误=========================
sudoers是取得root权限的关键文件,只有root可以写。所以,普通用户是不能用VIM编辑的。但sudoers用户可以运行sudo,运行sudo可以将进程有效用户ID设为文件所有者root,但exec  vim后,由于vim不是setuid程序,子进程不会将euid设置为vim所有者uid,而会继承父进程的euid即为root的uid=0,所以vim进程的euid为0,这时的vim以写方式打开sudoers文件是可以通过权限检查的。

sudo的实现里有setuid函数,但对于上边那个例子只用fork和exec已经可以实现了。什么时候会把[子]进程的实际用户ID也设为0,这个还没弄清楚,运行一个属主非root的steuid程序?
=======================================================
通过输出父子进程的uid和euid证实,sudo通过setuid将进程的实际用户ID和有效用户ID都设置为了0,也就是整个过程中进程都是有root权限的。关键不在exec处了!!

这篇关于setuid函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/904200

相关文章

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客

Python函数作用域示例详解

《Python函数作用域示例详解》本文介绍了Python中的LEGB作用域规则,详细解析了变量查找的四个层级,通过具体代码示例,展示了各层级的变量访问规则和特性,对python函数作用域相关知识感兴趣... 目录一、LEGB 规则二、作用域实例2.1 局部作用域(Local)2.2 闭包作用域(Enclos

MySQL count()聚合函数详解

《MySQLcount()聚合函数详解》MySQL中的COUNT()函数,它是SQL中最常用的聚合函数之一,用于计算表中符合特定条件的行数,本文给大家介绍MySQLcount()聚合函数,感兴趣的朋... 目录核心功能语法形式重要特性与行为如何选择使用哪种形式?总结深入剖析一下 mysql 中的 COUNT

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

Python get()函数用法案例详解

《Pythonget()函数用法案例详解》在Python中,get()是字典(dict)类型的内置方法,用于安全地获取字典中指定键对应的值,它的核心作用是避免因访问不存在的键而引发KeyError错... 目录简介基本语法一、用法二、案例:安全访问未知键三、案例:配置参数默认值简介python是一种高级编

python 常见数学公式函数使用详解(最新推荐)

《python常见数学公式函数使用详解(最新推荐)》文章介绍了Python的数学计算工具,涵盖内置函数、math/cmath标准库及numpy/scipy/sympy第三方库,支持从基础算术到复杂数... 目录python 数学公式与函数大全1. 基本数学运算1.1 算术运算1.2 分数与小数2. 数学函数

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五