APIERR MNetGroupEnum( const TCHAR FAR * pszServer, UINT Level, BYTE FAR ** ppbBuffer, UINT FAR * pcEntriesRead ) { APIERR err; USHORT cbTotalAvail; // get a 4K buffer *ppbBuffer = MNetApiBufferAlloc(BIG_BUFFER_SIZE); if (*ppbBuffer == NULL) { return(ERROR_NOT_ENOUGH_MEMORY); } err = NetGroupEnum(pszServer, Level, *ppbBuffer, BIG_BUFFER_SIZE, pcEntriesRead, & cbTotalAvail); // is there more data? if so, allocate a big enough buffer to get it if(err == ERROR_MORE_DATA || err == NERR_BufTooSmall) { MNetApiBufferFree(ppbBuffer); *ppbBuffer = MNetApiBufferAlloc( FULL_SEG_BUFFER_SIZE ); if( *ppbBuffer == NULL ) { return(ERROR_NOT_ENOUGH_MEMORY); } err = NetGroupEnum(pszServer, Level, *ppbBuffer, FULL_SEG_BUFFER_SIZE, pcEntriesRead, & cbTotalAvail); } // If we're returning an error that's not moredata, or there are no // entries to return, free the buffer first if ((err && err != ERROR_MORE_DATA && err != NERR_BufTooSmall) || *pcEntriesRead == 0) { MNetApiBufferFree(ppbBuffer); } return (err); } // MNetGroupEnum
USHORT MNetGroupEnum ( const CHAR FAR * pszServer, SHORT Level, CHAR FAR ** ppBuffer, USHORT FAR * pcEntriesRead ) { USHORT usReturnCode, cbTotalAvail; SEL sel; // get a 4K buffer *ppBuffer = MGetBuffer(BIG_BUFFER_SIZE); if (*ppBuffer == NULL) { return(ERROR_NOT_ENOUGH_MEMORY); } usReturnCode = NetGroupEnum(pszServer, Level, *ppBuffer, BIG_BUFFER_SIZE, pcEntriesRead, & cbTotalAvail); // is there more data? if so, allocate a big enough buffer to get it if(usReturnCode == ERROR_MORE_DATA || usReturnCode == NERR_BufTooSmall) { NetApiBufferFree(*ppBuffer); if (DEBUGALLOC(FULL_SEG_BUFFER_SIZE, & sel, SEG_NONSHARED)) { return(ERROR_NOT_ENOUGH_MEMORY); } *ppBuffer = MAKEP(sel, 0); usReturnCode = NetGroupEnum(pszServer, Level, *ppBuffer, FULL_SEG_BUFFER_SIZE, pcEntriesRead, & cbTotalAvail); } // If we're returning an error that's not moredata, or there are no // entries to return, free the buffer first if ((usReturnCode && usReturnCode != ERROR_MORE_DATA && usReturnCode != NERR_BufTooSmall) || *pcEntriesRead == 0) { NetApiBufferFree(*ppBuffer); } return (usReturnCode); }
static int get_all_global_groups(struct oscap_list *list) { NET_API_STATUS status; GROUP_INFO_0 *buffer = NULL; DWORD preffered_max_len = MAX_PREFERRED_LENGTH; DWORD entries_read = 0; DWORD total_entries = 0; DWORD resume_handle = 0; status = NetGroupEnum(NULL, 0, (LPBYTE *)&buffer, preffered_max_len, &entries_read, &total_entries, &resume_handle); if (status != NERR_Success) { dD("NetGroupEnum failed: %d", status); return 1; } for (DWORD i = 0; i < entries_read; i++) { WCHAR *group_name = buffer[i].grpi0_name; oscap_list_add(list, wcsdup(group_name)); } NetApiBufferFree(buffer); return 0; }
static NET_API_STATUS test_netgroupenum(const char *hostname, uint32_t level, const char *groupname) { NET_API_STATUS status; uint32_t entries_read = 0; uint32_t total_entries = 0; uint32_t resume_handle = 0; int found_group = 0; const char *current_name = NULL; uint8_t *buffer = NULL; int i; struct GROUP_INFO_0 *info0 = NULL; struct GROUP_INFO_1 *info1 = NULL; struct GROUP_INFO_2 *info2 = NULL; struct GROUP_INFO_3 *info3 = NULL; printf("testing NetGroupEnum level %d\n", level); do { status = NetGroupEnum(hostname, level, &buffer, 120, /*(uint32_t)-1, */ &entries_read, &total_entries, &resume_handle); if (status == 0 || status == ERROR_MORE_DATA) { switch (level) { case 0: info0 = (struct GROUP_INFO_0 *)buffer; break; case 1: info1 = (struct GROUP_INFO_1 *)buffer; break; case 2: info2 = (struct GROUP_INFO_2 *)buffer; break; case 3: info3 = (struct GROUP_INFO_3 *)buffer; break; default: return -1; } for (i=0; i<entries_read; i++) { switch (level) { case 0: current_name = info0->grpi0_name; break; case 1: current_name = info1->grpi1_name; break; case 2: current_name = info2->grpi2_name; break; case 3: current_name = info3->grpi3_name; break; default: break; } if (strcasecmp(current_name, groupname) == 0) { found_group = 1; } switch (level) { case 0: info0++; break; case 1: info1++; break; case 2: info2++; break; case 3: info3++; break; } } NetApiBufferFree(buffer); } } while (status == ERROR_MORE_DATA); if (status) { return status; } if (!found_group) { printf("failed to get group\n"); return -1; } return 0; }
static void enum_groups (domlist_t *mach, const char *sep, DWORD id_offset, char *disp_groupname, int print_current) { WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1]; GROUP_INFO_2 *buffer; DWORD entriesread = 0; DWORD totalentries = 0; DWORD_PTR resume_handle = 0; WCHAR gname[GNLEN + 1]; DWORD rc; int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1); if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1) { fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n", program_invocation_short_name, mach->str); return; } do { DWORD i; if (disp_groupname != NULL) { mbstowcs (gname, disp_groupname, GNLEN + 1); rc = NetGroupGetInfo (machine, (LPWSTR) & gname, 2, (void *) &buffer); entriesread=1; /* Avoid annoying error messages just because the group hasn't been found. */ if (rc == NERR_GroupNotFound) return; } else rc = NetGroupEnum (machine, 2, (void *) & buffer, MAX_PREFERRED_LENGTH, &entriesread, &totalentries, &resume_handle); switch (rc) { case ERROR_ACCESS_DENIED: print_win_error (rc); return; case ERROR_MORE_DATA: case ERROR_SUCCESS: break; default: print_win_error (rc); return; } for (i = 0; i < entriesread; i++) { WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1]; DWORD domname_len = MAX_DOMAIN_NAME_LEN + 1; char psid_buffer[MAX_SID_LEN]; PSID psid = (PSID) psid_buffer; DWORD sid_length = MAX_SID_LEN; SID_NAME_USE acc_type; int gid = buffer[i].grpi2_group_id; if (!LookupAccountNameW (machine, buffer[i].grpi2_name, psid, &sid_length, domain_name, &domname_len, &acc_type)) { print_win_error (GetLastError ()); fprintf(stderr, " (%ls)\n", buffer[i].grpi2_name); continue; } else if (acc_type == SidTypeDomain) { WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2]; wcscpy (domname, machine); wcscat (domname, L"\\"); wcscat (domname, buffer[i].grpi2_name); sid_length = MAX_SID_LEN; domname_len = MAX_DOMAIN_NAME_LEN + 1; if (!LookupAccountNameW (machine, domname, psid, &sid_length, domain_name, &domname_len, &acc_type)) { print_win_error (GetLastError ()); fprintf(stderr, " (%ls)\n", domname); continue; } } if (!print_current) /* fall through */; else if (EqualSid (curr_pgrp.psid, psid)) got_curr_pgrp = TRUE; printf ("%ls%s%ls:%s:%" PRIu32 ":\n", mach->with_dom ? domain_name : L"", mach->with_dom ? sep : "", buffer[i].grpi2_name, put_sid (psid), (unsigned int) (id_offset + gid)); } NetApiBufferFree (buffer); } while (rc == ERROR_MORE_DATA); }