UINT initializeAfsAdminGroup(void) { PSID psidAdmin = NULL; SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY; NET_API_STATUS status; LOCALGROUP_MEMBERS_INFO_0 *gmAdmins = NULL; DWORD dwNEntries, dwTEntries; WCHAR AdminGroupName[UNLEN+1]; DWORD cchName = UNLEN; if (!LookupAliasFromRid( NULL, DOMAIN_ALIAS_RID_ADMINS, AdminGroupName, &cchName )) { /* if we fail, we will try the English string "Administrators" */ wcsncpy(AdminGroupName, L"Administrators", UNLEN+1); AdminGroupName[UNLEN] = 0; } status = NetLocalGroupGetMembers(NULL, AdminGroupName, 0, (LPBYTE *) &gmAdmins, MAX_PREFERRED_LENGTH, &dwNEntries, &dwTEntries, NULL); if(status) return status; status = NetLocalGroupAddMembers(NULL, AFSCLIENT_ADMIN_GROUPNAMEW, 0, (LPBYTE) gmAdmins, dwNEntries); NetApiBufferFree( gmAdmins ); return status; }
static int get_local_group_members(WCHAR *group_name, struct oscap_list *list) { NET_API_STATUS status; LOCALGROUP_MEMBERS_INFO_1 *buffer = NULL; DWORD preffered_max_len = MAX_PREFERRED_LENGTH; DWORD entries_read = 0; DWORD total_entries = 0; DWORD resume_handle = 0; status = NetLocalGroupGetMembers(NULL, group_name, 1, (LPBYTE *) &buffer, preffered_max_len, &entries_read, &total_entries, &resume_handle); if (status != NERR_Success) { dD("NetLocalGroupGetMembers failed: %d", status); return 1; } for (DWORD i = 0; i < entries_read; i++) { WCHAR *member_name = buffer[i].lgrmi1_name; oscap_list_add(list, wcsdup(member_name)); } NetApiBufferFree(buffer); return 0; }
gboolean Usercheck_IsAdminMember(const gchar *userName) { NET_API_STATUS status; gunichar2 *userNameW = NULL; LOCALGROUP_MEMBERS_INFO_1 *groupList; DWORD entriesRead; DWORD totalEntries; DWORD i; gboolean bRetVal = FALSE; BOOL ok; DWORD lastError; WCHAR *accountW = NULL; WCHAR *domainW = NULL; DWORD accountChar2Needed = 0; DWORD domainChar2Needed = 0; SID_NAME_USE eUse; PSID pSid = NULL; /* * XXX Should this cache some (all?) of the returned data for a perf boost? * Or does that open up bugs (security or other) where it might * change while the service is running? The name of the group changing * seems unlikely; member changing less so. */ /* * To avoid localization issues, start with the Administrators group's SID, * and find the name to pass to NetLocalGroupGetMembers to get * the group members. */ pSid = WinUtil_GroupAdminSid(); ok = LookupAccountSidW(NULL, pSid, NULL, &accountChar2Needed, NULL, &domainChar2Needed, &eUse); ASSERT(!ok); lastError = GetLastError(); if (lastError != ERROR_INSUFFICIENT_BUFFER) { VGAUTH_LOG_ERR_WIN_CODE(lastError, "LookupAccountSidW() failed"); goto done; } ASSERT(accountChar2Needed > 0); ASSERT(domainChar2Needed > 0); accountW = (WCHAR *) g_malloc0(accountChar2Needed * sizeof(WCHAR)); domainW = (WCHAR *) g_malloc0(domainChar2Needed * sizeof(WCHAR)); ok = LookupAccountSidW(NULL, pSid, accountW, &accountChar2Needed, domainW, &domainChar2Needed, &eUse); if (!ok) { VGAUTH_LOG_ERR_WIN("LookupAccountSidW failed"); goto done; } /* * Since the query is being done on the local server, the domain * return value shouldn't matter (and should be 'BUILTIN'). */ // get everything in one shot status = NetLocalGroupGetMembers(NULL, // server name accountW, // group name 1, // level (LPBYTE *) &groupList, // return buffer MAX_PREFERRED_LENGTH, // get it all &entriesRead, &totalEntries, NULL); // resume handle if (status != NERR_Success) { VGAUTH_LOG_ERR_WIN_CODE(status, "NetLocalGroupGetMembers() failed"); goto done; } CHK_UTF8_TO_UTF16(userNameW, userName, goto done); for (i = 0; i < entriesRead; i++) { #ifdef VMX86_DEBUG g_debug("%s: checking input %S against group member #%d %S\n", __FUNCTION__, userNameW, i, groupList[i].lgrmi1_name); #endif if (_wcsicmp(userNameW, groupList[i].lgrmi1_name) == 0) { bRetVal = TRUE; goto done; } } done: g_free(pSid); if (groupList) { NetApiBufferFree(groupList); } g_free(userNameW); g_free(accountW); g_free(domainW); return bRetVal; }
// // Determines if user is a member of the local group group_name // // 1 = yes, 0 = no, -1 = error // int perm::userInLocalGroup( const char *account, const char *domain, const char *group_name ) { LOCALGROUP_MEMBERS_INFO_3 *buf, *cur; // group members output buffer pointers dprintf(D_FULLDEBUG,"in perm::userInLocalGroup() looking at group '%s'\n", (group_name) ? group_name : "NULL"); unsigned long entries_read; unsigned long total_entries; NET_API_STATUS status; wchar_t group_name_unicode[MAX_GROUP_LENGTH+1]; _snwprintf(group_name_unicode, MAX_GROUP_LENGTH+1, L"%S", group_name); DWORD_PTR resume_handle = 0; do { // loop until we have checked all the group members status = NetLocalGroupGetMembers ( NULL, // servername group_name_unicode, // name of group 3, // information level (BYTE**) &buf, // pointer to buffer that receives data 16384, // preferred length of data &entries_read, // number of entries read &total_entries, // total entries available &resume_handle // resume handle ); switch ( status ) { case ERROR_ACCESS_DENIED: dprintf(D_ALWAYS, "perm::NetLocalGroupGetMembers failed: ERROR_ACCESS_DENIED\n"); NetApiBufferFree( buf ); dprintf(D_ALWAYS, "perm::NetLocalGroupGetMembers failed: (total entries: %d, entries read: %d )\n", total_entries, entries_read ); return -1; break; case NERR_InvalidComputer: dprintf(D_ALWAYS, "perm::NetLocalGroupGetMembers failed: ERROR_InvalidComputer\n"); NetApiBufferFree( buf ); dprintf(D_ALWAYS, "perm::NetLocalGroupGetMembers failed: (total entries: %d, entries read: %d )\n", total_entries, entries_read ); return -1; break; case ERROR_NO_SUCH_ALIAS: dprintf(D_ALWAYS, "perm::NetLocalGroupGetMembers failed: ERROR_NO_SUCH_ALIAS\n"); NetApiBufferFree( buf ); dprintf(D_ALWAYS, "perm::NetLocalGroupGetMembers failed: (total entries: %d, entries read: %d )\n", total_entries, entries_read ); return -1; break; } DWORD i; for ( i = 0, cur = buf; i < entries_read; ++ i, ++ cur ) { wchar_t* member_unicode = cur->lgrmi3_domainandname; // convert unicode string to ansi string char member[MAX_DOMAIN_LENGTH+MAX_ACCOUNT_LENGTH+2]; // domain+acct+slash+null snprintf(member, MAX_DOMAIN_LENGTH+MAX_ACCOUNT_LENGTH+2, "%S", member_unicode); // compare domain and name to find a match char *member_name, *member_domain; getDomainAndName( member, member_domain, member_name ); if ( domainAndNameMatch (account, member_name, domain, member_domain) ) { NetApiBufferFree( buf ); return 1; } } } while ( status == ERROR_MORE_DATA ); // having exited the for loop without finding anything, we conclude // that the account does not exist in the explicit access structure NetApiBufferFree( buf ); return 0; } // end if is a local group