标签:
昨天看完了,今天来看看第六章。感觉第六章的内容不是非常重要。简单看看吧
6.2 口令文件
口令文件其实就是/etc文件夹下的passwd文件,但处于安全性的考虑,我们无法直接读取它。就是通过直接限制权限的方式对其进行保护,passwd文件具体权限如下:
-rw-r--r-- 1 root root
不过为了解决以上问题,Linux中给出了一系列数据结构与函数帮助我们操纵口令文件,首先是关键数据结构,定义位于/include/pwd.h
struct passwd { char *pw_name; /* Username. */ char *pw_passwd; /* Password. */ __uid_t pw_uid; /* User ID. */ __gid_t pw_gid; /* Group ID. */ char *pw_gecos; /* Real name. */ char *pw_dir; /* Home directory. */ char *pw_shell; /* Shell program. */ };
#include <pwd.h> extern struct passwd *getpwuid (__uid_t __uid); extern struct passwd *getpwnam (const char *__name);
以上两个函数仅能查看某一个用户的口令信息,但如果不知道其他用户的登录名或数值ID,则无法获得这些信息。因此Linux中又给出了以下三个函数来查看整个口令文件。
#include <pwd.h> extern struct passwd *getpwent (void); //若成功,返回指针,指向口令文件中的下一个记录项。第一次调用时,它打开所使用的各个文件。 extern void setpwent (void); //回到口令文件开头 extern void endpwent (void); //关闭口令文件
6.3节中所提到的阴影口令文件感觉与口令文件的内容并没有多大的差距,在此就先不深入研究了,以后遇到了再说。
6.4组文件
还是相同的思路,如果用户程序想访问组相关信息,这些信息虽然存放在/etc/group中,但还是由于权限的限制导致一般的用户无法直接访问这一问题。Linux中给出的方法是通过相关的函数与数据结构进行访问,首先来看关键数据结构。
struct group { char *gr_name; /* Group name. */ char *gr_passwd; /* Password. */ __gid_t gr_gid; /* Group ID. */ char **gr_mem; /* Member list. */ };
#include <grp.h> extern struct group *getgrgid (__gid_t __gid); extern struct group *getgrnam (const char *__name);
#include <grp.h> extern void setgrent (void); extern void endgrent (void); extern struct group *getgrent (void);
引入附属组的一个原因是:一个用户会参与多个项目,因此也就要同时属于多个组。为了解决上述问题,4.2BSD引入了附属组的概念,用户不再简单的属于一个组,也可以属于多至16个另外的组。
用户程序可通过以下函数获取和设置附属组ID。
extern int getgrouplist (const char *__user, __gid_t __group, __gid_t *__groups, int *__ngroups); extern int setgroups (size_t __n, const __gid_t *__groups) __THROW; extern int initgroups (const char *__user, __gid_t __group);
其中setgroups需要超级用户权限调用,而由于initgroups需要调用setgroups,因此initgroups也同样只有超级用户才能调用。
6.7其他数据文件
除了上面提到的口令文件和组文件,Linux还有多个具有类似概念的文件。书中给出了一个表对上述内容进行总结。
说明 | 数据文件 | 头文件 | 结构 | 附加的减搜索函数 |
口令 | /etc/passwd | <pwd.h> | passwd | getpwnam/getpwuid |
组 | /etc/group | <grp.h> | group | getgrnam/getgrgid |
阴影口令 | /etc/shadow | <shadow.h> | spwd | getspnam |
主机 | /etc/hosts | <netdb.h> | hostnet | getnameinfo/getaddrinfo |
网络 | /etc/networks | <netdb.h> | netent | getnetbyname/getnetbyaddr |
协议 | /etc/protocols | <netdb.h> | protonet | getprotobyname/getprotobynumber |
服务 | /etc/services | <netdb.h> | servent | getserbyname/getserbyport |
6.8登录账户记录
Linux通过“/var/run/utmp”对当前登录到系统的各个用户进行记录;通过“/var/log/wtmp”文件跟踪各个登录和注销事件。以上两个文件是二进制文件,不能直接打开。
Linux通过以下几个函数与数据结构对以上两个文件进行修改。首先来看看关键数据结构,定义位于/usr/include/x86_64-linux-gnu/bits/utmp.h中
struct utmp { short int ut_type; /* Type of login. */ pid_t ut_pid; /* Process ID of login process. */ char ut_line[UT_LINESIZE]; /* Devicename. */ char ut_id[4]; /* Inittab ID. */ char ut_user[UT_NAMESIZE]; /* Username. */ char ut_host[UT_HOSTSIZE]; /* Hostname for remote login. */ struct exit_status ut_exit; /* Exit status of a process marked as DEAD_PROCESS. */ /* The ut_session and ut_tv fields must be the same size when compiled 32- and 64-bit. This allows data files and shared memory to be shared between 32- and 64-bit applications. */ #ifdef __WORDSIZE_TIME64_COMPAT32 int32_t ut_session; /* Session ID, used for windowing. */ struct { int32_t tv_sec; /* Seconds. */ int32_t tv_usec; /* Microseconds. */ } ut_tv; /* Time entry was made. */ #else long int ut_session; /* Session ID, used for windowing. */ struct timeval ut_tv; /* Time entry was made. */ #endif int32_t ut_addr_v6[4]; /* Internet address of remote host. */ char __glibc_reserved[20]; /* Reserved for future use. */ };
extern void login (const struct utmp *__entry) __THROW;
注销时,init进程将utmp文件中相应的记录擦除,并将一个新记录添写到wtmp文件中。
6.9 系统标识
POSIX.1 定义了uname函数,它返回与主机和操作系统有关的信息。定义位于/usr/include/x86_64-linux-gnu/sys/utsname.h。
extern int uname (struct utsname *__name) __THROW; //__name即是输入参数也是输出参数。若程序运行成功返回非负值,若出错返回-1。
参数定义如下:
struct utsname { /* Name of the implementation of the operating system. */ char sysname[_UTSNAME_SYSNAME_LENGTH]; /* Name of this node on the network. */ char nodename[_UTSNAME_NODENAME_LENGTH]; /* Current release level of this implementation. */ char release[_UTSNAME_RELEASE_LENGTH]; /* Current version level of this release. */ char version[_UTSNAME_VERSION_LENGTH]; /* Name of the hardware type the system is running on. */ char machine[_UTSNAME_MACHINE_LENGTH]; #if _UTSNAME_DOMAIN_LENGTH - 0 /* Name of the domain of this node on the network. */ # ifdef __USE_GNU char domainname[_UTSNAME_DOMAIN_LENGTH]; # else char __domainname[_UTSNAME_DOMAIN_LENGTH]; # endif #endif };
Linux
还有一个返回主机名的函数,该名字通常就是TCP/IP网络上主机的名字。
extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1));
hostname命令可用来获取和设置主机名。主机名通常在系统自举时设置,它由/etc/rc或init取自一个启动文件。
6.10 时间和日期例程
由UNIX内核提供的基本时间服务是计算自协调世界时(Coordinated Universal Time,UTC)公元1970年1月1日00:00:00这一特定时间以来经过的秒数。这一秒数通过以下函数获得:
#include <time.h> extern time_t time (time_t *__timer) __THROW;
#include <time.h> extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;
time_t类型的参数可以通过gmtime函数转化为协调统一时间的年、月、日、时、分、秒、周日分解。这一格式的时间通过以下结构体表示。
struct tm { int tm_sec; /* Seconds. [0-60] (1 leap second) */ int tm_min; /* Minutes. [0-59] */ int tm_hour; /* Hours. [0-23] */ int tm_mday; /* Day. [1-31] */ int tm_mon; /* Month. [0-11] */ int tm_year; /* Year - 1900. */ int tm_wday; /* Day of week. [0-6] */ int tm_yday; /* Days in year.[0-365] */ int tm_isdst; /* DST. [-1/0/1]*/ # ifdef __USE_MISC long int tm_gmtoff; /* Seconds east of UTC. */ const char *tm_zone; /* Timezone abbreviation. */ # else long int __tm_gmtoff; /* Seconds east of UTC. */ const char *__tm_zone; /* Timezone abbreviation. */ # endif };
extern size_t strftime (char *__restrict __s, size_t __maxsize, const char *__restrict __format, const struct tm *__restrict __tp) __THROW;
extern char *strptime (const char *__restrict __s, const char *__restrict __fmt, struct tm *__tp) __THROW;
extern time_t mktime (struct tm *__tp) __THROW;
标签:
原文地址:http://blog.csdn.net/u012927281/article/details/51930666