《UNIX环境高级编程》笔记--口令文件,阴影文件,组文件,附加组ID,其他数据文件

来源:互联网 发布:淘宝重复铺货怎么举报 编辑:程序博客网 时间:2024/04/29 07:18

1.口令文件

UNIX系统的口令文件(/etc/passwd)包含如下个字段,这些字段包含在<pwd.h>中定义的passwd文件中。


POSIX只定义了两个获取口令文件项的函数,在给出用户登录名或者数值用户ID后,这两个函数就能查询相关项。
#include <pwd.h>struct passwd *getpwuid(uid_t uid);struct passwd *getpwnam(const char *name);
两个函数返回值,如果成功返回指针,出错则返回NULL。

实践:
#include <stdio.h>#include <pwd.h>int main(void){        struct passwd* pwd;        if((pwd = getpwuid(1)) == NULL){                perror("getpwuid");                return -1;        }        printf("%s,%s,%ld,%ld,%s,%s,%s\n",pwd->pw_name,pwd->pw_passwd,pwd->pw_uid,pwd->pw_gid,pwd->pw_gecos,pwd->pw_dir,pwd->pw_shell);        if((pwd = getpwnam("daemon")) == NULL){                perror("getpwnam");                return -1;        }        printf("%s,%s,%ld,%ld,%s,%s,%s\n",pwd->pw_name,pwd->pw_passwd,pwd->pw_uid,pwd->pw_gid,pwd->pw_gecos,pwd->pw_dir,pwd->pw_shell);        return 0;}
运行结果:
daemon,x,1,1,daemon,/usr/sbin,/bin/sh
daemon,x,1,1,daemon,/usr/sbin,/bin/sh

如果要查看整个口令文件,可使用以下三个函数。
#include <pwd.h>struct passwd* getpwent(void); //如果成功返回指针,出错或者达到文件末尾则返回NULL。void setpwent(void); //反绕所使用的文件,使指针指向文件的第一行void endpwent(void); //关闭文件。

实践:
#include <stdio.h>#include <pwd.h>int main(void){        struct passwd* pwd;        if((pwd = getpwent()) == NULL){                perror("getpwent");                return -1;        }        printf("%s,%s,%ld,%ld,%s,%s,%s\n",pwd->pw_name,pwd->pw_passwd,pwd->pw_uid,pwd->pw_gid,pwd->pw_gecos,pwd->pw_dir,pwd->pw_shell);        setpwent();        while((pwd = getpwent()) != NULL){                printf("%s,%s,%ld,%ld,%s,%s,%s\n",pwd->pw_name,pwd->pw_passwd,pwd->pw_uid,pwd->pw_gid,pwd->pw_gecos,pwd->pw_dir,pwd->pw_shell);        }        endpwent();        return 0;}

运行结果:
root,x,0,0,root,/root,/bin/bash
root,x,0,0,root,/root,/bin/bash
daemon,x,1,1,daemon,/usr/sbin,/bin/sh
bin,x,2,2,bin,/bin,/bin/sh
.......此处省略多行
hplip,x,112,7,HPLIP system user,,,,/var/run/hplip,/bin/false
pulse,x,113,121,PulseAudio daemon,,,,/var/run/pulse,/bin/false
saned,x,114,123,,/home/saned,/bin/false
yan,x,1000,1000,yanwenjie,,,,/home/yan,/bin/bash
sshd,x,115,65534,,/var/run/sshd,/usr/sbin/nologin

2.阴影文件

因为/etc/passwd文件对普通用户来说是可见的,所以现在的系统都将加密的密码存放在一个阴影文件(shadow password)中,
该文件至少包含用户名和密码。阴影文件(/etc/shadow)各字段说明如下:


与口令文件一组函数类似,有另一组函数可以访问阴影文件。(只有root用户才能权限调用该组函数)
#include <pwd.h>struct spwd *getspnam(const char *name); //如果成功返回指针, 如果出错则返回NULL。struct spwd *getspent(void);  //如果成功返回指针, 如果出错则返回NULL。void setspent(void);  //反绕阴影文件,将指针指向文件的第一行。void entspent(void);  //关闭文件。

