xref: /aosp_15_r20/external/libbrillo/brillo/userdb_utils.cc (revision 1a96fba65179ea7d3f56207137718607415c5953)
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