static int get_user_local_groups(WCHAR *user, struct oscap_list *list) { NET_API_STATUS status; LOCALGROUP_USERS_INFO_0 *buffer = NULL; DWORD preffered_max_len = MAX_PREFERRED_LENGTH; DWORD entries_read = 0; DWORD total_entries = 0; /* * LG_INCLUDE_INDIRECT means the function also returns the names of * the local groups in which the user is indirectly a member (that is, * the user has membership in a global group that is itself a member * of one or more local groups). */ status = NetUserGetLocalGroups(NULL, user, 0, LG_INCLUDE_INDIRECT, (LPBYTE *)&buffer, preffered_max_len, &entries_read, &total_entries); if (status != NERR_Success) { dD("NetUserGetLocalGroups failed: %d", status); return 1; } for (DWORD i = 0; i < entries_read; i++) { WCHAR *group_name = buffer[i].lgrui0_name; oscap_list_add(list, wcsdup(group_name)); } NetApiBufferFree(buffer); return 0; }
std::vector<Group*> UserUtilities::GetUserGroupList(CString strUserName) { std::vector<Group*> lstUserGroups; LOCALGROUP_USERS_INFO_0 *grpInfo = NULL; LOCALGROUP_USERS_INFO_0 *tempgrpInfo = NULL; DWORD entriesRead = 0; DWORD totalEntries = 0; int res = NetUserGetLocalGroups(NULL, strUserName, 0, 0, (LPBYTE*)&grpInfo, MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries); if(entriesRead > 0) { tempgrpInfo = grpInfo; for(int i = 0;i < entriesRead;i++) { Group* grp = new Group(); grp->m_StrGroupName = tempgrpInfo->lgrui0_name; lstUserGroups.push_back(grp); tempgrpInfo++; } } if(grpInfo) { NetApiBufferFree(grpInfo); grpInfo = NULL; } return lstUserGroups; }
static VOID GetUserMembershipData(HWND hwndDlg, PMEMBERSHIP_USER_DATA pUserData) { NET_API_STATUS status; DWORD dwTotal; DWORD i; HIMAGELIST hImgList; HICON hIcon; LV_ITEM lvi; HWND hwndLV; LV_COLUMN column; RECT rect; hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST); /* Create the image list */ hImgList = ImageList_Create(16, 16, ILC_COLOR8 | ILC_MASK, 5, 5); hIcon = LoadImage(hApplet, MAKEINTRESOURCE(IDI_GROUP), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); ImageList_AddIcon(hImgList, hIcon); DestroyIcon(hIcon); (void)ListView_SetImageList(hwndLV, hImgList, LVSIL_SMALL); /* Set the list column */ GetClientRect(hwndLV, &rect); memset(&column, 0x00, sizeof(column)); column.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM; column.fmt = LVCFMT_LEFT; column.cx = (INT)(rect.right - rect.left); column.iSubItem = 0; (void)ListView_InsertColumn(hwndLV, 0, &column); status = NetUserGetLocalGroups(NULL, pUserData->szUserName, 0, 0, (LPBYTE*)&pUserData->pGroupData, MAX_PREFERRED_LENGTH, &pUserData->dwGroupCount, &dwTotal); if (status != NERR_Success) return; for (i = 0; i < pUserData->dwGroupCount; i++) { ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE; lvi.pszText = pUserData->pGroupData[i].lgrui0_name; lvi.state = 0; lvi.iImage = 0; (void)ListView_InsertItem(hwndLV, &lvi); } }
/*! @brief ユーザグループの取得 (MBCS) */ BOOL CUserInfoDlg::GetGroupNameA(char *UserName, char *dest) { WCHAR wszUserName[256]; // Unicode user name LPBYTE ComputerName = 0; // Convert ASCII user name and domain to Unicode. MultiByteToWideChar(CP_ACP, 0, UserName, strlen(UserName) + 1, wszUserName, sizeof(wszUserName) / sizeof(WCHAR)); // Get the computer name of a DC for the specified domain. BOOL bFoundDC = TRUE; DWORD nRet = NetGetDCName(NULL, NULL, &ComputerName ); if (nRet != NERR_Success) { printf("Error getting group information.\n" ); bFoundDC = FALSE; } LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; // Look up the user on the DC. nRet = NetUserGetLocalGroups((LPWSTR) ComputerName, (LPWSTR) wszUserName, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &pBuf, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries); if (nRet != NERR_Success) { if (bFoundDC == TRUE) { NetApiBufferFree(ComputerName); } printf("Error getting group information.\n" ); return(FALSE ); } if (bFoundDC == TRUE) { NetApiBufferFree(ComputerName); } LPLOCALGROUP_USERS_INFO_0 pTmpBuf = pBuf; for (unsigned int i = 0; i < dwEntriesRead; i++) { if (pTmpBuf == NULL) { fprintf(stderr, "An access violation has occurred\n"); break; } strcat_s(dest, (GNLEN + 1) * 5, ","); char szGroupName[GNLEN + 1]; // Convert the Unicode full name to ASCII. WideCharToMultiByte(CP_ACP, 0, pTmpBuf->lgrui0_name, -1, szGroupName, GNLEN, NULL, NULL ); strcat_s(dest, (GNLEN + 1) * 5, szGroupName); pTmpBuf++; } NetApiBufferFree(pBuf); return (TRUE); }
static VOID AddGroupToUser(HWND hwndDlg, PMEMBERSHIP_USER_DATA pUserData) { HWND hwndLV; NET_API_STATUS status; DWORD i; DWORD dwTotal; LV_ITEM lvi; if (DialogBoxParam(hApplet, MAKEINTRESOURCE(IDD_USER_ADD_MEMBERSHIP), hwndDlg, AddGroupToUserDlgProc, (LPARAM)pUserData) == IDOK) { // TODO: Update Membership list! hwndLV = GetDlgItem(hwndDlg, IDC_USER_MEMBERSHIP_LIST); if (pUserData->pGroupData) NetApiBufferFree(pUserData->pGroupData); (void)ListView_DeleteAllItems(hwndLV); status = NetUserGetLocalGroups(NULL, pUserData->szUserName, 0, 0, (LPBYTE*)&pUserData->pGroupData, MAX_PREFERRED_LENGTH, &pUserData->dwGroupCount, &dwTotal); if (status != NERR_Success) return; for (i = 0; i < pUserData->dwGroupCount; i++) { ZeroMemory(&lvi, sizeof(lvi)); lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_IMAGE; lvi.pszText = pUserData->pGroupData[i].lgrui0_name; lvi.state = 0; lvi.iImage = 0; (void)ListView_InsertItem(hwndLV, &lvi); } } }
void processLocalUserGroups(std::string uid, std::string user, QueryData& results) { unsigned long userGroupInfoLevel = 0; unsigned long numGroups = 0; unsigned long totalUserGroups = 0; LOCALGROUP_USERS_INFO_0* ginfo = nullptr; PSID sid = nullptr; unsigned long ret = 0; ret = NetUserGetLocalGroups(nullptr, stringToWstring(user).c_str(), userGroupInfoLevel, 1, reinterpret_cast<LPBYTE*>(&ginfo), MAX_PREFERRED_LENGTH, &numGroups, &totalUserGroups); if (ret == ERROR_MORE_DATA) { LOG(WARNING) << "User " << user << " group membership exceeds buffer limits, processing " << numGroups << " our of " << totalUserGroups << " groups"; } else if (ret != NERR_Success || ginfo == nullptr) { VLOG(1) << " NetUserGetLocalGroups failed for user " << user << " with " << ret; return; } for (size_t i = 0; i < numGroups; i++) { Row r; auto sid = getSidFromUsername(ginfo[i].lgrui0_name); r["uid"] = uid; r["gid"] = INTEGER(getGidFromSid(static_cast<PSID>(sid.get()))); results.push_back(r); } if (ginfo != nullptr) { NetApiBufferFree(ginfo); } }
/*! @brief ユーザグループの取得 (Unicode) */ BOOL CUserInfoDlg::GetGroupNameW(TCHAR *UserName, TCHAR *dest) { LPBYTE ComputerName = 0; // Get the computer name of a DC for the specified domain. BOOL bFoundDC = TRUE; DWORD nRet = NetGetDCName(NULL, NULL, &ComputerName ); if (nRet != NERR_Success) { printf("Error getting group information.\n" ); bFoundDC = FALSE; } LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; // Look up the user on the DC. nRet = NetUserGetLocalGroups((LPWSTR) ComputerName, (LPWSTR) UserName, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &pBuf, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries); if (nRet != NERR_Success) { if (bFoundDC == TRUE) { NetApiBufferFree(ComputerName); } printf("Error getting group information.\n" ); return (FALSE); } if (bFoundDC == TRUE) { NetApiBufferFree(ComputerName); } LPLOCALGROUP_USERS_INFO_0 pTmpBuf = pBuf; for (unsigned int i = 0; i <dwEntriesRead; i++) { if (pTmpBuf == NULL) { fprintf(stderr, "An access violation has occurred\n"); break; } wcscat_s(dest, (GNLEN + 1) * 5, L","); wcscat_s(dest, (GNLEN + 1) * 5, pTmpBuf->lgrui0_name); pTmpBuf++; } NetApiBufferFree(pBuf); return (TRUE); }
int SetupTokenGroups(PTOKEN_GROUPS *groupsToken, wchar_t *userNameW) { wchar_t **localGroups = NULL; wchar_t **globalGroups = NULL; DWORD nLocalGroups = 0; DWORD nLocalGroupsTot = 0; DWORD nGlobalGroups = 0; DWORD nGlobalGroupsTot = 0; DWORD nGroupsTotal = 0; DWORD size; int i; int exitCode = 1; /* * Retrieve local groups, which user belong to. */ debug("Retrieving local groups list..."); FAIL(NetUserGetLocalGroups(NULL, userNameW, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &localGroups, MAX_PREFERRED_LENGTH, &nLocalGroups, &nLocalGroupsTot)); debug("Retrieving global groups list..."); /* * Retrieve global groups, which user belong to. */ FAIL(NetUserGetGroups(NULL, userNameW, 0, (LPBYTE *) &globalGroups, MAX_PREFERRED_LENGTH, &nGlobalGroups, &nGlobalGroupsTot)); /* * Allocate buffer for TOKEN_GROUPS struct. * * We assume user belong to Everyone, AuthenticatedUsers, Local, Interactive * and groups retrievied from NetUserGetLocalGroups() and NetUserGetGroups() * for given user. */ nGroupsTotal = nLocalGroups + nGlobalGroups + 4; size = (nGroupsTotal + 1) * sizeof(SID_AND_ATTRIBUTES) + sizeof(DWORD); *groupsToken = (TOKEN_GROUPS *) LocalAlloc(LPTR, size); (*groupsToken) -> GroupCount = nGroupsTotal; /* * Write SIDs of local groups into TOKEN_GROUPS struct. */ #define INSIDE_GROUP_FLAG SE_GROUP_ENABLED\ | SE_GROUP_ENABLED_BY_DEFAULT\ | SE_GROUP_MANDATORY int delta = 4; for (i = 0; i < nLocalGroups; i++) { FAIL(GetSidW(&(*groupsToken) -> Groups[i + delta].Sid, localGroups[i])); (*groupsToken) -> Groups[i + delta].Attributes = INSIDE_GROUP_FLAG; } /* * Write SIDs of global groups into TOKEN_GROUPS struct. */ delta = 4 + nLocalGroups; for (i = 0; i < nGlobalGroups; i++) { FAIL(GetSidW(&(*groupsToken) -> Groups[delta + i].Sid, globalGroups[i])); (*groupsToken) -> Groups[delta + i].Attributes = INSIDE_GROUP_FLAG; } /* * Write SIDs of Everyone, AuthenticatedUsers, Local and Interactive * groups into TOKEN_GROUPS struct. */ (*groupsToken) -> Groups[0].Sid = EveryoneSID(); (*groupsToken) -> Groups[0].Attributes = INSIDE_GROUP_FLAG; (*groupsToken) -> Groups[1].Sid = AuthenticatedUsersSID(); (*groupsToken) -> Groups[1].Attributes = INSIDE_GROUP_FLAG; (*groupsToken) -> Groups[2].Sid = LocalSID(); (*groupsToken) -> Groups[2].Attributes = INSIDE_GROUP_FLAG; (*groupsToken) -> Groups[3].Sid = InteractiveSID(); (*groupsToken) -> Groups[3].Attributes = INSIDE_GROUP_FLAG; exitCode = 0; fail: /* * Clean up. */ NetApiBufferFree(localGroups); NetApiBufferFree(globalGroups); if (exitCode) { debug("ERROR. Failed to setup TOKEN_GROUPS (%u).", GetLastError()); } return exitCode; }
// @pymethod [groupName, ...]|win32net|NetUserGetLocalGroups|Retrieves a list of local groups to which a specified user belongs. // @todo This needs to be extended to support the new model, while // not breaking existing code. A default arg would be perfect. PyObject * PyNetUserGetLocalGroups( PyObject *self, PyObject *args) { DWORD dwFlags = LG_INCLUDE_INDIRECT; DWORD dwBuffsize = 0xFFFFFFFF; // request it all baby! PyWin_AutoFreeBstr wzServerName; // storage for incoming domain string pointer PyWin_AutoFreeBstr wzUserName; // incoming username PyObject *obServerName; PyObject *obUserName; if (!PyArg_ParseTuple(args, "OO|i:NetUserGetLocalGroups", &obServerName, // @pyparm string|serverName||The name of the remote server on which the function is to execute. None or an empty string specifies the server program running on the local computer. &obUserName, // @pyparm string|userName||The name of the user to search for in each group account. This parameter can be of the form \<UserName\>, in which case the username is expected to be found on servername. The user name can also be of the form \<DomainName\>\\\<UserName\> in which case \<DomainName\> is associated with servername and \<UserName\> is expected to be to be found on that domain. &dwFlags)) // @pyparm int|flags|LG_INCLUDE_INDIRECT|Flags for the call. return NULL; if (!PyWinObject_AsAutoFreeBstr(obServerName, &wzServerName, TRUE)) return NULL; if (!PyWinObject_AsAutoFreeBstr(obUserName, &wzUserName, FALSE)) return NULL; DWORD dwMaxCount, dwCount; // see the win32api call for how these are used. LOCALGROUP_USERS_INFO_0 *lpBuffer; NET_API_STATUS Errno; dwMaxCount = dwCount = 0; PyObject * pRetlist = PyList_New(0); //create a return list of 0 size if (pRetlist==NULL) return NULL; // did we err? Py_BEGIN_ALLOW_THREADS Errno = NetUserGetLocalGroups(wzServerName, wzUserName, 0, dwFlags, (LPBYTE *)&lpBuffer, dwBuffsize, &dwCount, &dwMaxCount); // do the enumeration Py_END_ALLOW_THREADS if (Errno == NERR_Success) // if no error, then build the list { LOCALGROUP_USERS_INFO_0 *p_nr = lpBuffer; // Enum Resource returns a buffer of successive structs if (dwCount > 0) // we actually got something { do { PyObject *t_ob = PyWinObject_FromWCHAR(p_nr->lgrui0_name); int listerr = PyList_Append(pRetlist,t_ob); // append our obj...Append does an INCREF! Py_DECREF(t_ob); if (listerr) // or bail { Py_DECREF(pRetlist); // free the Python List NetApiBufferFree((LPVOID)lpBuffer); return NULL; } p_nr++; // next object (its a ++ because it is a typed pointer!) dwCount--; } while (dwCount); }; // if (dwCount > 0) } else // ERROR Occurred { Py_DECREF(pRetlist); return ReturnNetError("NetUserGetLocalGroups", Errno); } NetApiBufferFree((LPVOID)lpBuffer); return pRetlist; }
isc_result_t isc_ntsecurity_getaccountgroups (char *username, char **GroupList, unsigned int maxgroups, unsigned int *totalGroups) { LPGROUP_USERS_INFO_0 pTmpBuf; LPLOCALGROUP_USERS_INFO_0 pTmpLBuf; DWORD i; LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; LPGROUP_USERS_INFO_0 pgrpBuf = NULL; DWORD dwLevel = 0; DWORD dwFlags = LG_INCLUDE_INDIRECT; DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; NET_API_STATUS nStatus; DWORD dwTotalCount = 0; size_t retlen; wchar_t user[MAX_NAME_LENGTH]; retlen = mbstowcs (user, username, MAX_NAME_LENGTH); *totalGroups = 0; /* * Call the NetUserGetLocalGroups function * specifying information level 0. * * The LG_INCLUDE_INDIRECT flag specifies that the * function should also return the names of the local * groups in which the user is indirectly a member. */ nStatus = NetUserGetLocalGroups (NULL, user, dwLevel, dwFlags, (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); /* * See if the call succeeds, */ if (nStatus != NERR_Success) { if (nStatus == ERROR_ACCESS_DENIED) return (ISC_R_NOPERM); if (nStatus == ERROR_MORE_DATA) return (ISC_R_NOSPACE); if (nStatus == NERR_UserNotFound) dwEntriesRead = 0; } dwTotalCount = 0; if (pBuf != NULL) { pTmpLBuf = pBuf; /* * Loop through the entries */ for (i = 0; (i < dwEntriesRead && *totalGroups < maxgroups); i++) { assert (pTmpLBuf != NULL); if (pTmpLBuf == NULL) break; retlen = wcslen (pTmpLBuf->lgrui0_name); GroupList[*totalGroups] = (char *) malloc (retlen + 1); if (GroupList[*totalGroups] == NULL) return (ISC_R_NOMEMORY); retlen = wcstombs (GroupList[*totalGroups], pTmpLBuf->lgrui0_name, retlen); GroupList[*totalGroups][retlen] = '\0'; if (strcmp (GroupList[*totalGroups], "None") == 0) free (GroupList[*totalGroups]); else (*totalGroups)++; pTmpLBuf++; } } /* Free the allocated memory. */ if (pBuf != NULL) NetApiBufferFree (pBuf); /* * Call the NetUserGetGroups function, specifying level 0. */ nStatus = NetUserGetGroups (NULL, user, dwLevel, (LPBYTE *) & pgrpBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); /* * See if the call succeeds, */ if (nStatus != NERR_Success) { if (nStatus == ERROR_ACCESS_DENIED) return (ISC_R_NOPERM); if (nStatus == ERROR_MORE_DATA) return (ISC_R_NOSPACE); if (nStatus == NERR_UserNotFound) dwEntriesRead = 0; } if (pgrpBuf != NULL) { pTmpBuf = pgrpBuf; /* * Loop through the entries */ for (i = 0; (i < dwEntriesRead && *totalGroups < maxgroups); i++) { assert (pTmpBuf != NULL); if (pTmpBuf == NULL) break; retlen = wcslen (pTmpBuf->grui0_name); GroupList[*totalGroups] = (char *) malloc (retlen + 1); if (GroupList[*totalGroups] == NULL) return (ISC_R_NOMEMORY); retlen = wcstombs (GroupList[*totalGroups], pTmpBuf->grui0_name, retlen); GroupList[*totalGroups][retlen] = '\0'; if (strcmp (GroupList[*totalGroups], "None") == 0) free (GroupList[*totalGroups]); else (*totalGroups)++; pTmpBuf++; } } /* * Free the allocated memory. */ if (pgrpBuf != NULL) NetApiBufferFree (pgrpBuf); return (ISC_R_SUCCESS); }
Boolean System::isGroupMember(const char* userName, const char* groupName) { Boolean retVal = false; LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; DWORD dwLevel = 0; DWORD dwFlags = LG_INCLUDE_INDIRECT ; DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; NET_API_STATUS nStatus; wchar_t wcUserName[UNLEN+1]; wchar_t wcGroupName[UNLEN+1]; //Convert user name to unicode if (!MultiByteToWideChar(CP_ACP,0,userName, -1, wcUserName, strlen(userName)+1)) { return false; } //Convert group name to unicode if (!MultiByteToWideChar(CP_ACP, 0, groupName, -1, wcGroupName, strlen(groupName)+1)) { return false; } // // Call the NetUserGetLocalGroups function // specifying information level 0. // // The LG_INCLUDE_INDIRECT flag specifies that the // function should also return the names of the local // groups in which the user is indirectly a member. // nStatus = NetUserGetLocalGroups( NULL, (LPCWSTR)wcUserName, dwLevel, dwFlags, (LPBYTE *) &pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); // // If the call succeeds, // if (nStatus == NERR_Success) { LPLOCALGROUP_USERS_INFO_0 pTmpBuf; DWORD i; DWORD dwTotalCount = 0; if ((pTmpBuf = pBuf) != NULL) { // // Loop through the local groups that the user belongs // and find the matching group name. // for (i = 0; i < dwEntriesRead; i++) { // // Compare the user's group name to groupName. // if (wcscmp(pTmpBuf->lgrui0_name, wcGroupName) == 0) { // User is a member of the group. retVal = true; break; } pTmpBuf++; dwTotalCount++; } } } // // Free the allocated memory. // if (pBuf != NULL) NetApiBufferFree(pBuf); // // If the given user and group are not found in the local group // then try on the global groups. // if (!retVal) { LPGROUP_USERS_INFO_0 pBuf = NULL; dwLevel = 0; dwPrefMaxLen = MAX_PREFERRED_LENGTH; dwEntriesRead = 0; dwTotalEntries = 0; // // Call the NetUserGetGroups function, specifying level 0. // nStatus = NetUserGetGroups( NULL, (LPCWSTR)wcUserName, dwLevel, (LPBYTE*)&pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); // // If the call succeeds, // if (nStatus == NERR_Success) { LPGROUP_USERS_INFO_0 pTmpBuf; DWORD i; DWORD dwTotalCount = 0; if ((pTmpBuf = pBuf) != NULL) { // // Loop through the global groups to which the user belongs // and find the matching group name. // for (i = 0; i < dwEntriesRead; i++) { // // Compare the user's group name to groupName. // if (wcscmp(pTmpBuf->grui0_name, wcGroupName) == 0) { // User is a member of the group. retVal = true; break; } pTmpBuf++; dwTotalCount++; } } } // // Free the allocated buffer. // if (pBuf != NULL) NetApiBufferFree(pBuf); } return retVal; }
static NET_API_STATUS DisplayUser(LPWSTR lpUserName) { PUSER_MODALS_INFO_0 pUserModals = NULL; PUSER_INFO_4 pUserInfo = NULL; PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo = NULL; PGROUP_USERS_INFO_0 pGroupInfo = NULL; DWORD dwLocalGroupRead, dwLocalGroupTotal; DWORD dwGroupRead, dwGroupTotal; DWORD dwLastSet; DWORD i; INT nPaddedLength = 29; NET_API_STATUS Status; /* Modify the user */ Status = NetUserGetInfo(NULL, lpUserName, 4, (LPBYTE*)&pUserInfo); if (Status != NERR_Success) return Status; Status = NetUserModalsGet(NULL, 0, (LPBYTE*)&pUserModals); if (Status != NERR_Success) goto done; Status = NetUserGetLocalGroups(NULL, lpUserName, 0, 0, (LPBYTE*)&pLocalGroupInfo, MAX_PREFERRED_LENGTH, &dwLocalGroupRead, &dwLocalGroupTotal); if (Status != NERR_Success) goto done; Status = NetUserGetGroups(NULL, lpUserName, 0, (LPBYTE*)&pGroupInfo, MAX_PREFERRED_LENGTH, &dwGroupRead, &dwGroupTotal); if (Status != NERR_Success) goto done; PrintPaddedResourceString(IDS_USER_NAME, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_name); PrintPaddedResourceString(IDS_USER_FULL_NAME, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_full_name); PrintPaddedResourceString(IDS_USER_COMMENT, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_comment); PrintPaddedResourceString(IDS_USER_USER_COMMENT, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_usr_comment); PrintPaddedResourceString(IDS_USER_COUNTRY_CODE, nPaddedLength); ConPrintf(StdOut, L"%03ld ()\n", pUserInfo->usri4_country_code); PrintPaddedResourceString(IDS_USER_ACCOUNT_ACTIVE, nPaddedLength); if (pUserInfo->usri4_flags & UF_ACCOUNTDISABLE) ConResPuts(StdOut, IDS_GENERIC_NO); else if (pUserInfo->usri4_flags & UF_LOCKOUT) ConResPuts(StdOut, IDS_GENERIC_LOCKED); else ConResPuts(StdOut, IDS_GENERIC_YES); ConPuts(StdOut, L"\n"); PrintPaddedResourceString(IDS_USER_ACCOUNT_EXPIRES, nPaddedLength); if (pUserInfo->usri4_acct_expires == TIMEQ_FOREVER) ConResPuts(StdOut, IDS_GENERIC_NEVER); else PrintDateTime(pUserInfo->usri4_acct_expires); ConPuts(StdOut, L"\n\n"); PrintPaddedResourceString(IDS_USER_PW_LAST_SET, nPaddedLength); dwLastSet = GetTimeInSeconds() - pUserInfo->usri4_password_age; PrintDateTime(dwLastSet); PrintPaddedResourceString(IDS_USER_PW_EXPIRES, nPaddedLength); if ((pUserInfo->usri4_flags & UF_DONT_EXPIRE_PASSWD) || pUserModals->usrmod0_max_passwd_age == TIMEQ_FOREVER) ConResPuts(StdOut, IDS_GENERIC_NEVER); else PrintDateTime(dwLastSet + pUserModals->usrmod0_max_passwd_age); ConPuts(StdOut, L"\n"); PrintPaddedResourceString(IDS_USER_PW_CHANGEABLE, nPaddedLength); PrintDateTime(dwLastSet + pUserModals->usrmod0_min_passwd_age); PrintPaddedResourceString(IDS_USER_PW_REQUIRED, nPaddedLength); ConResPuts(StdOut, (pUserInfo->usri4_flags & UF_PASSWD_NOTREQD) ? IDS_GENERIC_NO : IDS_GENERIC_YES); ConPuts(StdOut, L"\n"); PrintPaddedResourceString(IDS_USER_CHANGE_PW, nPaddedLength); ConResPuts(StdOut, (pUserInfo->usri4_flags & UF_PASSWD_CANT_CHANGE) ? IDS_GENERIC_NO : IDS_GENERIC_YES); ConPuts(StdOut, L"\n\n"); PrintPaddedResourceString(IDS_USER_WORKSTATIONS, nPaddedLength); if (pUserInfo->usri4_workstations == NULL || wcslen(pUserInfo->usri4_workstations) == 0) ConResPuts(StdOut, IDS_GENERIC_ALL); else ConPrintf(StdOut, L"%s", pUserInfo->usri4_workstations); ConPuts(StdOut, L"\n"); PrintPaddedResourceString(IDS_USER_LOGON_SCRIPT, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_script_path); PrintPaddedResourceString(IDS_USER_PROFILE, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_profile); PrintPaddedResourceString(IDS_USER_HOME_DIR, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_home_dir); PrintPaddedResourceString(IDS_USER_LAST_LOGON, nPaddedLength); if (pUserInfo->usri4_last_logon == 0) ConResPuts(StdOut, IDS_GENERIC_NEVER); else PrintDateTime(pUserInfo->usri4_last_logon); ConPuts(StdOut, L"\n\n"); PrintPaddedResourceString(IDS_USER_LOGON_HOURS, nPaddedLength); if (pUserInfo->usri4_logon_hours == NULL) ConResPuts(StdOut, IDS_GENERIC_ALL); ConPuts(StdOut, L"\n\n"); ConPuts(StdOut, L"\n"); PrintPaddedResourceString(IDS_USER_LOCAL_GROUPS, nPaddedLength); if (dwLocalGroupTotal != 0 && pLocalGroupInfo != NULL) { for (i = 0; i < dwLocalGroupTotal; i++) { if (i != 0) PrintPadding(L' ', nPaddedLength); ConPrintf(StdOut, L"*%s\n", pLocalGroupInfo[i].lgrui0_name); } } else { ConPuts(StdOut, L"\n"); } PrintPaddedResourceString(IDS_USER_GLOBAL_GROUPS, nPaddedLength); if (dwGroupTotal != 0 && pGroupInfo != NULL) { for (i = 0; i < dwGroupTotal; i++) { if (i != 0) PrintPadding(L' ', nPaddedLength); ConPrintf(StdOut, L"*%s\n", pGroupInfo[i].grui0_name); } } else { ConPuts(StdOut, L"\n"); } done: if (pGroupInfo != NULL) NetApiBufferFree(pGroupInfo); if (pLocalGroupInfo != NULL) NetApiBufferFree(pLocalGroupInfo); if (pUserModals != NULL) NetApiBufferFree(pUserModals); if (pUserInfo != NULL) NetApiBufferFree(pUserInfo); return NERR_Success; }
/* returns 1 on success, 0 on failure */ int Valid_Local_Groups(char *UserName, const char **Groups) { int result = 0; char *Domain_Separator; WCHAR wszUserName[UNLEN + 1]; // Unicode user name LPLOCALGROUP_USERS_INFO_0 pBuf; LPLOCALGROUP_USERS_INFO_0 pTmpBuf; DWORD dwLevel = 0; DWORD dwFlags = LG_INCLUDE_INDIRECT; DWORD dwPrefMaxLen = -1; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; NET_API_STATUS nStatus; DWORD i; DWORD dwTotalCount = 0; LPBYTE pBufTmp = NULL; if ((Domain_Separator = strchr(UserName, '/')) != NULL) *Domain_Separator = '\\'; debug("Valid_Local_Groups: checking group membership of '%s'.\n", UserName); /* Convert ANSI User Name and Group to Unicode */ MultiByteToWideChar(CP_ACP, 0, UserName, strlen(UserName) + 1, wszUserName, sizeof(wszUserName) / sizeof(wszUserName[0])); /* * Call the NetUserGetLocalGroups function * specifying information level 0. * * The LG_INCLUDE_INDIRECT flag specifies that the * function should also return the names of the local * groups in which the user is indirectly a member. */ nStatus = NetUserGetLocalGroups(NULL, wszUserName, dwLevel, dwFlags, &pBufTmp, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); pBuf = (LPLOCALGROUP_USERS_INFO_0) pBufTmp; /* * If the call succeeds, */ if (nStatus == NERR_Success) { if ((pTmpBuf = pBuf) != NULL) { for (i = 0; i < dwEntriesRead; i++) { assert(pTmpBuf != NULL); if (pTmpBuf == NULL) { result = 0; break; } if (wcstrcmparray(pTmpBuf->lgrui0_name, Groups) == 0) { result = 1; break; } pTmpBuf++; dwTotalCount++; } } } else result = 0; /* * Free the allocated memory. */ if (pBuf != NULL) NetApiBufferFree(pBuf); return result; }
/* returns 1 on success, 0 on failure */ int Valid_Group(char *UserName, char *Group) { int result = FALSE; WCHAR wszUserName[256]; // Unicode user name WCHAR wszGroup[256]; // Unicode Group LPLOCALGROUP_USERS_INFO_0 pBuf = NULL; LPLOCALGROUP_USERS_INFO_0 pTmpBuf; DWORD dwLevel = 0; DWORD dwFlags = LG_INCLUDE_INDIRECT; DWORD dwPrefMaxLen = -1; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; NET_API_STATUS nStatus; DWORD i; DWORD dwTotalCount = 0; /* Convert ANSI User Name and Group to Unicode */ MultiByteToWideChar(CP_ACP, 0, UserName, strlen(UserName) + 1, wszUserName, sizeof(wszUserName) / sizeof(wszUserName[0])); MultiByteToWideChar(CP_ACP, 0, Group, strlen(Group) + 1, wszGroup, sizeof(wszGroup) / sizeof(wszGroup[0])); /* * Call the NetUserGetLocalGroups function * specifying information level 0. * * The LG_INCLUDE_INDIRECT flag specifies that the * function should also return the names of the local * groups in which the user is indirectly a member. */ nStatus = NetUserGetLocalGroups(NULL, wszUserName, dwLevel, dwFlags, (LPBYTE *) & pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries); /* * If the call succeeds, */ if (nStatus == NERR_Success) { if ((pTmpBuf = pBuf) != NULL) { for (i = 0; i < dwEntriesRead; i++) { if (pTmpBuf == NULL) { result = FALSE; break; } if (wcscmp(pTmpBuf->lgrui0_name, wszGroup) == 0) { result = TRUE; break; } pTmpBuf++; dwTotalCount++; } } } else result = FALSE; /* * Free the allocated memory. */ if (pBuf != NULL) NetApiBufferFree(pBuf); return result; }
static NET_API_STATUS DisplayUser(LPWSTR lpUserName) { PUSER_MODALS_INFO_0 pUserModals = NULL; PUSER_INFO_4 pUserInfo = NULL; PLOCALGROUP_USERS_INFO_0 pLocalGroupInfo = NULL; PGROUP_USERS_INFO_0 pGroupInfo = NULL; DWORD dwLocalGroupRead, dwLocalGroupTotal; DWORD dwGroupRead, dwGroupTotal; DWORD dwLastSet; DWORD i; WCHAR szCountry[40]; INT nPaddedLength = 36; NET_API_STATUS Status; /* Modify the user */ Status = NetUserGetInfo(NULL, lpUserName, 4, (LPBYTE*)&pUserInfo); if (Status != NERR_Success) return Status; Status = NetUserModalsGet(NULL, 0, (LPBYTE*)&pUserModals); if (Status != NERR_Success) goto done; Status = NetUserGetLocalGroups(NULL, lpUserName, 0, 0, (LPBYTE*)&pLocalGroupInfo, MAX_PREFERRED_LENGTH, &dwLocalGroupRead, &dwLocalGroupTotal); if (Status != NERR_Success) goto done; Status = NetUserGetGroups(NULL, lpUserName, 0, (LPBYTE*)&pGroupInfo, MAX_PREFERRED_LENGTH, &dwGroupRead, &dwGroupTotal); if (Status != NERR_Success) goto done; PrintPaddedMessageString(4411, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_name); PrintPaddedMessageString(4412, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_full_name); PrintPaddedMessageString(4413, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_comment); PrintPaddedMessageString(4414, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_usr_comment); PrintPaddedMessageString(4416, nPaddedLength); GetCountryFromCountryCode(pUserInfo->usri4_country_code, ARRAYSIZE(szCountry), szCountry); ConPrintf(StdOut, L"%03ld (%s)\n", pUserInfo->usri4_country_code, szCountry); PrintPaddedMessageString(4419, nPaddedLength); if (pUserInfo->usri4_flags & UF_ACCOUNTDISABLE) PrintMessageString(4301); else if (pUserInfo->usri4_flags & UF_LOCKOUT) PrintMessageString(4440); else PrintMessageString(4300); ConPuts(StdOut, L"\n"); PrintPaddedMessageString(4420, nPaddedLength); if (pUserInfo->usri4_acct_expires == TIMEQ_FOREVER) PrintMessageString(4305); else PrintDateTime(pUserInfo->usri4_acct_expires); ConPuts(StdOut, L"\n\n"); PrintPaddedMessageString(4421, nPaddedLength); dwLastSet = GetTimeInSeconds() - pUserInfo->usri4_password_age; PrintDateTime(dwLastSet); ConPuts(StdOut, L"\n"); PrintPaddedMessageString(4422, nPaddedLength); if ((pUserInfo->usri4_flags & UF_DONT_EXPIRE_PASSWD) || pUserModals->usrmod0_max_passwd_age == TIMEQ_FOREVER) PrintMessageString(4305); else PrintDateTime(dwLastSet + pUserModals->usrmod0_max_passwd_age); ConPuts(StdOut, L"\n"); PrintPaddedMessageString(4423, nPaddedLength); PrintDateTime(dwLastSet + pUserModals->usrmod0_min_passwd_age); ConPuts(StdOut, L"\n"); PrintPaddedMessageString(4437, nPaddedLength); PrintMessageString((pUserInfo->usri4_flags & UF_PASSWD_NOTREQD) ? 4301 : 4300); ConPuts(StdOut, L"\n"); PrintPaddedMessageString(4438, nPaddedLength); PrintMessageString((pUserInfo->usri4_flags & UF_PASSWD_CANT_CHANGE) ? 4301 : 4300); ConPuts(StdOut, L"\n\n"); PrintPaddedMessageString(4424, nPaddedLength); if (pUserInfo->usri4_workstations == NULL || wcslen(pUserInfo->usri4_workstations) == 0) PrintMessageString(4302); else ConPrintf(StdOut, L"%s", pUserInfo->usri4_workstations); ConPuts(StdOut, L"\n"); PrintPaddedMessageString(4429, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_script_path); PrintPaddedMessageString(4439, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_profile); PrintPaddedMessageString(4436, nPaddedLength); ConPrintf(StdOut, L"%s\n", pUserInfo->usri4_home_dir); PrintPaddedMessageString(4430, nPaddedLength); if (pUserInfo->usri4_last_logon == 0) PrintMessageString(4305); else PrintDateTime(pUserInfo->usri4_last_logon); ConPuts(StdOut, L"\n\n"); PrintPaddedMessageString(4432, nPaddedLength); if (pUserInfo->usri4_logon_hours == NULL) PrintMessageString(4302); ConPuts(StdOut, L"\n\n"); ConPuts(StdOut, L"\n"); PrintPaddedMessageString(4427, nPaddedLength); if (dwLocalGroupTotal != 0 && pLocalGroupInfo != NULL) { for (i = 0; i < dwLocalGroupTotal; i++) { if (i != 0) PrintPadding(L' ', nPaddedLength); ConPrintf(StdOut, L"*%s\n", pLocalGroupInfo[i].lgrui0_name); } } else { ConPuts(StdOut, L"\n"); } PrintPaddedMessageString(4431, nPaddedLength); if (dwGroupTotal != 0 && pGroupInfo != NULL) { for (i = 0; i < dwGroupTotal; i++) { if (i != 0) PrintPadding(L' ', nPaddedLength); ConPrintf(StdOut, L"*%s\n", pGroupInfo[i].grui0_name); } } else { ConPuts(StdOut, L"\n"); } done: if (pGroupInfo != NULL) NetApiBufferFree(pGroupInfo); if (pLocalGroupInfo != NULL) NetApiBufferFree(pLocalGroupInfo); if (pUserModals != NULL) NetApiBufferFree(pUserModals); if (pUserInfo != NULL) NetApiBufferFree(pUserInfo); return NERR_Success; }
/* * Check whether user is a member of Administrators group or * the group specified in s->ovpn_admin_group */ BOOL IsAuthorizedUser(SID *sid, settings_t *s) { LOCALGROUP_USERS_INFO_0 *groups = NULL; DWORD nread; DWORD nmax; WCHAR *tmp = NULL; const WCHAR *admin_group[2]; WCHAR username[MAX_NAME]; WCHAR domain[MAX_NAME]; WCHAR sysadmin_group[MAX_NAME]; DWORD err, len = MAX_NAME; int i; BOOL ret = FALSE; SID_NAME_USE sid_type; /* Get username */ if (!LookupAccountSidW(NULL, sid, username, &len, domain, &len, &sid_type)) { MsgToEventLog(M_SYSERR, TEXT("LookupAccountSid")); goto out; } /* Get an array of groups the user is member of */ err = NetUserGetLocalGroups(NULL, username, 0, LG_INCLUDE_INDIRECT, (LPBYTE *) &groups, MAX_PREFERRED_LENGTH, &nread, &nmax); if (err && err != ERROR_MORE_DATA) { SetLastError(err); MsgToEventLog(M_SYSERR, TEXT("NetUserGetLocalGroups")); goto out; } if (GetBuiltinAdminGroupName(sysadmin_group, _countof(sysadmin_group))) { admin_group[0] = sysadmin_group; } else { MsgToEventLog(M_SYSERR, TEXT("Failed to get the name of Administrators group. Using the default.")); /* use the default value */ admin_group[0] = SYSTEM_ADMIN_GROUP; } #ifdef UNICODE admin_group[1] = s->ovpn_admin_group; #else tmp = NULL; len = MultiByteToWideChar(CP_UTF8, 0, s->ovpn_admin_group, -1, NULL, 0); if (len == 0 || (tmp = malloc(len*sizeof(WCHAR))) == NULL) { MsgToEventLog(M_SYSERR, TEXT("Failed to convert admin group name to WideChar")); goto out; } MultiByteToWideChar(CP_UTF8, 0, s->ovpn_admin_group, -1, tmp, len); admin_group[1] = tmp; #endif /* Check if user's groups include any of the admin groups */ for (i = 0; i < nread; i++) { if (wcscmp(groups[i].lgrui0_name, admin_group[0]) == 0 || wcscmp(groups[i].lgrui0_name, admin_group[1]) == 0 ) { MsgToEventLog(M_INFO, TEXT("Authorizing user %s by virtue of membership in group %s"), username, groups[i].lgrui0_name); ret = TRUE; break; } } out: if (groups) { NetApiBufferFree(groups); } free(tmp); return ret; }