实践:
#include <stdio.h>#include <shadow.h>int main(void){        struct spwd* spwd;        if((spwd = getspnam("yan")) == NULL){                perror("getspnam");                return -1;        }        printf("%s,%s,%ld,%ld,%ld,%ld,%ld,%ld,%lu\n",spwd->sp_namp,spwd->sp_pwdp,spwd->sp_lstchg,spwd->sp_min,spwd->sp_max,spwd->sp_warn,spwd->sp_inact,spwd->sp_expire,spwd->sp_flag);        if((spwd = getspent()) == NULL){                perror("getspent");                return -1;        }        setspent();        while((spwd = getspent()) != NULL){                printf("%s,%s,%ld,%ld,%ld,%ld,%ld,%ld,%lu\n",spwd->sp_namp,spwd->sp_pwdp,spwd->sp_lstchg,spwd->sp_min,spwd->sp_max,spwd->sp_warn,spwd->sp_inact,spwd->sp_expire,spwd->sp_flag);        }        endspent();        return 0;}
运行结果:
yan,$6$OGnTte0B$fAq8CO01RIyf2mkaBUaY2LZjYyZDyLrQVbv94im4tpMgs1SdTjHIC9ls1p9MDI4TP5meeI8HWxgrkKWqJII.D.,15807,0,99999,7,-1,-1,4294967295
root,$6$sr2Imb6g$hbPz1T3OJTszUFgQXR36oW1l4qnzEA8cZR1qgqCMq3jIpv4Ev4Kyt3Nbfv/2PcOLYKoLk9sA.aGtV.srKGZM8.,15807,0,99999,7,-1,-1,4294967295
daemon,*,15630,0,99999,7,-1,-1,4294967295
bin,*,15630,0,99999,7,-1,-1,4294967295
.......此处省略多行
saned,*,15630,0,99999,7,-1,-1,4294967295
yan,$6$OGnTte0B$fAq8CO01RIyf2mkaBUaY2LZjYyZDyLrQVbv94im4tpMgs1SdTjHIC9ls1p9MDI4TP5meeI8HWxgrkKWqJII.D.,15807,0,99999,7,-1,-1,4294967295
sshd,*,15807,0,99999,7,-1,-1,4294967295

3.组文件

UNIX组文件包含了下表所示的字段,这些字段包含在<grp.h>所定义的group结构中。

字段gr_mem是一个指针数组,其中每个指针各指向一个属于该组的用户名,该数组以空指针结尾。

对组文件的访问函数如下,形式基本与口令文件和阴影文件相同。
#include <grp.h>struct group *getgrgid(gid_t gid);struct group *getgrnam(const char *name);//两个函数返回值:如果成功返回指针,出错则返回NULL。struct group *getgrent(void);  //如果成功返回指针,出错或者到达文件结尾则返回NULLvoid setgrent(void);void endgrent(void);

4.附加组

我们不仅可以属于口令文件记录项中组ID所对应的组,也可以属于多达16个另外的组。为了获取和设置附加组ID,提供以
下函数。
#include <unistd.h>
int getgroup(int gidsetsize, gid_t grouplist[]);  //如果成功返回附加组ID,出错则返回-1.
//函数将个附加组ID填写到数组grouplist中,数组中存放的元素最多为gidsetsize个。

#include <grp.h>  //on linux
#include <unistd.h>  //on FreeBSD and Mac OS X and Solaris
int setgroups(int ngroups, const gid_t grouplist[]);  //如果成功返回0,出错则返回-1.
//由root调用,为进程设置附加组ID表,grouplist是组ID数组,ngroups指定了数组中的元素个数。

#include <grp.h>  //on linux and Solaris
#include <unistd.h>  //on FreeBSD and Mac OS X 
int initgroups(const char* username, gid_t basegid); //如果成功返回0,出错则返回-1.
//initgroups()用来从组文件(/etc/group)读取整个组文件,然后对username确定其组的成员关系,然后调用setgroups,
为该用户初始化附加组ID表。除了在组文件中找到username是成员的所有组,initgroups也在附加组ID表中包括了
basegid,basegid是username在口令文件中的组ID。

5.其他数据文件

至此讨论了口令文件,阴影文件和组文件,在日常操作中,UNIX还使用其他文件。一般情况下,对于每个数据文件至少
有三个函数:get函数,set函数,end函数。下面列出了UNIX常用的文件对应的函数。

原创粉丝点击