1253
1266
struct winbindd_response response;
1254
1267
struct winbindd_request request;
1255
1268
NSS_STATUS ret;
1259
1272
gid_t *gid_list;
1260
char *r_user = user;
1273
char *r_user = NULL;
1274
FILE *groups_file = NULL;
1275
size_t num_local_gids = 0;
1276
size_t local_gid_list_capacity = 0;
1277
gid_t *local_gid_list = NULL;
1278
struct group group_buffer;
1279
char *aux_buffer = NULL;
1280
size_t aux_buffer_size = 2048;
1282
size_t member_index = 0;
1262
1284
if (*user == WB_AIX_ENCODED) {
1263
r_user = decode_user(r_user);
1285
r_user = decode_user(user);
1266
1290
logit_debug(LOG_DEBUG, "getgrset %s '%s'\n", user, r_user);
1273
ZERO_STRUCT(response);
1274
ZERO_STRUCT(request);
1297
ZERO_STRUCT(response);
1298
ZERO_STRUCT(request);
1276
1300
STRCPY_RETNULL(request.data.username, r_user);
1278
if (*user == WB_AIX_ENCODED) {
1282
1302
ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
1284
1304
HANDLE_ERRORS(ret);
1286
1306
num_gids = response.data.num_entries;
1287
1307
gid_list = (gid_t *)response.extra_data.data;
1309
/* Now search the local groups file to get a count of the local groups
1310
* the user is a member of.
1312
groups_file = fopen("/etc/group", "r");
1313
if (groups_file != NULL)
1315
aux_buffer = (char*) malloc(aux_buffer_size);
1316
if (aux_buffer == NULL) {
1322
/* There is no man page for fgetgrent_r on AIX. The Linux man page
1323
* says this function's last parameter is an out parameter for the
1324
* result, but on AIX it is an int which doesn't seem to be used
1325
* for anything, so I set it to 0.
1327
ret_errno = fgetgrent_r(groups_file, &group_buffer,
1328
aux_buffer, aux_buffer_size, 0);
1329
/* On Linux this function returns an errno value directly. On AIX,
1330
* it seems to return -1 and set the errno global.
1336
/* On Linux, ENOENT is returned when no more results are
1337
* available. On AIX, ESRCH is returned.
1339
if (ret_errno == ENOENT || ret_errno == ESRCH)
1344
if (ret_errno == ERANGE || ret_errno == EINVAL)
1346
/* The buffer is too small */
1347
if (aux_buffer_size > 1000000)
1349
/* We're not willing to give more space than that */
1350
logit_debug(LOG_DEBUG,
1351
"fgetgrent_r is requesting too much memory\n");
1357
aux_buffer_size *= 2;
1358
aux_buffer = (char*) malloc(aux_buffer_size);
1359
if (aux_buffer == NULL)
1369
logit_debug(LOG_DEBUG,
1370
"getgrset failed to enumerate local groups with error %d\n",
1374
for (member_index = 0;
1375
group_buffer.gr_mem[member_index] != NULL;
1378
if (!strcmp(r_user, group_buffer.gr_mem[member_index]) ||
1379
!strcmp(user, group_buffer.gr_mem[member_index]))
1382
if (num_local_gids >= local_gid_list_capacity)
1384
local_gid_list_capacity += 10;
1385
local_gid_list_capacity *= 2;
1386
local_gid_list = (gid_t *)realloc(local_gid_list,
1387
local_gid_list_capacity * sizeof(gid_t));
1388
if (local_gid_list == NULL)
1394
local_gid_list[num_local_gids++] = group_buffer.gr_gid;
1289
/* allocate a space large enough to contruct the string */
1290
tmpbuf = (char*) list_alloc(list, num_gids*12);
1401
/* allocate a space large enough to construct the string */
1402
tmpbuf = (char*) list_alloc(list, (num_gids + num_local_gids)*12);
1295
for (idx=i=0; i < num_gids-1; i++) {
1296
idx += sprintf(tmpbuf+idx, "%u,", gid_list[i]);
1298
idx += sprintf(tmpbuf+idx, "%u", gid_list[i]);
1409
for (i=0; i < num_gids; i++) {
1414
idx += sprintf(tmpbuf+idx, "%u", gid_list[i]);
1417
for (i=0; i < num_local_gids; i++) {
1422
idx += sprintf(tmpbuf+idx, "%u", local_gid_list[i]);
1427
if (groups_file != NULL)
1429
fclose(groups_file);
1300
1432
winbindd_free_response(&response);
1434
if (*user == WB_AIX_ENCODED) {
1438
if (local_gid_list != NULL) {
1439
free(local_gid_list);
1441
if (aux_buffer != NULL) {
1448
list_realloc(list, tmpbuf, 0);
1692
static int local_getgrgid_r(gid_t gid, struct group *group_buffer,
1693
char *aux_buffer, size_t aux_buffer_size, struct group **result)
1696
FILE *groups_file = NULL;
1699
/* Now search the local groups file to get a count of the local groups
1700
* the user is a member of.
1702
groups_file = fopen("/etc/group", "r");
1703
if (groups_file != NULL)
1707
/* There is no man page for fgetgrent_r on AIX. The Linux man page
1708
* says this function's last parameter is an out parameter for the
1709
* result, but on AIX it is an int which doesn't seem to be used
1710
* for anything, so I set it to 0.
1712
error = fgetgrent_r(groups_file, group_buffer,
1713
aux_buffer, aux_buffer_size, 0);
1714
/* On Linux this function returns an errno value directly. On AIX,
1715
* it seems to return -1 and set the errno global.
1721
/* On Linux, ENOENT is returned when no more results are
1722
* available. On AIX, ESRCH is returned.
1728
if (group_buffer->gr_gid == gid)
1730
*result = group_buffer;
1739
if (groups_file != NULL)
1741
fclose(groups_file);
1540
1746
static attrval_t pwd_to_groupsnames(struct mem_list** mlist, struct passwd *pwd)
1568
1777
gid = strtok_r(NULL, ",", &p)) {
1570
group = __wb_aix_getgrgid(mlist, strtoul(gid, NULL, 10));
1779
group = __wb_aix_getgrgid(local_list, strtoul(gid, NULL, 10));
1783
local_getgrgid_r(strtoul(gid, NULL, 10), &group_buffer,
1784
aux_buffer, sizeof(aux_buffer), &group);
1788
logit_debug(LOG_DEBUG, "Unable to lookup group id %s\n", gid);
1572
1791
len = strlen(group->gr_name);
1574
1793
/* See if we have enought memory */