Пример #1
0
NTSTATUS FspToolGetSidFromName(PWSTR Name, PSID *PSid)
{
    PSID Sid;
    WCHAR Domn[256];
    DWORD SidSize, DomnSize;
    SID_NAME_USE Use;

    SidSize = 0;
    DomnSize = sizeof Domn / sizeof Domn[0];
    if (LookupAccountNameW(0, Name, 0, &SidSize, Domn, &DomnSize, &Use))
        return STATUS_INVALID_PARAMETER;

    if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
        return FspNtStatusFromWin32(GetLastError());

    Sid = MemAlloc(SidSize);
    if (0 == Sid)
        return STATUS_INSUFFICIENT_RESOURCES;

    DomnSize = sizeof Domn / sizeof Domn[0];
    if (!LookupAccountNameW(0, Name, Sid, &SidSize, Domn, &DomnSize, &Use))
    {
        MemFree(Sid);
        return FspNtStatusFromWin32(GetLastError());
    }

    *PSid = Sid;

    return STATUS_SUCCESS;
}
Пример #2
0
// Security ID (SID) Lookup
HRESULT TCUserAccount::GetSID(LPCWSTR szUserName, PSID* ppSID, LPWSTR* ppszDomain)
{
  // Not supported under Windows9x
  if (IsWin9x())
    return S_FALSE;

  // Initialize the [out] parameters
  if (ppSID)
    *ppSID = NULL;
  if (ppszDomain)
    *ppszDomain = NULL;

  // Skip past "\" or ".\", if the specified name begins with that
  if (L'\\' == szUserName[0])
    szUserName += 1;
  else if (L'.' == szUserName[0] && L'\\' == szUserName[1])
    szUserName += 2;

  // Get the needed size of the buffers
  SID_NAME_USE eUse;
  DWORD cbSID = 0, cchDomain = 0;
  if (!LookupAccountNameW(NULL, szUserName, NULL, &cbSID, NULL, &cchDomain, &eUse))
  {
    DWORD dwLastError = GetLastError();
    if (ERROR_INSUFFICIENT_BUFFER != dwLastError)
      return HRESULT_FROM_WIN32(dwLastError);
  }

  // Allocate domain name buffer on the task allocation, since we return it
  DWORD cbDomain = cchDomain * sizeof(WCHAR);
  TCCoTaskPtr<WCHAR*> spszDomain = (WCHAR*)CoTaskMemAlloc(cbDomain);
  if (spszDomain.IsNull())
    return E_OUTOFMEMORY;

  // Allocate the SID buffer on the task allocator, since we return it
  TCCoTaskPtr<PSID> spSID = (PSID)CoTaskMemAlloc(cbSID);
  if (spSID.IsNull())
    return E_OUTOFMEMORY;

  // Lookup the account name
  if (!LookupAccountNameW(NULL, szUserName, spSID, &cbSID, spszDomain,
    &cchDomain, &eUse))
      return HRESULT_FROM_WIN32(GetLastError());

  // Copy the SID to the [out] parameter
  if (ppSID)
    *ppSID = spSID.Detach();

  // Copy the domain string to the [out] parameter
  if (ppszDomain)
    *ppszDomain = spszDomain.Detach();

  // Indicate success
  return S_OK;
}
static int GetSidW(PSID *psid, const wchar_t *user)
{
  wchar_t *refDomain = NULL;

  DWORD refDomainSize = 0;

  DWORD sidSize = 0;

  SID_NAME_USE peUse;
    
  int exitCode = 1;

  /*
   * Retrieve SID's size
   */

  LookupAccountNameW(NULL, user, NULL, &sidSize, NULL, &refDomainSize, &peUse);

  FAIL(GetLastError() != ERROR_INSUFFICIENT_BUFFER);

  /*
   * Allocate buffer and retrieve SID
   */
  
  *psid = (PSID) LocalAlloc(LPTR, sidSize);

  refDomain = (wchar_t *) LocalAlloc(LPTR, refDomainSize * sizeof(wchar_t));

  FAIL(LookupAccountNameW(NULL, user, *psid, &sidSize, 
                             refDomain, &refDomainSize, &peUse) == FALSE);
  
  exitCode = 0;
  
fail:
  
  /*
   * We don't need reference domain.
   */
  
  if (refDomain)
  {
    LocalFree(refDomain);
  }
  
  if (exitCode != 0)
  {
    debug("ERROR. Cannot retrieve SID (%u).", GetLastError());
  }
  
  return exitCode;
}
Пример #4
0
// https://ru.wikipedia.org/wiki/DACL
BOOL GetSidByName(WCHAR* wchUserName, PSID* lpSid, DWORD* dwSidLength) {
	DWORD dwLengthOfDomainName = 0;		// длина имени домена
	LPTSTR lpDomainName = NULL;			// указатель на имя домена
	SID_NAME_USE typeOfSid;				// тип учетной записи
	DWORD LastError;
	if (!LookupAccountNameW(NULL, wchUserName, NULL, dwSidLength, NULL, &dwLengthOfDomainName, &typeOfSid)) {
		LastError = GetLastError();
		if (LastError == ERROR_INSUFFICIENT_BUFFER) {
			*lpSid = (SID*)malloc(*dwSidLength);
			lpDomainName = (LPTSTR)malloc(dwLengthOfDomainName * sizeof(WCHAR));
			if (!LookupAccountNameW(NULL, wchUserName, *lpSid, dwSidLength, lpDomainName, &dwLengthOfDomainName, &typeOfSid)) {
				free(*lpSid);
				free(lpDomainName);
				DebugOut("LookupAccountNameW[2](..., %S,...) failed! (LastError=0x%x)\n", wchUserName, GetLastError());
				return FALSE;
			}
		} else {
			DebugOut("LookupAccountNameW[1](..., %S,...) failed! (LastError=0x%x)\n", wchUserName, LastError);
			return FALSE;
		}
	}
	free(lpDomainName);
	return TRUE;
}
Пример #5
0
void
TestLookupNameW(
    LPWSTR Name
    )

