曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 6135|回复: 0
打印 上一主题 下一主题

[文件I/O] 用户信息(User Information)

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-2-21 22:10:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
所有的 linux 程序, 除了 init 外,都被其它的程序或用户启动.用户经常从 shell 中启动程序.通过检查环境变量和读取系统时钟,程序便可确定环境的大量信息.一个程序亦可找出正在使用它的使用者的信息.

当一个用户登录(log in)Linux系统时,他也就同时具有了用户名和密码.一旦这些信息被确认,用户将得到一个shell.用户也有他自己的特定标识--UID. 每一个在 Linux 上运行的程序代表有一个相应的用户,这个用户关联着一个UID.

你可以创建程序运行,就像有另外一个用户已经启动了它们.当一个程序有那个用户的 UID 权限设置,它就会像由这个可执行文件的拥有者启动运行一样.当执行了 su 命令, 程序运行就像它被超级用户启动,然后对访问的访问进行验证,验证通过后就改变到目标用户的UID(changes the UID to that of the target account,改变 UID 到目前帐户的那去),最后执行那个用户的登录shell.也程序运行得就像有另外一个用户启动了它,这常被系统管理员使用来执行维护任务.

UID 是用户身份表示的一把钥匙!

UID 有自己的类型 __uid_t ,这被定义在 sys/types.h 里. 这通常是一个小整数.有一些由系统预定义; 其它的当要建立新用户时被系统管理员创建.通常的,用户一般有大于 100 的 UID 值.
#ifndef __uid_t_defined
typedef __uid_t uid_t;
# define __uid_t_defined
#endif
在 bits/types.h 里:
# define __STD_TYPE             typedef
#include <bits/typesizes.h>     /* Defines __*_T_TYPE macros.  */
__STD_TYPE __UID_T_TYPE __uid_t;        /* Type of user identifications.  */

在 bits/typesizes.h 里:
#define __UID_T_TYPE            __U32_TYPE

再看 bits/types.h 里:
#define __S32_TYPE              unsigned int

相关函数:
#include <sys/types.h>
#include <unistd.h>
uid_t getuid(void);
char *getlogin(void);

getuid() 函数返回程序所关联的 UID .这通常也是启动这个程序的用户的 UID .

getlogin 函数返回当前登录用户的用户名.

系统文件 /etc/passwd 包含一个处理用户帐户的数据库.它由行构成,每一行中代表一个用户信息: 用户名, 加密的密码, 用户的UID,组的GID,全名,家目录,默认shell.如下所示:
beyes:x:500:500:beyes:/home/beyes:/bin/bash

如果写一个程序, 要确定那个启动了这个程序的用户的 UID, 你可以进一步查看密码文件以找出登录的用户名和全名.但一般不建议这么做,因为现代的类 UNIX 系统已经不使用(move away from)简单的密码文件以提升系统的安全性.许多系统,包括 Linux, 可以选择使用 "影子密码文件(shadow password files)" ,这个文件完全不包含任何有用的密码加密信息(这个文件通常为 /etc/shadow,这个文件普通用户不可读). 基于这样的原因, 就定义了一组函数以提供标准有效的用户信息编程接口:
#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);

密码数据库结构体 passwd 定义在 pwd.h 中,包含以下成员:
passwd Member                        Description
char *pw_name                          用户的登录名
uid_t pw_uid                             UID 号
gid_t pw_gid                             GID 号
char *pw_dir                             用户家目录
char *pw_shell                           用户默认shell

对于用户的全名, 一些 UNIX 系统可能在域中使用不同的名字 : 在一些系统,它可能是 pw_gecos ,如在 Linux; 在其它的系统上,它可能会是 pw_comment . 这意味着,并不建议使用它.

getpwuid() 与 getpwnam() 两个函数都返回一个相应于用户的的指向 passwd 结构体的指针.

测试代码
01 #include <sys/types.h>
02 #include <pwd.h>
03 #include <stdio.h>
04 #include <unistd.h>
05 #include <stdlib.h>
06
07
08 int main()
09 {
10         uid_t uid;
11         gid_t gid;
12         struct passwd *pw;
13
14         uid = getuid();
15         gid = getgid();
16
17         printf("User is %s\n", getlogin());
18
19         printf("User IDs: uid=%d, gid=%d\n", uid, gid);
20
21         pw = getpwuid(uid);
22
23         pw = getpwuid(uid);
24         printf("UID passwd entry:\n name=%s, uid=%d, gid=%d, home=%s, shell=%s\n",
25     pw->pw_name, pw->pw_uid, pw->pw_gid, pw->pw_dir, pw->pw_shell);
26
27
28         pw = getpwnam("root");
29         printf("root passwd entry:\n");
30
31         printf("name=%s, uid=%d, gid=%d, home=%s, shell=%s\n",
32                 pw->pw_name, pw->pw_uid, pw->pw_gid, pw->pw_dir, pw->pw_shell);
33
34         exit(0);
35 }

运行输出
[root@localhost C]# ./user.exe
User is root
User IDs: uid=0, gid=0
UID passwd entry:
 name=root, uid=0, gid=0, home=/root, shell=/bin/bash
root passwd entry:
name=root, uid=0, gid=0, home=/root, shell=/bin/bash

说明
程序中,调用 getuid() 函数获得当前用户的 UID。这个 UID 被用在 getpwuid() 函数中获得详细的密码文件信息。

如果需要扫描所有的密码文件信息,你可以使用 getpwent() 函数,它能取得连续的文件条目:
#include <pwd.h>
#include <sys/types.h>
void endpwent(void);
struct passwd *getpwent(void);
void setpwent(void);

getpwent() 函数依次返回每一个用户信息条目。当所有都返回时,它返回一个空指针。一旦已经获得足够的条目信息,你可以使用 endpwent() 函数结束进程。setpwent() 函数使指针重置回到密码文件的开始位置处,这样就新的扫描就可以从下一次调用 getpwent() 开始。

用户和组的身份可以从其它的函数里获得,这些函数通常较少用到:
#include <sys/types.h>
#include <unistd.h>
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
int setuid(uid_t uid);
int setgid(gid_t gid);
注意,这里只有超级用户才可以调用 setuid() 和 setgid() 函数
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-4 00:23 , Processed in 0.111031 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表