Skip to content

Commit 80c0b0d

Browse files
committed
BF: CS-1141: MacOS build broken due to getgrouplist() deviation
1 parent 6cbbb5a commit 80c0b0d

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

source/libs/uti/sge_uidgid.cc

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
#include "uti/sge_uidgid.h"
4343

44+
#include <cassert>
4445
#include <cstdio>
4546
#include <cstdlib>
4647
#include <cerrno>
@@ -1308,6 +1309,87 @@ ocs_get_groups(int *amount, ocs_grp_elem_t **grp_array, char *err_str, int err_s
13081309
DRETURN(true);
13091310
}
13101311

1312+
/**
1313+
* @brief returns supplementary group ids for a specific user
1314+
*
1315+
* @param user user name
1316+
* @param gid gid of the user
1317+
* @param amount used to return the number of group ids
1318+
* @param grp_array used to return the array of group ids
1319+
* @param error_dstr dstring to return error messages
1320+
* @return true if the supplementary group information could be retrieved, else false (and error_dstr contains the reason)
1321+
*/
1322+
bool
1323+
ocs_get_groups(const char *user, gid_t gid, int *amount, ocs_grp_elem_t **grp_array, dstring *error_dstr) {
1324+
DENTER(TOP_LAYER);
1325+
bool ret = true;
1326+
1327+
if (amount == nullptr) {
1328+
sge_dstring_sprintf(error_dstr, "invalid input parameter (amount).");
1329+
DRETURN(false);
1330+
}
1331+
if (grp_array == nullptr) {
1332+
sge_dstring_sprintf(error_dstr, "invalid input parameter (grp_array).");
1333+
DRETURN(false);
1334+
}
1335+
1336+
// get maximum amount of supplementary group IDs
1337+
int max_groups = static_cast<int>(sge_sysconf(SGE_SYSCONF_NGROUPS_MAX));
1338+
if (max_groups == -1) {
1339+
sge_dstring_sprintf(error_dstr, "sge_sysconf(SGE_SYSCONF_NGROUPS_MAX) failed.");
1340+
DRETURN(false);
1341+
}
1342+
1343+
// allocate buffer for group IDs
1344+
auto *grp_id_list = reinterpret_cast<gid_t *>(sge_malloc(max_groups * sizeof(gid_t)));
1345+
if (grp_id_list == nullptr) {
1346+
sge_dstring_sprintf(error_dstr, "Unable to allocate buffer that should hold group IDs");
1347+
DRETURN(false);
1348+
}
1349+
1350+
// fetch group IDs
1351+
#ifdef DARWIN
1352+
static_assert(sizeof(gid_t) == sizeof(int), "Size of gid_t does not match that of type int!");
1353+
int num_group_ids = getgrouplist(user, static_cast<int>(gid), reinterpret_cast<int *>(grp_id_list), &max_groups);
1354+
#else
1355+
int num_group_ids = getgrouplist(user, gid, grp_id_list, &max_groups);
1356+
#endif
1357+
if (num_group_ids == -1) {
1358+
sge_dstring_sprintf(error_dstr, "getgrouplist() failed.");
1359+
sge_free(&grp_id_list);
1360+
DRETURN(false);
1361+
}
1362+
if (num_group_ids == 0) {
1363+
// success case: user has no supplementary groups (this case probably does not exist)
1364+
*amount = 0;
1365+
*grp_array = nullptr;
1366+
sge_free(&grp_id_list);
1367+
DRETURN(true);
1368+
}
1369+
1370+
// fetch group names and store them with corresponding IDs in the array to be returned
1371+
auto array = reinterpret_cast<ocs_grp_elem_t *>(sge_malloc(num_group_ids * sizeof(ocs_grp_elem_t)));
1372+
if (array == nullptr) {
1373+
sge_dstring_sprintf(error_dstr, "Unable to allocate buffer that should hold group information");
1374+
sge_free(&grp_id_list);
1375+
DRETURN(false);
1376+
}
1377+
for (int i = 0; i < num_group_ids; i++) {
1378+
// try to get the name
1379+
array[i].id = grp_id_list[i];
1380+
int lret = sge_gid2group(grp_id_list[i], array[i].name, MAX_STRING_SIZE, 1);
1381+
1382+
// non-resolvable groups are no error. also OCS uses GIDs without name for job tracing
1383+
if (lret != 0) {
1384+
snprintf(array[i].name, MAX_STRING_SIZE, gid_t_fmt, grp_id_list[i]);
1385+
}
1386+
}
1387+
sge_free(&grp_id_list);
1388+
*amount = num_group_ids;
1389+
*grp_array = array;
1390+
DRETURN(ret);
1391+
}
1392+
13111393
/**
13121394
* @brief Fills a dstring with the information about user, group, supplementary group's similar to the id-command.
13131395
*

0 commit comments

Comments
 (0)