{

    //
    // LookupAccountNameW test
    //

    BOOL          Bool;
    DWORD         cbSid = 0;
    UCHAR         Sid[BUFFER_SIZE];
    SID_NAME_USE  peUse = SidTypeUser;
    DWORD         cbReferencedDomainName = 0;
    WCHAR         ReferencedDomainName[BUFFER_SIZE];


    printf("      LookupW call . . . . . . . . . . . . . . . . . ");


    Bool = LookupAccountNameW(
               NULL,
               Name,
               Sid,
               &cbSid,
               ReferencedDomainName,
               &cbReferencedDomainName,
               &peUse
               );

    //
    // Expect failure here
    //

    if ( !Bool && GetLastError() != ERROR_INSUFFICIENT_BUFFER ) {
        printf("** FAILED **\n");
        printf("        First call.\n");
        printf("        Status:             %d\n", GetLastError());
        printf("        Sid  Length:        %d\n", cbSid);
        printf("        Domain Name Length: %d\n", cbReferencedDomainName);
    } else {


        Bool = LookupAccountNameW(
                   NULL,
                   Name,
                   Sid,
                   &cbSid,
                   ReferencedDomainName,
                   &cbReferencedDomainName,
                   &peUse
                   );

        if ( !Bool ) {
            printf("** FAILED **\n");
            printf("        Second call.\n");
            printf("        Status:             %d\n", GetLastError());
            printf("        Sid  Length:        %d\n", cbSid);
            printf("        Domain Name Length: %d\n", cbReferencedDomainName);
        } else {
            printf("Succeeded\n");
            printf("        Sid  Length:        %d\n", cbSid);
            printf("        Sid:                ");
            DisplayAccountSid( Sid );
            printf("\n");
            printf("        Domain Name Length: %d\n", cbReferencedDomainName);
            printf("        Domain Name:        *");
            DumpWCharString( ReferencedDomainName );
            printf("*\n");
            printf("        Use:                ");
            DisplayUse( peUse );
            printf("\n\n");
        }
    }

}
int
__cdecl
wmain(
    int argc,
    wchar_t *argv[]
    )
{
    LPWSTR DirectoryToShare;
    LPWSTR Sharename;
    LPWSTR Username;
    LPWSTR Server;

    PSID pSid = NULL;
    DWORD cbSid;

    WCHAR RefDomain[DNLEN + 1];
    DWORD cchDomain = DNLEN + 1;
    SID_NAME_USE peUse;

    SECURITY_DESCRIPTOR sd;
    PACL pDacl = NULL;
    DWORD dwAclSize;

    SHARE_INFO_502 si502;
    NET_API_STATUS nas;

    BOOL bSuccess = FALSE; // assume this function fails

    if(argc < 4) {
        printf("Usage: %ls <directory> <sharename> <user/group> [\\\\Server]\n", argv[0]);
        printf(" directory is fullpath of directory to share\n");
        printf(" sharename is name of share on server\n");
        printf(" user/group is an WinNT user/groupname (REDMOND\\sfield, Administrators, etc)\n");
        printf(" optional Server is the name of the computer to create the share on\n");
        printf("\nExample: %ls c:\\public public Everyone\n", argv[0]);
        printf("c:\\public shared as public granting Everyone full access\n");
        printf("\nExample: %ls c:\\private cool$ REDMOND\\sfield \\\\WINBASE\n", argv[0]);
        printf("c:\\private on \\\\WINBASE shared as cool$ (hidden) granting REDMOND\\sfield access\n");

        return RTN_USAGE;
    }

    //
    // since the commandline was Unicode, just provide pointers to
    // the relevant items
    //

    DirectoryToShare = argv[1];
    Sharename = argv[2];
    Username = argv[3];

    if( argc > 4 ) {
        Server = argv[4];
    } else {
        Server = NULL; // local machine
    }

    //
    // initial allocation attempt for Sid
    //
#define SID_SIZE 96
    cbSid = SID_SIZE;

    pSid = (PSID)HeapAlloc(GetProcessHeap(), 0, cbSid);
    if(pSid == NULL) {
        printf("HeapAlloc error!\n");
        return RTN_ERROR;
    }

    //
    // get the Sid associated with the supplied user/group name
    // force Unicode API since we always pass Unicode string
    //

    if(!LookupAccountNameW(
        NULL,       // default lookup logic
        Username,   // user/group of interest from commandline
        pSid,       // Sid buffer
        &cbSid,     // size of Sid
        RefDomain,  // Domain account found on (unused)
        &cchDomain, // size of domain in chars
        &peUse
        )) {

        //
        // if the buffer wasn't large enough, try again
        //

        if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {

            PSID psidTemp;

            psidTemp = (PSID)HeapReAlloc(GetProcessHeap(), 0, pSid, cbSid);

            if(psidTemp == NULL) {
                printf("HeapReAlloc error!\n");
                goto cleanup;
            }
            else
            {
                pSid = psidTemp;
            }

            cchDomain = DNLEN + 1;

            if(!LookupAccountNameW(
                NULL,       // default lookup logic
                Username,   // user/group of interest from commandline
                pSid,       // Sid buffer
                &cbSid,     // size of Sid
                RefDomain,  // Domain account found on (unused)
                &cchDomain, // size of domain in chars
                &peUse
                )) {
                    printf("LookupAccountName error! (rc=%lu)\n", GetLastError());
                    goto cleanup;
                }

        } else {
            printf("LookupAccountName error! (rc=%lu)\n", GetLastError());
            goto cleanup;
        }
    }

    //
    // compute size of new acl
    //

    dwAclSize = sizeof(ACL) +
        1 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
        GetLengthSid(pSid) ;

    //
    // allocate storage for Acl
    //

    pDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
    if(pDacl == NULL) goto cleanup;

    if(!InitializeAcl(pDacl, dwAclSize, ACL_REVISION))
        goto cleanup;

    //
    // grant GENERIC_ALL (Full Control) access
    //

    if(!AddAccessAllowedAce(
        pDacl,
        ACL_REVISION,
        GENERIC_ALL,
        pSid
        )) goto cleanup;

    if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
        goto cleanup;

    if(!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) {
        fprintf(stderr, "SetSecurityDescriptorDacl error! (rc=%lu)\n",
            GetLastError());
        goto cleanup;
    }

    //
    // setup share info structure
    //

    si502.shi502_netname = (LMSTR) Sharename;
    si502.shi502_type = STYPE_DISKTREE;
    si502.shi502_remark = NULL;
    si502.shi502_permissions = 0;
    si502.shi502_max_uses = SHI_USES_UNLIMITED;
    si502.shi502_current_uses = 0;
    si502.shi502_path = (LMSTR) DirectoryToShare;
    si502.shi502_passwd = NULL;
    si502.shi502_reserved = 0;
    si502.shi502_security_descriptor = &sd;

    nas = NetShareAdd(
        (LMSTR) Server,         // share is on local machine
        502,            // info-level
        (LPBYTE)&si502, // info-buffer
        NULL            // don't bother with parm
        );

    if(nas != NO_ERROR) {
        printf("NetShareAdd error! (rc=%lu)\n", nas);
        goto cleanup;
    }

    bSuccess = TRUE; // indicate success

cleanup:

    //
    // free allocated resources
    //
    if(pDacl != NULL)
        HeapFree(GetProcessHeap(), 0, pDacl);

    if(pSid != NULL)
        HeapFree(GetProcessHeap(), 0, pSid);

    if(!bSuccess) {
        return RTN_ERROR;
    }

    return RTN_OK;
}
Пример #7
0
        Private(const QString &name, PSID sid_ = 0) : userInfo(0), sid(NULL)
        {
            LPBYTE servername;
            NET_API_STATUS status = NetGetAnyDCName(0, 0, &servername);
            if (status != NERR_Success)
            {
                servername = NULL;
            }

            if (NetUserGetInfo((LPCWSTR) servername, (LPCWSTR) name.utf16(), 11, (LPBYTE *) &userInfo) != NERR_Success) {
                goto error;
            }
            if (servername)
            {
                NetApiBufferFree(servername);
                servername = 0;
            }

            if (!sid_) {
                DWORD size = 0;
                SID_NAME_USE nameuse;
                DWORD cchReferencedDomainName = 0;
                WCHAR* referencedDomainName = NULL;

                // the following line definitely fails:
                // both the sizes for sid and for referencedDomainName are Null
                // the needed sizes are set in size and cchReferencedDomainName
                LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, referencedDomainName, &cchReferencedDomainName, &nameuse);
                sid = (PSID) new SID[size + 1];
                referencedDomainName = new WCHAR[cchReferencedDomainName + 1];
                if (!LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, referencedDomainName, &cchReferencedDomainName, &nameuse)) {
                    delete[] referencedDomainName;
                    goto error;
                }

                // if you want to see both the DomainName and the sid of the user
                // uncomment the following lines
