1 // Copyright 2015 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "brillo/userdb_utils.h"
6
7 #include <errno.h>
8 #include <grp.h>
9 #include <pwd.h>
10 #include <sys/types.h>
11 #include <unistd.h>
12
13 #include <vector>
14
15 #include <base/logging.h>
16 #include <base/posix/safe_strerror.h>
17
18 namespace brillo {
19 namespace userdb {
20
GetUserInfo(const std::string & user,uid_t * uid,gid_t * gid)21 bool GetUserInfo(const std::string& user, uid_t* uid, gid_t* gid) {
22 ssize_t buf_len = sysconf(_SC_GETPW_R_SIZE_MAX);
23 if (buf_len < 0)
24 buf_len = 16384; // 16K should be enough?...
25 passwd pwd_buf;
26 passwd* pwd = nullptr;
27 std::vector<char> buf(buf_len);
28
29 int err_num;
30 do {
31 err_num = getpwnam_r(user.c_str(), &pwd_buf, buf.data(), buf_len, &pwd);
32 } while (err_num == EINTR);
33
34 if (!pwd) {
35 LOG(ERROR) << "Unable to find user " << user << ": "
36 << (err_num ? base::safe_strerror(err_num)
37 : "No matching record");
38 return false;
39 }
40
41 if (uid)
42 *uid = pwd->pw_uid;
43 if (gid)
44 *gid = pwd->pw_gid;
45 return true;
46 }
47
GetGroupInfo(const std::string & group,gid_t * gid)48 bool GetGroupInfo(const std::string& group, gid_t* gid) {
49 ssize_t buf_len = sysconf(_SC_GETGR_R_SIZE_MAX);
50 if (buf_len < 0)
51 buf_len = 16384; // 16K should be enough?...
52 struct group grp_buf;
53 struct group* grp = nullptr;
54 std::vector<char> buf(buf_len);
55
56 int err_num;
57 do {
58 err_num = getgrnam_r(group.c_str(), &grp_buf, buf.data(), buf_len, &grp);
59 } while (err_num == EINTR);
60
61 if (!grp) {
62 LOG(ERROR) << "Unable to find group " << group << ": "
63 << (err_num ? base::safe_strerror(err_num)
64 : "No matching record");
65 return false;
66 }
67
68 if (gid)
69 *gid = grp->gr_gid;
70 return true;
71 }
72
73 } // namespace userdb
74 } // namespace brillo
75