1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2020, Vaisala Oyj.
4 */
5
6 #include <teeacl.h>
7
8 #include <errno.h>
9 #include <grp.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14
teeacl_getgr_r_size_max(void)15 static long teeacl_getgr_r_size_max(void)
16 {
17 long s = sysconf(_SC_GETGR_R_SIZE_MAX);
18
19 if (s == -1)
20 return 1024;
21 return s;
22 };
23
teeacl_gid_from_name(gid_t * gid_out,const char * group_name)24 int teeacl_gid_from_name(gid_t *gid_out, const char *group_name)
25 {
26 struct group grp = { 0 };
27 char *buffer = NULL;
28 struct group *result = NULL;
29 size_t b_size = 0;
30 int rv = 0;
31
32 b_size = teeacl_getgr_r_size_max();
33 buffer = calloc(1, b_size);
34 if (!buffer)
35 return -ENOMEM;
36
37 rv = getgrnam_r(group_name, &grp, buffer, b_size, &result);
38
39 free(buffer);
40 if (!result) {
41 if (rv == 0)
42 return -ENOENT;
43 else
44 return rv;
45 } else {
46 *gid_out = grp.gr_gid;
47 return 0;
48 }
49 }
50
teeacl_current_user_is_member_of(gid_t group)51 enum rv_groupmember teeacl_current_user_is_member_of(gid_t group)
52 {
53 char username[L_cuserid] = { 0 };
54
55 cuserid(username);
56 return teeacl_user_is_member_of(username, group);
57 }
58
teeacl_user_is_member_of(const char * user,gid_t group)59 enum rv_groupmember teeacl_user_is_member_of(const char *user, gid_t group)
60 {
61 enum rv_groupmember result = E_MEMORY;
62 int ret = 0;
63 int i = 0;
64 int grouplistsize = 8; /* initial guess */
65 gid_t *p_groups = NULL;
66 gid_t *groups = calloc(grouplistsize, sizeof(gid_t));
67
68 if (!groups)
69 return E_MEMORY;
70 ret = getgrouplist(user, group, groups, &grouplistsize);
71
72 if (ret == -1) {
73 p_groups = groups;
74
75 groups = reallocarray(groups, grouplistsize, sizeof(gid_t));
76 if (!groups) {
77 free(p_groups);
78 return E_MEMORY;
79 }
80 ret = getgrouplist(user, group, groups, &grouplistsize);
81 if (ret == -1) {
82 result = E_GROUPLIST;
83 goto out;
84 }
85 }
86
87 for (i = 0; i < grouplistsize; ++i) {
88 if (group == groups[i]) {
89 result = IS_MEMBER;
90 goto out;
91 }
92 }
93 result = NOT_MEMBER;
94 out:
95 free(groups);
96 return result;
97 }
98