系统数据文件和信息之口令文件、阴影口令、组文件以及附属组ID

口令文件

<pwd.h>中定义了passwd结构体。以下就是Linux下的该结构体:

struct passwd{
    char *pw_name; /* username */
    char *pw_passwd /*user password */
    uid_t pw_uid /* user ID */
    gid_t pw_gid; /* group ID */
    char *pw_gecos; /* user information */
    char *pw_dir; /* home directory */
    char *pw_shell; /* shell program */
};

POSIX.1定义了两个获取口令文件项的函数。

#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
两个函数返回值: 若成功,返回指针;若出错,返回NULL

下面三个函数用于查看整个口令文件。

#include <pwd.h>
struct passwd *getpwent(void);
返回值: 若成功,返回指针;若出错或到达文件末尾,返回NULLvoid setpwent(void);
void endpwent(void);

getpwent函数用于返回口令文件中下一个记录项;

setpwent函数用来将getpwent函数的读写地址指向密码文件开头;

endpwent函数用于关闭使用getpwent函数查看完的口令文件。

测试示例:

#include <stdio.h>
#include <pwd.h>
#include <stddef.h>
#include <string.h>
/* this is implementation of getpwnam function. */
struct passwd *getpwnam(const char *name)
{
    struct passwd *ptr;
    setpwent();
    while((ptr = getpwent()) != NULL)
        if(strcmp(name, ptr->pw_name) == 0)
            break;
    endpwent();
    return ptr;
}
int main()
{
    struct passwd *user;
    user = getpwnam("dunk");
    printf("name = \"%s\" , password = \"%s\", user id = %d, group id = %d\n", 
           user->pw_name, user->pw_passwd, user->pw_uid, user->pw_gid);
    return 0;
}

结果如下:
在这里插入图片描述

阴影口令

将系统加密口令存放在被称之为阴影口令文件的文件中,与访问口令文件的一组函数相类似,有另一组函数可用于访问阴影口令文件。

扫描二维码关注公众号,回复: 9294815 查看本文章
#include <shadow.h>
struct spwd *getspnam(const char *name);
struct spwd *getspent(void);
两个函数返回值:若成功,返回指针;若出错,返回NULLvoid setpent(void);
void endspent(void);

spwd结构体说明:

struct spwd{
    char *sp_name; /* Login name */
    char *sp_pwdp; /* Encrypted password */
    long sp_lstchg; /* Date of last change (measured in days since 1970-01-01  	00:00:00 +0000 (UTC)) */
    long sp_min; /* Min # of days between changes */
    long sp_max; /* Max # of days between changes */
    long sp_warn; /* # of days before password expires to warn user to  change it */
    long sp_inact; /* # of days after password expires until account is disabled */
    long sp_expire; /* Date when account expires (measured in days since 1970-01-01 00:00:00 +0000 (UTC)) */
    unsigned long sp_flag; /* Reserved */
};

组文件

UNIX组文件包含了如下结构体中的字段。这个结构体定义在<grp.h>中。

struct group{
    char *gr_name;    /* group name */
    char *gr_passwd;  /* group password */
    gid_t gr_gid;     /* group ID */
    char **gr_mem;    /* NULL-terminated array of pointers to names of group members */
};

下面两个函数是用来查看组名和组ID的。

#include <grp.h>
struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
这两个函数返回值:若成功,返回指针;若出错,返回NULL

用来查看整个组文件的需要用到如下三个函数。

#include <grp.h>
struct group *getgrent(void);
返回值:若成功,返回指针;若出错或到达文件末尾,返回NULLvoid setgrent(void);
void endgrent(void);

setgrent函数打开组文件并反绕它;

getgrent函数从组文件中读下一个记录,如若该文件尚未打开,则先打开它;

endgrent函数关闭组文件。

附属组ID

一个用户参与多个项目,因此用户就必须同时属于多个组,此类情况是很常有的。为了获取和设置附属组ID,提供了以下三个函数。

#include <unistd.h>
int getgroups(int gidsetsize, gid_t grouplist[]);
返回值:若成功,返回附属组ID数量;若出错,返回-1#include <grp.h> /* on Linux */
#include <unistd.h> /* on FreeBSD, Mac OS X, and Solaris*/
int setgroups(int ngroups, const gid_t grouplist[]);
#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

getgroups将进程所属用户的各附属组ID填写到数组grouplist中,填写入该数组的附属组ID数最多为gidsetsize个。

setgroups可由超级用户调用以便为调用进程设置附属组ID表。

initgroups函数调用setgroupsinitgroups读整个组文件,然后对username确定其组的成员关系。然后,它调用setgroups,以便为该用户初始化附属组ID表。因为initgroups要调用setgroups,所以只有超级用户才能调用initgroups。除了在组文件中找到username是其成员的所有组,initgroups也在附属组ID表中包括了basegidbasegidusername在口令文件中的组ID。只有少数几个程序可以调用initgroups

发布了229 篇原创文章 · 获赞 17 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_40073459/article/details/104409861