/*                LPWSTR sidstring;
                ConvertSidToStringSidW(sid, &sidstring);
                qDebug() << QString("\\\\") + QString::fromUtf16(reinterpret_cast<ushort*>(referencedDomainName)) + \
                            "\\" + name + "(" + QString::fromUtf16(reinterpret_cast<ushort*>(sidstring)) + ")";

                LocalFree(sidstring);*/
                delete[] referencedDomainName;
            }
            else {
                if (!IsValidSid(sid_))
                    goto error;

                DWORD sidlength = GetLengthSid(sid_);
                sid = (PSID) new BYTE[sidlength];
                if (!CopySid(sidlength, sid, sid_))
                    goto error;
            }

            return;

          error:
            delete[] sid;
            sid = 0;
            if (userInfo) {
                NetApiBufferFree(userInfo);
                userInfo = 0;
            }
            if (servername)
            {
                NetApiBufferFree(servername);
                servername = 0;
            }
        }
Пример #8
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);
}
Пример #9
0
static int
enum_local_groups (domlist_t *mach, const char *sep,
		   DWORD id_offset, char *disp_groupname, int print_builtin,
		   int print_current)
{
  WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
  LOCALGROUP_INFO_0 *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 1;
    }

  do
    {
      DWORD i;

      if (disp_groupname)
	{
	  mbstowcs (gname, disp_groupname, GNLEN + 1);
	  rc = NetLocalGroupGetInfo (machine, gname, 0, (void *) &buffer);
	  if (rc == ERROR_SUCCESS)
	    entriesread = 1;
	  /* Allow further searching for the group and avoid annoying
	     error messages just because the group is not a local group or
	     the group hasn't been found. */
	  else if (rc == ERROR_NO_SUCH_ALIAS || rc == NERR_GroupNotFound)
	    return 0;
	}
      else
	rc = NetLocalGroupEnum (machine, 0, (void *) &buffer,
				MAX_PREFERRED_LENGTH, &entriesread,
				&totalentries, &resume_handle);
      switch (rc)
	{
	case ERROR_ACCESS_DENIED:
	  print_win_error (rc);
	  return 1;

	case ERROR_MORE_DATA:
	case ERROR_SUCCESS:
	  break;

	default:
	  print_win_error (rc);
	  return 1;
	}

      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;
	  DWORD gid;
	  SID_NAME_USE acc_type;
	  PDBGSID pdsid;
	  BOOL is_builtin = FALSE;

	  if (!LookupAccountNameW (machine, buffer[i].lgrpi0_name, psid,
				   &sid_length, domain_name, &domname_len,
				   &acc_type))
	    {
	      print_win_error (GetLastError ());
	      fprintf (stderr, " (%ls)\n", buffer[i].lgrpi0_name);
	      continue;
	    }
	  else if (acc_type == SidTypeDomain)
	    {
	      WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2];

	      wcscpy (domname, domain_name);
	      wcscat (domname, L"\\");
	      wcscat (domname, buffer[i].lgrpi0_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;
		}
	    }

	  /* Store all local SIDs with prefix "S-1-5-32-" and check if it
	     has been printed already.  This allows to get all builtin
	     groups exactly once and not once per domain. */
	  pdsid = (PDBGSID) psid;
	  if (pdsid->IdentifierAuthority.Value[5] == sid_nt_auth.Value[5]
	      && pdsid->SubAuthority[0] == SECURITY_BUILTIN_DOMAIN_RID)
	    {
	      int b;

	      if (!print_builtin)
		goto skip_group;
	      is_builtin = TRUE;
	      if (builtin_sid_cnt)
		for (b = 0; b < builtin_sid_cnt; b++)
		  if (EqualSid (&builtin_sid_list[b], psid))
		    goto skip_group;
	      if (builtin_sid_cnt < MAX_BUILTIN_SIDS)
		CopySid (sizeof (DBGSID), &builtin_sid_list[builtin_sid_cnt++],
			 psid);
	    }
	  if (!print_current)
	    /* fall through */;
	  else if (EqualSid (curr_pgrp.psid, psid))
	    got_curr_pgrp = TRUE;

	  gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
	  printf ("%ls%s%ls:%s:%" PRIu32 ":\n",
		  mach->with_dom && !is_builtin ? domain_name : L"",
		  mach->with_dom || is_builtin ? sep : "",
		  buffer[i].lgrpi0_name,
		  put_sid (psid),
		  (unsigned int) (gid + (is_builtin ? 0 : id_offset)));
