The Linux Programming Interface 08 Users And Groups 用户和组

The Linux Programming Interface

Users And Groups

(01)用户和组

Every user has a unique login name and an associated numeric user identifier (UID). Users can belong to one or more groups. Each group also has a unique name and a group identifier(GID).

(02) /etc/passwd文件

放有用户名,登录ID等信息。

(03) 密码文件 /etc/shadow

The shadow password file, /etc/shadow, was devised as a method of preventing such attacks.

(04) /etc/group

组函数文件夹

(05)获取用户和组信息

#include <pwd.h>

struct passwd *getpwnam(const char *name);

struct passwd *getpwuid(uid_t uid);

Given a login name in name, the getpwnam() function returns a pointer to a structure of the following type, containing the corresponding information from the password record:

struct passwd {
    char *pw_name;	/* Login name (username) */
    char *pw_passwd;	/* Encrypted password */
    uid_t pw_uid;	/* User ID */
    gid_t pw_gid;	/* Group ID */
    char *pw_gecos;	/* Comment (user information) */
    char *pw_dir;	/* Initial working (home) directory */
    char *pw_shell;	/* Login shell */
};

(06) getpwnam, getpwuid, getgrnam, getgrgid举例

通过uid 得到name, 通过name 得到uid,还有组。

#include <pwd.h>
#include <grp.h>
#include <ctype.h>
#include "ugid_functions.h"	/* Declares functions defined here */

/* Return name corresponding to 'uid', or NULL on error */
char * userNameFromId(uid_t uid) {
	struct passwd *pwd;
	pwd = getpwuid(uid);
	return (pwd == NULL) ? NULL : pwd->pw_name;
}

/* Return UID corresponding to 'name', or -1 on error */
uid_t userIdFromName(const char *name) {
	struct passwd *pwd;
	uid_t u;
	char *endptr;
	if (name == NULL || *name == '\0')
		return -1;
	u = strtol(name, &endptr, 10)
	if (*endptr == '\0')
		return u;
	
	pwd = getpwnam(name);
	if (pwd == NULL)
		return -1;
	return pwd->pw_uid;
}

/* Return name corresponding to 'gid', or NULL on error */
char *groupNameFromId(git_t gid) {
	struct group *grp;
	grp = getgrpid(gid);
	return (grp == NULL) ? NULL : grp->gr_name;
}

/* Return GID corresponding to 'name', or -1 on error */
gid_t groupIdFromName(const char *name) {
	struct group *grp;
	gid_t g;
	char *endptr;
	
	if (name == NULL || *name == '\0')
		return -1;
	g = strtol(name, &endptr, 10)
	if (*endptr == '\0')
		return g;

	grp = getgrnam(name);
	if (grp == NULL)
		return -1;
    return grp->gr_gid;
}

(07)得到所有的信息

#include <pwd.h>
#include <stdio.h>

int main() {
    struct passwd *pwd;
    while ((pwd = getpwent()) != NULL)
        printf("%-8s %5ld\n", pwd->pw_name, (long) pwd->pw_uid);
    return 0;
}

输出:

wang@wang:~/Documents/tlpi-dist/users_groups$ ./getall
root         0
daemon       1
bin          2
sys          3
sync         4
games        5
man          6
lp           7
mail         8
news         9
uucp        10
proxy       13
www-data    33
backup      34
list        38
irc         39
gnats       41
nobody   65534
systemd-timesync   100
systemd-network   101
systemd-resolve   102
systemd-bus-proxy   103
syslog     104
_apt       105
messagebus   106
uuidd      107
lightdm    108
whoopsie   109
avahi-autoipd   110
avahi      111
dnsmasq    112
colord     113
speech-dispatcher   114
hplip      115
kernoops   116
pulse      117
rtkit      118
saned      119
usbmux     120
wang      1000

(08) 组

The getgrent(), setgrent(), and endgrent() functions perform analogous tasks fro the group file.

(09)验证登录,结果是没有权限。

#define _BSD_SOURCE		/* Get getpass() declaration from <unisstd.h> */
#include <limits.h>
#include <pwd.h>
#include <shadow.h>
#include "tlpi_hdr.h"

#define _XOPEN_SOURCE       /* See feature_test_macros(7) */
#include <unistd.h>

int main(int argc, char *argv[]) {
	char *username, *password, *encrypted, *p;
	struct passwd *pwd;
	struct spwd *spwd;
	Boolean authOk;
	size_t len;
	long lnmax;
	lnmax = sysconf(_SC_LOGIN_NAME_MAX);
	if (lnmax == -1)
		lnmax = 256;
	
	username = malloc(lnmax);
	if (username == NULL)
		errExit("malloc");
	
	printf("Username: ");
	fflush(stdout);
	if (fgets(username, lnmax, stdin) == NULL)
		exit(EXIT_FAILURE);
	
	len = strlen(username);	
	if (username[len - 1] == '\n')
		username[len - 1] = '\0';
	
	pwd = getpwnam(username);
	if (pwd == NULL)
		fatal("couldn't get password record");
	
	spwd = getspnam(username);
	if (pwd == NULL)
		fatal("couldn't get password record");
	spwd = getspnam(username);
	if (spwd == NULL && errno == EACCES)
		fatal("no permission to read shadow password file");
	
	/* If there is a shadow password record, use the shadow password */
	if (spwd != NULL)
		pwd->pw_passwd = spwd->sp_pwdp;
	
	password = getpass("Password: ");

	/* Encrypt password and erase cleartext version immediately */
	encrypted = crypt(password, pwd->pw_passwd);
	for (p = password; *p != '\0';)
		*p++ = '\0';
	
	if (encrypted == NULL)
		errExit("crypt");

	authOk = strcmp(encrypted, pwd->pw_passwd) == 0;
	if (!authOk) {
		printf("Incorrect password\n");
		exit(EXIT_FAILURE);
	}
	printf("Successfully authenticated: UID=%ld\n", (long) pwd->pw_uid);

	/* Now do authenticated work ... */
	exit(EXIT_SUCCESS);
}
有些悲催的输出:

wang@wang:~/Documents/tlpi-dist/lib$ ./check_password
Username: wang
ERROR: no permission to read shadow password file

(10)总结

Each user has a unique login name and an associated numeric user ID. Users can belong to one or more groups, each of which also has a unique name and an associated numeric numeric identifier. The primary purpose of these identifiers is to establish ownership of various system resources (e.g., files) and permissions for accessing them.

A user's name and ID are defined in the /etc/passwd file, which also contains others information about the user. A user's group membership are defined by fields in the /etc/passwd/ and /etc/group files. A furher file, /etc/shadow, which can be read only by privileged processes, is used to separate the sensitive password information from the publicly available user information in /etc/passwd. Various library functions are provided for retrieving information from each of these files.

    The crypt() function encrypts a passwd in the same manner as the standard login program, which is useful for program that need to authenticate users.

(11)习题


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值