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

    xiaoxiao2021-03-25  943

    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)习题

    转载请注明原文地址: https://ju.6miu.com/read-5381.html

    最新回复(0)