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;
}
Exemple #2
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;
}
Exemple #3
0
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);
}
Exemple #5
0
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);
        }
    }
}
Exemple #6
0
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;
}
Exemple #9
0
// @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;
}
Exemple #10
0
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);
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
/* 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;
}
Exemple #15
0
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;
}
Exemple #16
0
/*
 * 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;
}