1、口令文件
该文件主要是针对unix中的/etc/passwd文件,该文件中存储用户名、用户密码、用户ID、用户主组ID,用户的昵称、用户的家目录、用户Shell这7个信息,但是用户密码现在已经不存储在该文件下,因为该文件所有人都能有读权限,所以不安全,密码改存在/etc/shadow文件中。
Linux中该文件的数据形式:xkey:x:700:100:xkey's color:/home/xkey:/bin/bash
#include <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 */ };
struct passwd *getpwuid(uid_t uid); //根据用户ID struct passwd *getpwnam(const char *name); //根据用户名查看整个口令文件,需要对口令文件进行遍历:
struct passwd *getpwent(void); //返回口令文件中的下一个记录项 void setpwent(void); //反绕文件,从文件头开始 void endpwent(void); //关闭文件
#include <stdio.h> #include <unistd.h> #include <error.h> #include <stdlib.h> #include <string.h> #include <pwd.h> int main(){ struct passwd *pwd; pwd = getpwnam("xkey"); printf("username is: %s\n",pwd->pw_name); printf("userid is: %d\n",pwd->pw_uid); printf("groupid is: %d\n",pwd->pw_gid); printf("usergecos is: %s\n",pwd->pw_gecos); printf("usershell is: %s\n",pwd->pw_shell); printf("userhome is: %s\n",pwd->pw_dir); printf("userpasswd is: %s\n",pwd->pw_passwd); // /etc/passwd setpwent(); while((pwd = getpwent()) != NULL){ if(strcmp(pwd->pw_name,"root") == 0) { printf("username is: %s\n",pwd->pw_name); printf("userid is: %d\n",pwd->pw_uid); printf("groupid is: %d\n",pwd->pw_gid); printf("usergecos is: %s\n",pwd->pw_gecos); printf("usershell is: %s\n",pwd->pw_shell); printf("userhome is: %s\n",pwd->pw_dir); printf("userpasswd is: %s\n",pwd->pw_passwd); break; } } endpwent(); return 0; }
xkey:$6$EDjnGJ7f$H6Q27GTL3TY84UDJxHWcldHRtFD8xCGX4sU.bxz6GTTJz0Z8P33mE3O9ZU3PgiJpAnn81EwoRcz3M/04ZZxfk.:15775:0:99999:7:::
拿此帐号来说明,字段间以冒号分隔,
第一个字段是账户名;
第二个字段是加密后的密码;
第三个是最近一次修改密码的日期,15775是修改密码的日期与1970年1月1日的相距的天数;
第四个字段是密码不可以被改动的日期,若为0则表示可以随时更改;
第五个字段是密码需要重新更改的天数,99999就表示99999天后强制修改密码;
第六个字段是密码需要修改的提前警告的天数,7就表示在强制修改密码的日期到的前7天提醒用户
第七个字段是密码过期后可以宽限的天数
第八个字段是帐号的失效日期
第九个字段保留
这里通过第七和第八个字段的联合使用就能让一个帐号失效。
#include <shadow.h>中定义spwd数据结构:
struct spwd { char *sp_namp; char *sp_pwdp; long sp_lstchg; long sp_min; long sp_max; long sp_warn; long sp_inact; long sp_expire; unsigned long sp_flag; };函数:
struct spwd *getspnam(const char *name); struct spwd *getspent(void); void setspent(void); void endspent(void);
#include <shadow.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(){ struct spwd *shd; shd = getspnam("xkey"); printf("username is: %s\n",shd->sp_namp); printf("user passwd is: %s\n",shd->sp_pwdp); printf("user change pwd last: %d\n",shd->sp_lstchg); printf("user allowed change pwd min days: %d\n",shd->sp_min); printf("user must be change pwd days: %d\n",shd->sp_max); printf("warning days: %d\n",shd->sp_warn); printf("user account inactive days: %d\n",shd->sp_inact); printf("account expire days: %d\n",shd->sp_expire); //setspent(); //getspent(); // endspent(); }此函数要在root权限下运行,因为/etc/shadow文件只有root有权限读取。
在/etc/group中,#include <grp.h>中定义了其数据结构
struct group { char *gr_name; /* group name */ char *gr_passwd; /* group password */ gid_t gr_gid; /* group ID */ char **gr_mem; /* group members */ }; 按照组名或组ID来获取组信息 struct group *getgrnam(const char *name); struct group *getgrgid(gid_t gid); 搜索整个文件组函数: struct group *getgrent(void); void setgrent(void); void endgrent(void);这里需要指出的是,组密码不存储在/etc/group中,而是存储在/etc/gshadow中
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <grp.h> int main(){ struct group *grp; grp = getgrnam("users"); printf("group name: %s\n",grp->gr_name); printf("group id: %d\n",grp->gr_gid); printf("group pwd: %s\n",grp->gr_passwd); int len = sizeof(grp->gr_mem)/sizeof(char*); printf("%d %d\n",sizeof(grp->gr_mem),sizeof(char*)); char *p[]={"a","bc","cbf"}; printf("%d\n",sizeof(p)); printf("group members: %d\n",len); while(*grp->gr_mem!=NULL){ printf("%s\n",*grp->gr_mem++); len --; } //setgrent(); //getgrent(); //endgrent(); return 0; }
说明 | 数据文件 | 头文件 | 结构 | 附加的关键字查找函数 |
口令 | /etc/passwd | <pwd.h> | passwd | getpwnam 、getpwuid |
组 | /etc/group | <grp.h> | group | getpwnam、getpwuid |
阴影 | /etc/shadow | <shadow.h> | spwd | getspnam |
主机 | /etc/hosts | <netdb.h> | hostent | gethostbyname、gethostbyaddr |
网络 | /etc/networks | <netdb.h> | netent | getnetbyname、getnetbyaddr |
协议 | /etc/protocols | <netdb.h> | protoent | getprotobyname、getprotobyaddr |
服务 | /etc/services | <netdb.h> | servent | getservbyname、getservbyad |
5、系统标识
#include <utsname.h>
int uname(struct utsname *name)
数据结构
struct utsname { char sysname[]; char nodename[]; char release[]; char version[]; char machine[]; };
#include <sys/utsname.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(){ struct utsname name; uname(&name); printf("%s\n%s\n%s\n%s\n",name.sysname,name.nodename,name.release,name.version); printf("%s\n",name.machine); char host[32]; gethostname(host,32);//得到主机名函数 printf("%s\n",host); return 0; }
UNIX中的基本时间服务是计算从1970年1月1日00:00:00以来的秒数,此秒数是通过数据类型time_t表示的。
#include <time.h>
time_t time(time_t *calptr)
与time函数相比gettimeofday拥有更高的精度。
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz)
timeval结构体
struct timeval{
long tv_sec;/*秒*/
long tv_usec;/*微妙*/
};
timezone结构体
struct timezone{
int tz_minuteswest;/*和greenwich(格林尼治)时间差了多少分钟*/
int tz_dsttime;/*type of DST correction*/
}
时间转换图例:
a、日历时间转换为以年月日时分秒表示的时间,将该事件存放在tm结构体中
struct tm { int tm_sec; /* seconds[0-60] */ int tm_min; /* minutes [0-59]*/ int tm_hour; /* hours [0-23]*/ int tm_mday; /* day of the month [1-31]*/ int tm_mon; /* month [0-11]*/ int tm_year; /* year since 1900*/ int tm_wday; /* day of the week [0-6]*/ int tm_yday; /* day in the year [0-365]*/ int tm_isdst; /* daylight saving time flags: < 0, 0 , > 0*/ };#include<time.h>
struct tm *localtime(const time_t *calptr)
struct tm *gmtime(const time_t *calptr)
b、年月日时分秒表示的时间转换为日历时间
#include<time.h>
time_t mktime(struct tm *tmptr)
c、日历或tm时间转换为字符串
#include <time.h>
char *asctime(const struct tm *tmptr)
char *ctime(const time_t *calptr)
d、格式化输出到一个字符串
#include <time.h>
size_t strftime(char *buf, size_t size, const char *format,const struct tm *tmptr); //对tm进行格式化输出到一个字符串,具体的参数太多不列举
#include <time.h> #include <sys/types.h> #include <sys/time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(){ time_t now; now = time(&now); struct timeval tv; struct timezone tz; gettimeofday(&tv,&tz); printf("%d\n",now); printf("seconds: %d, microseconds: %d\n",tv.tv_sec,tv.tv_usec); printf("Greenwich: %d, DST: %d\n",tz.tz_minuteswest,tz.tz_dsttime); char *str; str = ctime(&now); puts(str); struct tm *gmnow; struct tm *localnow; gmnow = gmtime(&now); localnow = localtime(&now); printf("%d\n",gmnow->tm_mday); printf("%d\n",localnow->tm_year+1900); printf("%d\n",gmnow->tm_yday); printf("%d\n",localnow->tm_isdst); struct tm mtime; mtime.tm_sec = 60; mtime.tm_min = 34; mtime.tm_hour = 12; mtime.tm_mday = 23; mtime.tm_mon = 3; mtime.tm_year = 111; now = mktime(&mtime); printf("%d\n",now); puts(ctime(&now)); puts(asctime(&mtime)); char buf[64]; memset(buf,0,sizeof(buf)); strftime(buf,sizeof(buf),"%x %X, %B %A",&mtime); puts(buf); return 0; }