2 shadow passwords
linux獲取各種進程類型的信息
1 password file
終端上輸入cat /etc/passwd
可以看見很多相關信息。
也可以通過以下函數:
#include <sys/types.h>
#include <pwd.h>
struct passwd* getpwnam(const char* name);
struct passwd* getpwuid(uid_t uid);
int getpwnam_r(const char* name, struct passwd* pwd, char* buf, size_t buflen, struct passwd** result);
int getpwuid_r(uid_t uid, struct passwd* pwd, char* buf, size_t buflen, struct passwd** result);
結構體passwd(<pwd.h>):
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 */
};
如果不能理解每個成員的意思,可以通過man 5 passwd查閱。
getpwuid和getpwnam的程序用例:
#include <stdio.h>
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>
static void PrintfPwd(const passwd* pwdInfo)
{
if(!pwdInfo)
return;
printf("name: \t%s\n", pwdInfo->pw_name);
printf("passwd: \t%s\n", pwdInfo->pw_passwd);
printf("uid: \t%d\n", pwdInfo->pw_uid);
printf("gid: \t%d\n", pwdInfo->pw_gid);
printf("gecos: \t%s\n", pwdInfo->pw_gecos);
printf("dir: \t%s\n", pwdInfo->pw_dir);
printf("shell: \t\%s\n", pwdInfo->pw_shell);
}
int main(int argc, char* argv[])
{
printf("test getpwuid: \n");
uid_t uid = getuid();
printf("uid: %d\n", uid);
// test getpwuid
struct passwd* pwdInfo = getpwuid(uid);
if(!pwdInfo)
return 1;
PrintfPwd(pwdInfo);
// test getpwnam
printf("\n\ntest getpwnam: \n");
struct passwd* pwdInfo2 = getpwnam(pwdInfo->pw_name);
PrintfPwd(pwdInfo2);
return 0;
}
getpwuid_r用例:
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#include <unistd.h>
#include <errno.h>
static void PrintfPwd(const passwd* pwdInfo)
{
if(!pwdInfo)
return;
printf("name: \t%s\n", pwdInfo->pw_name);
printf("passwd: \t%s\n", pwdInfo->pw_passwd);
printf("uid: \t%d\n", pwdInfo->pw_uid);
printf("gid: \t%d\n", pwdInfo->pw_gid);
printf("gecos: \t%s\n", pwdInfo->pw_gecos);
printf("dir: \t%s\n", pwdInfo->pw_dir);
printf("shell: \t\%s\n", pwdInfo->pw_shell);
}
int main(int argc, char* argv[])
{
uid_t uid = getuid();
size_t len = sysconf(_SC_GETPW_R_SIZE_MAX);
if(len == -1)
len = 16384;
char* buffer = new char[len];
if(!buffer)
{
printf("buffer create failed. error[%d]\n", errno);
return 1;
}
struct passwd pwd;
struct passwd* result = NULL;
int ret = getpwuid_r(uid, &pwd, buffer, len, &result);
if(!result)
{
printf("getpwuid failed. ret[%d]\n", ret);
return 1;
}
printf("----------pwd---------- \n");
PrintfPwd(&pwd);
printf("\n\n----------result----------\n");
PrintfPwd(result);
printf("\n\n----------buffer----------\n");
printf("buffer: %s\n", buffer);
return 0;
}
以下三個函數與讀取/etc/passwd相關:
#include <sys/types.h>
#include <pwd.h>
struct passwd* getpwent(void);
void setpwent(void);
void endpwent(void);
getpwent: 獲取passwd文件中的一個口令,嚴格的說,是獲取下一個口令
setpwent: 將獲取口令重置到第一個
endpwent: 關閉由getpwent打開的文件
程序用例:
#include <stdio.h>
#include <pwd.h>
int main(int argc, char* argv[])
{
// 爲了測試方便,最多隻打印10個口令信息
struct passwd* pwd;
// 設置從頭開始讀取
setpwent();
int n = 0;
while((pwd = getpwent()) != NULL)
{
printf("name: %s \t uid: %d\n", pwd->pw_name, pwd->pw_uid);
if(++n >= 10)
break;
}
endpwent();
return 0;
}
2 shadow passwords
看着名字就知道它藏的好深。
有以下函數可以操作這個文件:
#include <shadow.h>
struct spwd* getspnam(const char* name);
struct spwd* getspent(void);
void setspent(void);
void endspent(void);
struct spwd* fgetspent(FILE* fp);
struct spwd* sgetspent(const char* s);
int putspent(struct spwd* p, FILE* fp);
int lckpwdf(void);
int ulckpwdf(void);
/* GNU extension */
#include <shadow.h>
int getspent_r(struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);
int getspnam_r(const char* name, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);
int fgetspent_r(FILE* fp, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);
int sgetspent_r(const char* s, struct spwd* spbuf, char* buf, size_t buflen, struct spwd** spbufp);
其中的struct spwd定義如下:
struct spwd
{
char* sp_namp; /* 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 */
};
getspnam程序用例:
#include <stdio.h>
#include <shadow.h>
#include <errno.h>
#include <string.h>
int main(int argc, char* argv[])
{
struct spwd* pwd = getspnam("alex_my");
if(!pwd)
{
printf("getspnam failed, error: [%d] [%s]\n", errno, strerror(errno));
return 1;
}
printf("name: %s\t password: %s\n", pwd->sp_namp, pwd->sp_pwdp);
return 0;
}
如果在普通賬號下運行,就會發生錯誤,因爲讀取文件的權限不夠。
3 group file
位於/etc/group
有以下函數可以操作:
#include <sys/types.h>
#include <grp.h>
struct group *getgrnam(const char *name);
struct group *getgrgid(gid_t gid);
int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result);
int getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result);
用法可以參考passwd file
用戶在登陸的時候,就會獲取到group ID,屬於某一個group,可以通過命令來改變所屬的組。但總體來說不方便。
於是,出現了supplementary group IDs(附加組ID)。
4 獲取本地主機名
#include <unistd.h>
int gethostname(char* name, size_t namelen);
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
char name[256] = { 0 };
gethostname(name, sizeof(name));
printf("name: %s\n", name);
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.