skip_group:
	  ;
	}

      NetApiBufferFree (buffer);

    }
  while (rc == ERROR_MORE_DATA);

  /* Return 1 if the single group we're looking for has been found here to
     avoid calling enum_groups for the same group, thus avoiding a spurious
     error message "group name could not be found" in enum_groups. */
  return disp_groupname && entriesread ? 1 : 0;
}
Пример #10
0
static void
enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset,
		  char *unix_grp_list)
{
  WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
  SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } };
  char *gstr, *grp_list;
  WCHAR grp[GNLEN + sizeof ("Unix Group\\") + 1];
  WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
  DWORD glen, dlen, sidlen;
  PSID psid;
  char psid_buffer[MAX_SID_LEN];
  SID_NAME_USE acc_type;

  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;
    }

  if (!AllocateAndInitializeSid (&auth, 2, 2, 0, 0, 0, 0, 0, 0, 0, &psid))
    return;

  if (!(grp_list = strdup (unix_grp_list)))
    {
      FreeSid (psid);
      return;
    }

  for (gstr = strtok (grp_list, ","); gstr; gstr = strtok (NULL, ","))
    {
      if (!isdigit ((unsigned char) gstr[0]) && gstr[0] != '-')
	{
	  PWCHAR p = wcpcpy (grp, L"Unix Group\\");
	  ret = mbstowcs (p, gstr, GNLEN + 1);
	  if (ret < 1 || ret >= GNLEN + 1)
	    fprintf (stderr, "%s: Invalid group name '%s'.  Skipping...\n",
		     program_invocation_short_name, gstr);
	  else if (LookupAccountNameW (machine, grp,
				       psid = (PSID) psid_buffer,
				       (sidlen = MAX_SID_LEN, &sidlen),
				       dom,
				       (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
				       &acc_type))
	    printf ("%s%s%ls:%s:%" PRIu32 ":\n",
		    mach->with_dom ? "Unix_Group" : "",
		    mach->with_dom ? sep : "",
		    p,
		    put_sid (psid),
		    (unsigned int) (id_offset +
		    *GetSidSubAuthority (psid,
					 *GetSidSubAuthorityCount(psid) - 1)));
	}
      else
	{
	  DWORD start, stop;
	  char *p = gstr;
	  if (*p == '-')
	    start = 0;
	  else
	    start = strtol (p, &p, 10);
	  if (!*p)
	    stop = start;
	  else if (*p++ != '-' || !isdigit ((unsigned char) *p)
		   || (stop = strtol (p, &p, 10)) < start || *p)
	    {
	      fprintf (stderr, "%s: Malformed unix group list entry '%s'.  "
			       "Skipping...\n",
			       program_invocation_short_name, gstr);
	      continue;
	    }
	  for (; start <= stop; ++ start)
	    {
	      *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1)
	      = start;
	      if (LookupAccountSidW (machine, psid,
				     grp, (glen = GNLEN + 1, &glen),
				     dom,
				     (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
				     &acc_type)
		  && !iswdigit (grp[0]))
		printf ("%s%s%ls:%s:%" PRIu32 ":\n",
			mach->with_dom ? "Unix_Group" : "",
			mach->with_dom ? sep : "",
			grp,
			put_sid (psid),
			(unsigned int) (id_offset + start));
	    }
	}
    }

  free (grp_list);
  FreeSid (psid);
}
Пример #11
0
static int collect_access_rights(probe_ctx *ctx, WCHAR *security_principle, bool include_group, bool resolve_group)
{
	char *security_principle_str = oscap_windows_wstr_to_str(security_principle);

	LSA_OBJECT_ATTRIBUTES object_attributes;
	ZeroMemory(&object_attributes, sizeof(LSA_OBJECT_ATTRIBUTES));
	LSA_HANDLE lsa_policy_handle;

	NTSTATUS status = LsaOpenPolicy(NULL, &object_attributes, POLICY_LOOKUP_NAMES, &lsa_policy_handle);
	if (status != STATUS_SUCCESS) {
		DWORD err = LsaNtStatusToWinError(status);
		char *error_message = oscap_windows_error_message(err);
		dD("LsaOpenPolicy failed for principle '%s': %s", security_principle_str, error_message);
		free(error_message);
		free(security_principle_str);
		return 1;
	}

	/* Convert the value of the security_principle element to a SID. */
	DWORD sid_len = 0;
	DWORD domain_name_len = 0;
	SID_NAME_USE sid_type;
	LookupAccountNameW(NULL, security_principle, NULL, &sid_len, NULL, &domain_name_len, &sid_type);
	SID *sid = malloc(sid_len);
	WCHAR *domain_name = malloc(domain_name_len * sizeof(WCHAR));
	if (!LookupAccountNameW(NULL, security_principle, sid, &sid_len, domain_name, &domain_name_len, &sid_type)) {
		DWORD err = GetLastError();
		char *error_message = oscap_windows_error_message(err);
		dD("LookupAccountNameW failed for '%s': %s", security_principle_str, error_message);
		free(error_message);
		free(security_principle_str);
		free(sid);
		free(domain_name);
		return 1;
	}

	/* Is it a group? */
	if (sid_type == SidTypeGroup || sid_type == SidTypeWellKnownGroup || sid_type == SidTypeAlias) {
		if (resolve_group) {
			struct oscap_list *group_members_list = oscap_list_new();
			get_local_group_members(security_principle, group_members_list);
			get_global_group_members(security_principle, group_members_list);
			struct oscap_iterator *group_members_it = oscap_iterator_new(group_members_list);
			while (oscap_iterator_has_more(group_members_it)) {
				WCHAR *group_member = oscap_iterator_next(group_members_it);
				collect_access_rights(ctx, group_member, include_group, resolve_group);
			}
			oscap_iterator_free(group_members_it);
			oscap_list_free(group_members_list, free);
		}
		if (!include_group) {
			free(sid);
			free(domain_name);
			free(security_principle_str);
			return 0;
		}
	}

	/* Users and groups can inherit their privileges from their parents */
	struct oscap_list *every_rights_sources = oscap_list_new();
	oscap_list_add(every_rights_sources, wcsdup(security_principle));
	get_user_local_groups(security_principle, every_rights_sources);
	get_user_global_groups(security_principle, every_rights_sources);

	/* Iterate over the items */
	bool privileges_enabled[OVAL_PRIVILEGES_COUNT] = { false };
	struct oscap_iterator *it = oscap_iterator_new(every_rights_sources);
	while (oscap_iterator_has_more(it)) {
		WCHAR *account_name = oscap_iterator_next(it);

		DWORD account_sid_len = 0;
		DWORD account_domain_name_len = 0;
		SID_NAME_USE account_sid_type;
		LookupAccountNameW(NULL, account_name, NULL, &account_sid_len, NULL, &account_domain_name_len, &account_sid_type);
		SID *account_sid = malloc(account_sid_len);
		WCHAR *account_domain_name = malloc(account_domain_name_len * sizeof(WCHAR));
		if (!LookupAccountNameW(NULL, account_name, account_sid, &account_sid_len, account_domain_name, &account_domain_name_len, &account_sid_type)) {
			free(account_sid);
			free(account_domain_name);
			DWORD err = GetLastError();
			char *error_message = oscap_windows_error_message(err);
			dD("LookupAccountNameW failed for '%s': %s", security_principle_str, error_message);
			free(error_message);
			free(security_principle_str);
			return 1;
		}

		LSA_UNICODE_STRING *granted_rights = NULL;
		ULONG granted_rights_count = 0;
		status = LsaEnumerateAccountRights(lsa_policy_handle, account_sid, &granted_rights, &granted_rights_count);
		if (status != STATUS_SUCCESS) {
			free(account_sid);
			free(account_domain_name);
			DWORD err = LsaNtStatusToWinError(status);
			char *error_message = oscap_windows_error_message(err);
			dD("LsaEnumerateAccountRights failed for '%s': %s", security_principle_str, error_message);
			free(error_message);
			/* We should not exit here, because when LsaEnumerateAccountRights
			* failed it can mean that the entity simply doesn't have any specific
			* privileges, it only inhertis privileges form its parent group(s).
			*/
			continue;
		}

		for (int i = 0; i < OVAL_PRIVILEGES_COUNT; i++) {
			if (!privileges_enabled[i]) {
				for (ULONG j = 0; j < granted_rights_count; j++) {
					if (wcscmp(granted_rights[j].Buffer, privileges_texts[i]) == 0) {
						privileges_enabled[i] = true;
						break;
					}
				}
			}
		}
		LsaFreeMemory(granted_rights);
		free(account_sid);
		free(account_domain_name);

	}
	oscap_iterator_free(it);
	oscap_list_free(every_rights_sources, free);

	/* Collect the OVAL item */
	SEXP_t *item = probe_item_create(OVAL_WINDOWS_ACCESS_TOKEN, NULL,
		"security_principle", OVAL_DATATYPE_STRING, strdup(security_principle_str), NULL);
	for (int i = 0; i < OVAL_PRIVILEGES_COUNT; i++) {
		char *privilege_name = oscap_windows_wstr_to_str(privileges_texts[i]);
		/* Convert the element name to lowercase */
		for (char *p = privilege_name; *p; p++) {
			*p = tolower(*p);
		}
		SEXP_t *privilege_value = SEXP_number_newb(privileges_enabled[i]);
		probe_item_ent_add(item, privilege_name, NULL, privilege_value);
		free(privilege_name);
		SEXP_free(privilege_value);
	}
	probe_item_collect(ctx, item);
	free(security_principle_str);

	return 0;
}
// Calling function is responsible for freeing ppszSID using LocalAlloc
HRESULT WpcuSidStringFromUserName(PCWSTR pcszUserName, PWSTR* ppszSID)
{
    HRESULT hr = E_INVALIDARG;

    if (pcszUserName && ppszSID)
    {
        DWORD cbSID = 0, cchDomain = 0;
        SID_NAME_USE SidNameUse;

        // Call twice, first with null SID buffer.  Retrieves required buffer
        //  size for domain name
        LookupAccountNameW(NULL, pcszUserName, NULL, &cbSID, NULL, 
            &cchDomain, &SidNameUse);
        if (!cbSID || !cchDomain)
        {
            hr = E_FAIL;
        }
        else
        {
            WCHAR* pszDomain = NULL;
            // Allocate properly sized buffer (with termination character) 
            //  for domain name
            pszDomain = new WCHAR[cchDomain];
            if (!pszDomain)
            {
                hr = E_OUTOFMEMORY;
            }
            else
            {
                // Allocate properly sized buffer (with termination character)
                //  for PSID
                PSID pSID = static_cast<PSID> (new BYTE[cbSID]); //(LocalAlloc (LMEM_FIXED, cbSID));
                if (!pSID)
                {
                    hr = E_OUTOFMEMORY;
                }
                else
                {
                    // Second call with buffers allocated and sizes set
                    if (!LookupAccountName(NULL, pcszUserName, pSID, &cbSID,
                        pszDomain, &cchDomain, &SidNameUse))
                    {
                        hr = HRESULT_FROM_WIN32(GetLastError());
                    }
                    else
                    {
                        // Convert PSID to SID string
                        if (!ConvertSidToStringSidW(pSID, ppszSID))
                        {
                            hr = HRESULT_FROM_WIN32(GetLastError());
                        }
                        else
                        {
                            hr = S_OK;
                        }
                    }
                    delete[] pSID; // (LocalFree (pSID);
                }
                delete[] pszDomain;
            }
        }
    }

    return (hr);
}