|
41 | 41 |
|
42 | 42 | #include "uti/sge_uidgid.h" |
43 | 43 |
|
| 44 | +#include <cassert> |
44 | 45 | #include <cstdio> |
45 | 46 | #include <cstdlib> |
46 | 47 | #include <cerrno> |
@@ -1308,6 +1309,87 @@ ocs_get_groups(int *amount, ocs_grp_elem_t **grp_array, char *err_str, int err_s |
1308 | 1309 | DRETURN(true); |
1309 | 1310 | } |
1310 | 1311 |
|
| 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 | + |
1311 | 1393 | /** |
1312 | 1394 | * @brief Fills a dstring with the information about user, group, supplementary group's similar to the id-command. |
1313 | 1395 | * |
|
0 commit comments