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