Beispiel #1
0
/* Do some black magic with the NT security API.
 * We prepare a DACL (Discretionary Access Control List) so that
 * we, the creator, are allowed all access, while "Everyone Else"
 * is only allowed to read and write to the pipe.
 * This avoids security issues on shared hosts where a luser messes
 * with the lower-level pipe settings and screws up the FastCGI service.
 */
static PACL prepare_named_pipe_acl(PSECURITY_DESCRIPTOR sd, LPSECURITY_ATTRIBUTES sa)
{
	DWORD req_acl_size;
	char everyone_buf[32], owner_buf[32];
	PSID sid_everyone, sid_owner;
	SID_IDENTIFIER_AUTHORITY
		siaWorld = SECURITY_WORLD_SID_AUTHORITY,
		siaCreator = SECURITY_CREATOR_SID_AUTHORITY;
	PACL acl;

	sid_everyone = (PSID)&everyone_buf;
	sid_owner = (PSID)&owner_buf;

	req_acl_size = sizeof(ACL) +
		(2 * ((sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetSidLengthRequired(1)));

	acl = malloc(req_acl_size);

	if (acl == NULL) {
		return NULL;
	}

	if (!InitializeSid(sid_everyone, &siaWorld, 1)) {
		goto out_fail;
	}
	*GetSidSubAuthority(sid_everyone, 0) = SECURITY_WORLD_RID;

	if (!InitializeSid(sid_owner, &siaCreator, 1)) {
		goto out_fail;
	}
	*GetSidSubAuthority(sid_owner, 0) = SECURITY_CREATOR_OWNER_RID;

	if (!InitializeAcl(acl, req_acl_size, ACL_REVISION)) {
		goto out_fail;
	}

	if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_GENERIC_READ | FILE_GENERIC_WRITE, sid_everyone)) {
		goto out_fail;
	}

	if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_ALL_ACCESS, sid_owner)) {
		goto out_fail;
	}

	if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
		goto out_fail;
	}

	if (!SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE)) {
		goto out_fail;
	}

	sa->lpSecurityDescriptor = sd;

	return acl;

out_fail:
	free(acl);
	return NULL;
}
Beispiel #2
0
static bool s_GetOwnerGroupFromSIDs(PSID owner_sid, PSID group_sid,
                                    string* owner_name, string* group_name,
                                    unsigned int* uid, unsigned int* gid)
{
    bool success = true;

    // Get numeric owner
    if ( uid ) {
        int match = SidTypeUser;
        if ( !x_GetAccountNameBySid(owner_sid, owner_name, &match) ) {
            if ( owner_name )
                success = false;
            *uid = 0;
        } else {
            *uid = match ? CYGWIN_MAGIC_ID_OFFSET : 0;
        }
        owner_name = NULL;
        *uid += *GetSidSubAuthority(owner_sid, *GetSidSubAuthorityCount(owner_sid) - 1);
    }
    // Get numeric group
    if ( gid ) {
        int match = SidTypeGroup;
        if ( !x_GetAccountNameBySid(group_sid, group_name, &match) ) {
            *gid = 0;
        } else {
            *gid = match ? CYGWIN_MAGIC_ID_OFFSET : 0;
        }
        group_name = NULL;
        *gid += *GetSidSubAuthority(group_sid, *GetSidSubAuthorityCount(group_sid) - 1);
    }
    if ( !success ) {
        return false;
    }

    // Get owner name
    if ( owner_name  &&  !x_GetAccountNameBySid(owner_sid, owner_name) ) {
        return false;
    }
    // Get group name
    if ( group_name  &&  !x_GetAccountNameBySid(group_sid, group_name) ) {
        // This is not an error, because the group name on Windows
        // is an auxiliary information.  Sometimes accounts cannot
        // belong to groups, or we don't have permissions to get
        // such information.
        group_name->clear();
    }
    return true;
}
Beispiel #3
0
/* Internal sid binary to string translation, see MSKB Q131320.
 * Several user related operations require our SID to access
 * the registry, but in a string format.  All error handling
 * depends on IsValidSid(), which internally we better test long
 * before we get here!
 */
void get_sid_string(char *buf, apr_size_t blen, apr_uid_t id)
{
    PSID_IDENTIFIER_AUTHORITY psia;
    DWORD nsa;
    DWORD sa;
    int slen;

    /* Determine authority values (these is a big-endian value, 
     * and NT records the value as hex if the value is > 2^32.)
     */
    psia = GetSidIdentifierAuthority(id);
    nsa =  (DWORD)(psia->Value[5])        + ((DWORD)(psia->Value[4]) <<  8)
        + ((DWORD)(psia->Value[3]) << 16) + ((DWORD)(psia->Value[2]) << 24);
    sa  =  (DWORD)(psia->Value[1])        + ((DWORD)(psia->Value[0]) <<  8);
    if (sa) {
        slen = apr_snprintf(buf, blen, "S-%lu-0x%04x%08x",
                            SID_REVISION, sa, nsa);
    } else {
        slen = apr_snprintf(buf, blen, "S-%lu-%lu",
                            SID_REVISION, nsa);
    }

    /* Now append all the subauthority strings.
     */
    nsa = *GetSidSubAuthorityCount(id);
    for (sa = 0; sa < nsa; ++sa) {
        slen += apr_snprintf(buf + slen, blen - slen, "-%lu",
                             *GetSidSubAuthority(id, sa));
    }
} 
DWORD CRemoteCacheLink::GetProcessIntegrityLevel() const
{
	DWORD dwIntegrityLevel = SECURITY_MANDATORY_MEDIUM_RID;

	CAutoGeneralHandle hProcess = GetCurrentProcess();
	CAutoGeneralHandle hToken;
	if (OpenProcessToken(hProcess, TOKEN_QUERY |
		TOKEN_QUERY_SOURCE, hToken.GetPointer()))
	{
		// Get the Integrity level.
		DWORD dwLengthNeeded;
		if (!GetTokenInformation(hToken, TokenIntegrityLevel,
			NULL, 0, &dwLengthNeeded))
		{
			DWORD dwError = GetLastError();
			if (dwError == ERROR_INSUFFICIENT_BUFFER)
			{
				PTOKEN_MANDATORY_LABEL pTIL =
					(PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwLengthNeeded);
				if (pTIL != NULL)
				{
					if (GetTokenInformation(hToken, TokenIntegrityLevel,
						pTIL, dwLengthNeeded, &dwLengthNeeded))
					{
						dwIntegrityLevel = *GetSidSubAuthority(pTIL->Label.Sid,
							(DWORD)(UCHAR)(*GetSidSubAuthorityCount(pTIL->Label.Sid)-1));
					}
					LocalFree(pTIL);
				}
			}
		}
	}

	return dwIntegrityLevel;
}
Beispiel #5
0
static SECURITY_ATTRIBUTES* security_attributes(void)
{
	static int			initialized;
	static SECURITY_ATTRIBUTES	asa;
	static int			aclbuf[512];
	static ACL*			acl = (ACL*)&aclbuf[0];
	static SECURITY_DESCRIPTOR	asd;
	static int			sid[SID_BUF_MAX];

	if (initialized < 0)
		return 0;
	if (initialized > 0)
		return &asa;
	initialized = -1;
	CopySid(sizeof(sid), (SID*)sid, &admins_sid_hdr);
	*GetSidSubAuthority((SID*)sid, 1) = DOMAIN_ALIAS_RID_ADMINS;
	InitializeSecurityDescriptor(&asd, SECURITY_DESCRIPTOR_REVISION);
	if (!SetSecurityDescriptorGroup(&asd, (SID*)sid, 0))
		return 0;
	if (!InitializeAcl(acl, sizeof(ACL) + 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetLengthSid((SID*)sid) + GetLengthSid(&worldsid), ACL_REVISION))
		return 0;
	if (!AddAccessAllowedAce(acl, ACL_REVISION, GENERIC_ALL|READ_CONTROL|WRITE_DAC, (SID*)sid))
		return 0;
	if (!AddAccessAllowedAce(acl, ACL_REVISION, GENERIC_READ, &worldsid))
		return 0;
	if (!SetSecurityDescriptorDacl(&asd, 1, acl, 0))
		return 0;
	asa.nLength = sizeof(asa);
	asa.bInheritHandle = 0;
	asa.lpSecurityDescriptor = &asd;
	initialized = 1;
	return &asa;
}
PUBLIC_FUNCTION_END

PUBLIC_FUNCTION(IsUserTheAdministrator)
{
  TCHAR * name = (TCHAR *)LocalAlloc(LPTR, string_size*sizeof(TCHAR));
  TCHAR * sidstr = NULL;
  DWORD dwName = string_size;
  PSID pSid = NULL;
  DWORD sidLen = 0;
  DWORD domLen = 0;
  TCHAR * domain = NULL;
  SID_NAME_USE use;

  if (popstring(name))
    ABORT("Missing user name plug-in parameter.");

  if ((LookupAccountName(NULL, name, 
      NULL, &sidLen, NULL, &domLen, &use) ||
      ERROR_INSUFFICIENT_BUFFER == GetLastError()) &&
      NULL != (domain = (TCHAR *)LocalAlloc(LPTR, domLen*sizeof(TCHAR))) &&
    NULL != (pSid = (PSID)LocalAlloc(LPTR, sidLen)))
  {
    if (!LookupAccountName(NULL, name, 
      pSid, &sidLen, domain, &domLen, &use))
    {
      LocalFree(pSid);
      pSid = NULL;
      ABORT_d("Couldn't lookup current user name. Error code %d: ", GetLastError());
    }

    int uid;
    if (500 == (uid = *GetSidSubAuthority(pSid, *GetSidSubAuthorityCount(pSid) - 1)))
      pushstring(_T("yes"));
    else
      pushstring(_T("no"));

    sidstr = (TCHAR *)LocalAlloc(LPTR, string_size*sizeof(TCHAR));
    ConvertSidToStringSid(pSid, &sidstr);

    int len = lstrlen(sidstr);
    TCHAR * strend = sidstr + len - 1;
    TCHAR * strstart = sidstr;
    while (*strend != '-' && len >= 0)
    {
      strend--;
      len--;
    }
    *strend = '\0';
    lstrcat(strend, _T("-500"));

    pushstring(sidstr);
  }

cleanup:
  if (NULL != sidstr)
    LocalFree(sidstr);
  LocalFree(name);
}
Beispiel #7
0
	bool GetProcessIntegrityLevel(ProcessHandle process, IntegrityLevel *level) {
		if (!level)
			return false;

		if (win::GetVersion() < base::win::VERSION_VISTA)
			return false;

		HANDLE process_token;
		if (!OpenProcessToken(process, TOKEN_QUERY | TOKEN_QUERY_SOURCE,
			&process_token))
			return false;

		win::ScopedHandle scoped_process_token(process_token);

		DWORD token_info_length = 0;
		if (GetTokenInformation(process_token, TokenIntegrityLevel, NULL, 0,
			&token_info_length) ||
			GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			return false;

		scoped_ptr<char[]> token_label_bytes(new char[token_info_length]);
		if (!token_label_bytes.get())
			return false;

		TOKEN_MANDATORY_LABEL* token_label =
			reinterpret_cast<TOKEN_MANDATORY_LABEL*>(token_label_bytes.get());
		if (!token_label)
			return false;

		if (!GetTokenInformation(process_token, TokenIntegrityLevel, token_label,
			token_info_length, &token_info_length))
			return false;

		DWORD integrity_level = *GetSidSubAuthority(token_label->Label.Sid,
			(DWORD)(UCHAR)(*GetSidSubAuthorityCount(token_label->Label.Sid) - 1));

		if (integrity_level < SECURITY_MANDATORY_MEDIUM_RID) {
			*level = LOW_INTEGRITY;
		}
		else if (integrity_level >= SECURITY_MANDATORY_MEDIUM_RID &&
			integrity_level < SECURITY_MANDATORY_HIGH_RID) {
			*level = MEDIUM_INTEGRITY;
		}
		else if (integrity_level >= SECURITY_MANDATORY_HIGH_RID) {
			*level = HIGH_INTEGRITY;
		}
		else {
			NOTREACHED();
			return false;
		}

		return true;
	}
Beispiel #8
0
BOOL IsLogonSid( PSID ps )
{
	static SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;

	// a logon SID has: sia = 5, subauth count = 3, first subauth = 5
	// the following three lines test these three conditions
	if ( ! memcmp( GetSidIdentifierAuthority( ps ), &sia, sizeof sia )	&& // is sia == 5?
	  *GetSidSubAuthorityCount( ps ) == 3								&& // is subauth count == 3?
	  *GetSidSubAuthority( ps, 0 ) == 5									)  // first subauth == 5?
		return TRUE;
	else
		return FALSE;
}
Beispiel #9
0
/*
  (in) PSID 
  (in/out) char 
  (in) size_t
return
  0 - success
 -1 - error
*/
int get_textual_sid(PSID pSid,char * buf,size_t len)
{
  /*FROM MSDN Converting a Binary SID to String Format in C++*/
  PSID_IDENTIFIER_AUTHORITY psia;
  DWORD dwSubAuthorities;
  DWORD dwSidRev = SID_REVISION;
  DWORD dwCounter;
  DWORD dwSidSize;

  if (!IsValidSid(pSid)){
    SetLastError(ERROR_INVALID_DATA);
    return -1;
  }
  psia = GetSidIdentifierAuthority(pSid);

  dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

  dwSidSize = (15 + 12 + (12 * dwSubAuthorities) +1) * sizeof(char);

  if (len < dwSidSize){
    SetLastError(ERROR_INSUFFICIENT_BUFFER);
    return -1;
  }

  _snprintf(buf,len,"S-%lu-",dwSidRev);

  if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ){
    _snprintf(buf + strlen(buf),len-(strlen(buf)+1),
	    "0x%02hx%02hx%02hx%02hx%02hx%02hx",
	    (USHORT) psia->Value[0],
	    (USHORT) psia->Value[1],
	    (USHORT) psia->Value[2],
	    (USHORT) psia->Value[3],
	    (USHORT) psia->Value[4],
	    (USHORT) psia->Value[5]);
  }else {
    _snprintf(buf + strlen(buf),len - (strlen(buf)+1),
	      "%lu",
	      (USHORT) (psia->Value[5])      +
	      (USHORT) (psia->Value[4] <<  8)+
	      (USHORT) (psia->Value[3] << 16)+
	      (USHORT) (psia->Value[2] << 24));
  }

  for (dwCounter = 0; dwCounter < dwSubAuthorities; dwCounter++){
    _snprintf(buf + strlen(buf),len - (strlen(buf)+1),"-%lu",
	      *GetSidSubAuthority(pSid,dwCounter));
  }
  
  return 0;
}
Beispiel #10
0
/*!
@brief Gets Integration level of the given process in Vista. 
In the older OS assumes the integration level is equal to SECURITY_MANDATORY_HIGH_RID

The function opens the process for all access and opens its token for all access. 
Then it extracts token information and closes the handles.
@param[in] dwProcessId ID of the process to operate
@param[out] pdwProcessIL pointer to write the value
@return HRESULT
@retval <return value> { description }
@remarks Function check for OS version by querying the presence of Kernel32.GetProductInfo function. 
This way is used due to the function is called from InstallShield12 script, so GetVersionEx returns incorrect value.
@todo restrict access rights when quering for tokens
*/
inline HRESULT GetProcessIL(DWORD dwProcessId, LPDWORD pdwProcessIL)
{
	HRESULT hr=S_OK;
	if(!pdwProcessIL)
		hr=E_INVALIDARG;
	if(SUCCEEDED(hr))
	{
		bool bVista=false;
		{
			// When the function is called from IS12, GetVersionEx returns dwMajorVersion=5 on Vista!
			HMODULE hmodKernel32=LoadLibraryA("Kernel32");
			if(hmodKernel32 && GetProcAddress(hmodKernel32, "GetProductInfo"))
				bVista=true;
			if(hmodKernel32) FreeLibrary(hmodKernel32);
		}

		DWORD dwIL=SECURITY_MANDATORY_HIGH_RID;
		if(bVista)
		{//Vista
			HANDLE hToken=NULL;
			HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
			if(hProcess)
			{
				if(OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
				{
					PTOKEN_MANDATORY_LABEL pTIL=NULL;
					DWORD dwSize=0;
					if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwSize) 
						&& ERROR_INSUFFICIENT_BUFFER==GetLastError() && dwSize)
						pTIL=(PTOKEN_MANDATORY_LABEL)HeapAlloc(GetProcessHeap(), 0, dwSize);

					if(pTIL && GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwSize, &dwSize))
					{
						LPBYTE lpb=GetSidSubAuthorityCount(pTIL->Label.Sid);
						if(lpb)
							dwIL = *GetSidSubAuthority(pTIL->Label.Sid, *lpb-1);
						else
							hr=E_UNEXPECTED;
					}
					if(pTIL)
						HeapFree(GetProcessHeap(), 0, pTIL);
					CloseHandle(hToken);
				}//if(OpenProcessToken(...))
				CloseHandle(hProcess);
			}//if(hProcess)
		}//if(bVista)
		if(SUCCEEDED(hr))
			*pdwProcessIL=dwIL;
	}//if(SUCCEEDED(hr))
	return hr;
}
Beispiel #11
0
static void PrintSidText(PSID psid, BPRINT_BUFFER & bp)
{
   //
   // test if parameters passed in are valid, IsValidSid can not take
   // a NULL parameter
   //
   if ( ! psid)
      return;

   // obtain SidIdentifierAuthority
   // obtain sidsubauthority count
   PSID_IDENTIFIER_AUTHORITY psia = GetSidIdentifierAuthority(psid);
   DWORD cSubAs = *GetSidSubAuthorityCount(psid);

   //
   // S-SID_REVISION-
   //
   bprintf(bp, TEXT("S-%lu-"), SID_REVISION);

   //
   // append SidIdentifierAuthority
   //
   if (psia->Value[0] || psia->Value[1]) 
      {
      bprintf(bp, TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
             (USHORT)psia->Value[0],
             (USHORT)psia->Value[1],
             (USHORT)psia->Value[2],
             (USHORT)psia->Value[3],
             (USHORT)psia->Value[4],
             (USHORT)psia->Value[5]);
      }
   else
      {
      bprintf(bp, TEXT("%lu"),
             (ULONG)(psia->Value[5]      ) +
             (ULONG)(psia->Value[4] <<  8) +
             (ULONG)(psia->Value[3] << 16) +
             (ULONG)(psia->Value[2] << 24));
      }

   //
   // append SidSubAuthorities
   //
   for (UINT ix = 0 ; ix < cSubAs; ++ix) 
      {
      bprintf(bp, TEXT("-%lu"), *GetSidSubAuthority(psid, ix));
      }
}
unsigned int GetProcessIntegrityLevel(HANDLE hToken)
{
	std::vector<unsigned char> tokenIL = GetTokenInfo(hToken, TokenIntegrityLevel);

	if (tokenIL.size() > 0)
	{
		PTOKEN_MANDATORY_LABEL il = reinterpret_cast<PTOKEN_MANDATORY_LABEL>(&tokenIL[0]);

		return *GetSidSubAuthority(il->Label.Sid, 0);
	}
	else
	{
		return 0xFFFFFFFF;
	}
}
Beispiel #13
0
BOOL IsDomainSid(
    _In_ PSID pSid
    ) {
    static const SID_IDENTIFIER_AUTHORITY sSidIdAuthNtSecurity = SECURITY_NT_AUTHORITY;
    PUCHAR n = GetSidSubAuthorityCount(pSid);
    if (*n >= 1) {
        SID_IDENTIFIER_AUTHORITY *pIdAuth = GetSidIdentifierAuthority(pSid);
        if (memcmp(pIdAuth, &sSidIdAuthNtSecurity, sizeof(SID_IDENTIFIER_AUTHORITY) == 0)) {
            PDWORD pdwAuth = GetSidSubAuthority(pSid, 0);
            if ((*pdwAuth == SECURITY_NT_NON_UNIQUE) || (*pdwAuth == SECURITY_BUILTIN_DOMAIN_RID)) {
                return TRUE;
            }
        }
    }

    return FALSE;
}
Beispiel #14
0
static char *
put_sid (PSID psid)
{
  static char s[512];
  char t[32];
  DWORD i;

  strcpy (s, "S-1-");
  sprintf(t, "%u", GetSidIdentifierAuthority (psid)->Value[5]);
  strcat (s, t);
  for (i = 0; i < *GetSidSubAuthorityCount (psid); ++i)
    {
      sprintf(t, "-%" PRIu32 , (unsigned int) *GetSidSubAuthority (psid, i));
      strcat (s, t);
    }
  return s;
}
Beispiel #15
0
bool GetCurrentProcessIntegrityLevel(int* level) {
  bool ret = false;
  HANDLE process = ::GetCurrentProcess(), token;
  if (OpenProcessToken(process, TOKEN_QUERY | TOKEN_QUERY_SOURCE, &token)) {
    DWORD size;
    if (!GetTokenInformation(token, TokenIntegrityLevel, NULL, 0, &size) &&
        GetLastError() == ERROR_INSUFFICIENT_BUFFER) {

      char* buf = STACK_ARRAY(char, size);
      TOKEN_MANDATORY_LABEL* til =
          reinterpret_cast<TOKEN_MANDATORY_LABEL*>(buf);
      if (GetTokenInformation(token, TokenIntegrityLevel, til, size, &size)) {

        DWORD count = *GetSidSubAuthorityCount(til->Label.Sid);
        *level = *GetSidSubAuthority(til->Label.Sid, count - 1);
        ret = true;
      }
    }
const TCHAR *vncExportACL::SidToText( PSID psid )
{
    // S-rev- + SIA + subauthlen*maxsubauth + terminator
    static TCHAR buf[15 + 12 + 12*SID_MAX_SUB_AUTHORITIES + 1];
    TCHAR *p = &buf[0];
    PSID_IDENTIFIER_AUTHORITY psia;
    DWORD numSubAuths, i;

    // Validate the binary SID.

    if (!IsValidSid(psid))
        return FALSE;

    psia = GetSidIdentifierAuthority(psid);

    p = buf;
    p += _sntprintf(p, &buf[sizeof buf] - p, _T("S-%lu-"), 0x0f & *((byte *)psid));

    if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
        p += _sntprintf( p, &buf[sizeof buf] - p, _T("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
                         (USHORT) psia->Value[0], (USHORT) psia->Value[1],
                         (USHORT) psia->Value[2], (USHORT) psia->Value[3],
                         (USHORT) psia->Value[4], (USHORT) psia->Value[5] );
    else
        p += _sntprintf(p, &buf[sizeof buf] - p, _T("%lu"), (ULONG) (psia->Value[5]) +
                        (ULONG) (psia->Value[4] << 8) + (ULONG) (psia->Value[3] << 16) +
                        (ULONG) (psia->Value[2] << 24));

    // Add SID subauthorities to the string.

    numSubAuths = *GetSidSubAuthorityCount(psid);
    for (i = 0; i < numSubAuths; ++ i)
        p += _sntprintf(p, &buf[sizeof buf] - p, _T("-%lu"), *GetSidSubAuthority(psid, i));

    return buf;
}
Beispiel #17
0
sal_Bool SAL_CALL osl_getUserIdent(oslSecurity Security, rtl_uString **strIdent)
{
    if (Security != NULL)
    {
        oslSecurityImpl *pSecImpl = (oslSecurityImpl*)Security;

        HANDLE hAccessToken = pSecImpl->m_hToken;

        if (hAccessToken == NULL)
            OpenProcessToken(GetCurrentProcess(), TOKEN_DUP_QUERY, &hAccessToken);

        if (hAccessToken)
        {
            sal_Char        *Ident;
            DWORD  nInfoBuffer = 512;
            UCHAR* pInfoBuffer = malloc(nInfoBuffer);

            while (!GetTokenInformation(hAccessToken, TokenUser,
                                           pInfoBuffer, nInfoBuffer, &nInfoBuffer))
            {
                if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
                    pInfoBuffer = realloc(pInfoBuffer, nInfoBuffer);
                else
                {
                    free(pInfoBuffer);
                    pInfoBuffer = NULL;
                    break;
                }
            }

            if (pSecImpl->m_hToken == NULL)
                CloseHandle(hAccessToken);

            if (pInfoBuffer)
            {
                PSID pSid = ((PTOKEN_USER)pInfoBuffer)->User.Sid;
                PSID_IDENTIFIER_AUTHORITY psia;
                DWORD dwSubAuthorities;
                DWORD dwSidRev=SID_REVISION;
                DWORD dwCounter;
                DWORD dwSidSize;
                PUCHAR pSSACount;

                /* obtain SidIdentifierAuthority */
                psia=GetSidIdentifierAuthority(pSid);

                /* obtain sidsubauthority count */
                pSSACount = GetSidSubAuthorityCount(pSid);
                dwSubAuthorities = (*pSSACount < 5) ? *pSSACount : 5;

                /* buffer length: S-SID_REVISION- + identifierauthority- + subauthorities- + NULL */
                Ident=malloc(88*sizeof(sal_Char));

                /* prepare S-SID_REVISION- */
                dwSidSize=wsprintf(Ident, TEXT("S-%lu-"), dwSidRev);

                /* prepare SidIdentifierAuthority */
                if ((psia->Value[0] != 0) || (psia->Value[1] != 0))
                {
                    dwSidSize+=wsprintf(Ident + strlen(Ident),
                                TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
                                (USHORT)psia->Value[0],
                                (USHORT)psia->Value[1],
                                (USHORT)psia->Value[2],
                                (USHORT)psia->Value[3],
                                (USHORT)psia->Value[4],
                                (USHORT)psia->Value[5]);
                }
                else
                {
                    dwSidSize+=wsprintf(Ident + strlen(Ident),
                                TEXT("%lu"),
                                (ULONG)(psia->Value[5]      )   +
                                (ULONG)(psia->Value[4] <<  8)   +
                                (ULONG)(psia->Value[3] << 16)   +
                                (ULONG)(psia->Value[2] << 24)   );
                }

                /* loop through SidSubAuthorities */
                for (dwCounter=0; dwCounter < dwSubAuthorities; dwCounter++)
                {
                    dwSidSize+=wsprintf(Ident + dwSidSize, TEXT("-%lu"),
                                *GetSidSubAuthority(pSid, dwCounter) );
                }

                rtl_uString_newFromAscii( strIdent, Ident );

                free(pInfoBuffer);
                free(Ident);

                return sal_True;
            }
        }
        else
        {
            DWORD needed=0;
            sal_Unicode     *Ident;

            WNetGetUserA(NULL, NULL, &needed);
            if (needed < 16)
            {
                needed = 16;
            }
            Ident=malloc(needed*sizeof(sal_Unicode));

            if (WNetGetUserW(NULL, Ident, &needed) != NO_ERROR)
            {
                wcscpy(Ident, L"unknown");
                Ident[7] = L'\0';
            }

            rtl_uString_newFromStr( strIdent, Ident);

            free(Ident);

            return sal_True;
        }
    }

    return sal_False;
}
BOOL GetProcessIntegrityLevel(
   HANDLE hProcess, 
   PDWORD pIntegrityLevel, 
   PDWORD pPolicy, 
   PDWORD pResourceIntegrityLevel, 
   PDWORD pResourcePolicy) 
{   
   HANDLE hToken = NULL;

   /* The OpenProcessToken function opens the access token associated with a process. 
    * ProcessHandle [in]
    *    A handle to the process whose access token is opened. 
	*    The process must have the PROCESS_QUERY_INFORMATION access permission.
	* DesiredAccess [in]
    *    Specifies an access mask that specifies the requested types 
	*    of access to the access token. These requested access types 
	*    are compared with the discretionary access control list (DACL) 
	*    of the token to determine which accesses are granted or denied.
    */
   if (!OpenProcessToken(hProcess, TOKEN_READ, &hToken)) 
   {
      return(FALSE);
   }

   BOOL bReturn = FALSE;
   
   /* First, compute the size of the buffer to get the Integrity level */
   DWORD dwNeededSize = 0;
   /* The GetTokenInformation function retrieves a specified type 
    * of information about an access token. The calling process must have appropriate 
	* access rights to obtain the information. */
   if (!GetTokenInformation(
          hToken, 
		  TokenIntegrityLevel, 
		  NULL, 
		  0, 
		  &dwNeededSize)) 
   {
      PTOKEN_MANDATORY_LABEL pTokenInfo = NULL;
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 
	  {
         /* Second, allocate a memory block with the the required size */
         pTokenInfo = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwNeededSize);
         if (pTokenInfo != NULL) 
		 {
            /* And finally, ask for the integrity level */
            if (GetTokenInformation(
				  hToken, 
				  TokenIntegrityLevel, 
				  pTokenInfo, 
                  dwNeededSize, 
				  &dwNeededSize)) 
			{

               /* The GetSidSubAuthority function returns a pointer to a 
			    * specified subauthority in a security identifier (SID). 
				* The subauthority value is a relative identifier (RID). 
				* pSid [in] 
                *   A pointer to the SID structure from which a pointer 
				*   to a subauthority is to be returned.
                *   This function does not handle SID structures that are not valid. 
				*   Call the IsValidSid function to verify that the SID structure 
				*   is valid before you call this function.
                * nSubAuthority [in] 
                *   Specifies an index value identifying the subauthority array 
				*   element whose address the function will return.
				*   The function performs no validation tests on this value. 
				*   An application can call the GetSidSubAuthorityCount function 
				*   to discover the range of acceptable values.
				* Return value:
				*   If the function succeeds, the return value is a pointer 
				*   to the specified SID subauthority. To get extended error information, 
				*   call GetLastError.
			    */

               /* Exaplanation for GetSidSubAuthorityCount function
			    * The GetSidSubAuthorityCount function returns a pointer 
				* to the member in a security identifier (SID) structure 
				* that contains the subauthority count.
				* pSid [in] 
                *   A pointer to the SID structure from which a pointer
				*   to the subauthority count is returned.
                *   This function does not handle SID structures that are not valid.
				*   Call the IsValidSid function to verify that the SID structure 
				*   is valid before you call this function.
                *
			    */
               *pIntegrityLevel = 
                  *GetSidSubAuthority(
                     pTokenInfo->Label.Sid, 
                     (*GetSidSubAuthorityCount(pTokenInfo->Label.Sid)-1)
                     );
               bReturn = TRUE;
            }
          
            /* Don't forget to free the memory */
            LocalFree(pTokenInfo);
         }
      }
   }

   /* Try to get the policy if the integrity level was available */
   if (bReturn) 
   {
      *pPolicy = TOKEN_MANDATORY_POLICY_OFF;
      dwNeededSize = sizeof(DWORD);
      GetTokenInformation(
		  hToken, 
		  TokenMandatoryPolicy, 
		  pPolicy, 
          dwNeededSize, 
		  &dwNeededSize);
   }
   
   /* Look for the resource policy */
   *pResourceIntegrityLevel = 0; 
   /* 0 means none explicitely set */
   *pResourcePolicy = 0;
   
   PACL pSACL = NULL;
   PSECURITY_DESCRIPTOR pSD = NULL;
   DWORD dwResult = ERROR_SUCCESS;
   
   /* Look for the no-read-up/no-write-up policy in the SACL */
   if (hToken != NULL) 
   {
      /* The GetSecurityInfo function retrieves a copy of the 
	   * security descriptor for an object specified by a handle.
	   * handle [in] 
       *  A handle to the object from which to retrieve security information.
	   * ObjectType [in] 
       *  SE_OBJECT_TYPE enumeration value that indicates the type of object.
       * SecurityInfo [in] 
       *  A set of bit flags that indicate the type of security information to retrieve.
	   *  This parameter can be a combination of the SECURITY_INFORMATION bit flags.
       * ppsidOwner [out, optional] 
       *  A pointer to a variable that receives a pointer to the owner SID 
	   *  in the security descriptor returned in ppSecurityDescriptor. 
	   *  The returned pointer is valid only if you set the OWNER_SECURITY_INFORMATION flag. 
	   *  This parameter can be NULL if you do not need the owner SID.
       *
       *
	   */
      dwResult = 
         GetSecurityInfo(
            hProcess, 
			SE_KERNEL_OBJECT,
            LABEL_SECURITY_INFORMATION,
            NULL, 
			NULL, 
			NULL, 
            &pSACL, 
			&pSD
          );

      if (dwResult == ERROR_SUCCESS) 
	  {
         if (pSACL != NULL) 
		 {
            SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
			/* The GetAce function obtains a pointer to an access control entry (ACE) 
			 * in an access control list (ACL).
			 * pAcl [in] 
             *    A pointer to an ACL that contains the ACE to be retrieved.
             * dwAceIndex [in] 
             *    The index of the ACE to be retrieved. 
			 *    A value of zero corresponds to the first ACE in the ACL, 
			 *    a value of one to the second ACE, and so on.
             * pAce [out] 
             *    A pointer to a pointer that the function sets to the address of the ACE.
             *
			 */
            if ((pSACL->AceCount > 0) && (GetAce(pSACL, 0, (PVOID*)&pACE))) 
			{
               if (pACE != NULL) 
			   {
                  SID* pSID = (SID*)(&pACE->SidStart);
                  *pResourceIntegrityLevel = pSID->SubAuthority[0];
                  *pResourcePolicy = pACE->Mask;
               }
            }
         }
      }
      
      /* Cleanup memory allocated on our behalf */
      if (pSD != NULL) LocalFree(pSD); 
   }

   /* Don't forget to close the token handle. */
   CloseHandle(hToken);

   return(bReturn);   
}
Beispiel #19
0
// nearly straight from the SDK
BOOL Sid2Text( PSID ps, char *buf, int bufSize )
{
	PSID_IDENTIFIER_AUTHORITY psia;
	DWORD dwSubAuthorities;
	DWORD dwSidRev = SID_REVISION;
	DWORD i;
	int n, size;
	char *p;

	// Validate the binary SID.

	if ( ! IsValidSid( ps ) )
		return FALSE;

	// Get the identifier authority value from the SID.

	psia = GetSidIdentifierAuthority( ps );

	// Get the number of subauthorities in the SID.

	dwSubAuthorities = *GetSidSubAuthorityCount( ps );

	// Compute the buffer length.
	// S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL

	size = 15 + 12 + ( 12 * dwSubAuthorities ) + 1;

	// Check input buffer length.
	// If too small, indicate the proper size and set last error.

	if ( bufSize < size )
	{
		SetLastError( ERROR_INSUFFICIENT_BUFFER );
		return FALSE;
	}

	// Add 'S' prefix and revision number to the string.

	size = wsprintf( buf, "S-%lu-", dwSidRev );
	p = buf + size;

	// Add SID identifier authority to the string.

	if ( psia->Value[0] != 0 || psia->Value[1] != 0 )
	{
		n = wsprintf( p, "0x%02hx%02hx%02hx%02hx%02hx%02hx",
		(USHORT) psia->Value[0], (USHORT) psia->Value[1],
		(USHORT) psia->Value[2], (USHORT) psia->Value[3],
		(USHORT) psia->Value[4], (USHORT) psia->Value[5] );
		size += n;
		p += n;
	}
	else
	{
		n = wsprintf( p, "%lu", ( (ULONG) psia->Value[5] ) +
		( (ULONG) psia->Value[4] << 8 ) + ( (ULONG) psia->Value[3] << 16 ) +
		( (ULONG) psia->Value[2] << 24 ) );
		size += n;
		p += n;
	}

	// Add SID subauthorities to the string.

	for ( i = 0; i < dwSubAuthorities; ++ i )
	{
		n = wsprintf( p, "-%lu", *GetSidSubAuthority( ps, i ) );
		size += n;
		p += n;
	}

	return TRUE;
}
Beispiel #20
0
JNIEXPORT void JNICALL
Java_org_apache_harmony_auth_module_NTSystem_load
(JNIEnv * jenv, jobject thiz)
{
	DWORD i; /* tmp */

	DWORD dwError = -1; /* presume unknown error */
	LPCSTR errMsg = NULL;
	DWORD dwSaveError = -1;

	HANDLE hUser = INVALID_HANDLE_VALUE;
	HANDLE iToken= INVALID_HANDLE_VALUE;

	LPVOID lpUserData = NULL, lpGroupData = NULL, lpAllGroupsData = NULL;
	LPSTR lpStr0 = NULL, lpStr1 = NULL, lpStr2 = NULL;
	LPSTR lpUserSid = NULL, lpDomainName = NULL;
	PSID domainSid = NULL;

	SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;

	TOKEN_USER * ptu = NULL;
	PSID userSid = NULL;

	jclass jkl = NULL;
	jmethodID ctor = NULL;

	jstring jstrSid = NULL;
	jstring jstrUser = NULL;
	jstring jstrDomain = NULL;
	jobject obj = NULL;

	jstring jstrDomainSid = NULL;

	PTOKEN_PRIMARY_GROUP ptpg = NULL;
	PSID groupSid = NULL;

	jclass jklassPrimaryGroup = NULL;
	jobject jobj = NULL;

	PTOKEN_GROUPS ptgs = NULL;

	jclass klassGroup = NULL;
	jmethodID groupCtor3 = NULL;
	jmethodID groupCtor1 = NULL;
	jobjectArray jgroups = NULL;

	jobject jobj1 = NULL;

	//
	// Get the token for the user currently running this Thread
	//
	if( !OpenThreadToken(GetCurrentThread(), TOKEN_QUERY|TOKEN_DUPLICATE, TRUE, &hUser) ) {
		// failed to open thread token. well, let's try process' one
		if( !OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY|TOKEN_DUPLICATE, &hUser) ) {
			errMsg = "Unable to obtain user token";
			goto exit;
		}
	}

	//
	// Obtain the User's info
	//
	if( NULL == (lpUserData = (TOKEN_USER*)QueryInfo(jenv, hUser, TokenUser)) ) {
		errMsg = "Unable to obtain user's token info";
		goto exit;
	}

	ptu = (TOKEN_USER*)lpUserData;

	if( !IsValidSid(ptu->User.Sid) ) {
		errMsg = "Got invalid user's SID";
		goto exit;
	}

	userSid = ptu->User.Sid;

	ConvertSidToStringSid(userSid, &lpStr0);
	lpUserSid = lpStr0;
	lpStr0 = NULL;

	//
    // step +n:  Retrieve user name and domain name basing on user's SID.
	//
	if( !GetInfo(jenv, userSid, &lpStr0, &lpStr1) ) {
		errMsg = "Unable to retrieve user's name and domain";
		goto exit;
	};

	jkl = (*jenv)->FindClass (jenv, "org/apache/harmony/auth/NTSidUserPrincipal");
	if( NULL == jkl || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find class NTSidUserPrincipal";
		goto exit;
	}
	ctor = (*jenv)->GetMethodID (jenv, jkl, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
	if( NULL == ctor || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find ctor at NTSidUserPrincipal class";
		goto exit;
	}

	jstrSid = (*jenv)->NewStringUTF (jenv, lpUserSid);
	jstrUser = (*jenv)->NewStringUTF (jenv, lpStr0);
	jstrDomain = (*jenv)->NewStringUTF (jenv, lpStr1);
	obj = (*jenv)->NewObject (jenv, jkl, ctor, jstrSid, jstrUser, jstrDomain);
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}
	(*jenv)->SetObjectField (jenv, thiz, jf_user, obj);
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}
	
	LocalFree(lpStr0); lpStr0 = NULL;
	lpDomainName = lpStr1; 
	lpStr1 = NULL;

	//
	// Step +1: Obtain domain SID
	//
	if( !AllocateAndInitializeSid(
		&sia, 4, 
		*GetSidSubAuthority(userSid, 0), 
		*GetSidSubAuthority(userSid, 1), 
		*GetSidSubAuthority(userSid, 2),
		*GetSidSubAuthority(userSid, 3), 
		0, 0, 0, 0, 
		&domainSid)) {

		errMsg = "Unable to allocate domain SID";
		goto exit;
	}

	if( !IsValidSid(domainSid) ) {
		errMsg = "Got invalid domain SID";
		goto exit;
	}

	ConvertSidToStringSid(domainSid, &lpStr0);

	jstrDomainSid = (*jenv)->NewStringUTF (jenv, lpStr0);
	(*jenv)->SetObjectField (jenv, thiz, jf_domainSid, jstrDomainSid);
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}
	LocalFree(lpStr0); lpStr0 = NULL;

	//
	// step +1: get primary group sid
	//
	if( NULL == (lpGroupData = QueryInfo(jenv, hUser, TokenPrimaryGroup)) ) {
		errMsg = "Unable to get primary group";
		goto exit;
	};

	ptpg = (PTOKEN_PRIMARY_GROUP)lpGroupData;
	groupSid = ptpg->PrimaryGroup;

	if( !IsValidSid(groupSid) ) {
		errMsg = "Got invalid primary groups' SID";
		goto exit;
	}

	if( !GetInfo(jenv, groupSid, &lpStr0, &lpStr1) ) {
		errMsg = "Unable to get primary group's info";
		goto exit;
	}
	ConvertSidToStringSid(groupSid, &lpStr2);

	jklassPrimaryGroup = (*jenv)->FindClass (jenv, "org/apache/harmony/auth/NTSidPrimaryGroupPrincipal");
	if( NULL == jklassPrimaryGroup || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find class NTSidPrimaryGroupPrincipal";
		goto exit;
	}

	ctor = (*jenv)->GetMethodID (jenv, jklassPrimaryGroup, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
	if( NULL == ctor ) {
		errMsg = "Could not find appropriate ctor at NTSidPrimaryGroupPrincipal";
		goto exit;
	}

	jobj = (*jenv)->NewObject (jenv, jklassPrimaryGroup, ctor, 
		(*jenv)->NewStringUTF (jenv, lpStr2), (*jenv)->NewStringUTF (jenv, lpStr0), (*jenv)->NewStringUTF (jenv, lpStr1));

	LocalFree(lpStr0); lpStr0 = NULL;
	LocalFree(lpStr1); lpStr1 = NULL;
	LocalFree(lpStr2); lpStr2 = NULL;


	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}
	(*jenv)->SetObjectField (jenv, thiz, jf_mainGroup, jobj);

	//
	// step +1: get groups
	//
	if( NULL== (lpAllGroupsData = QueryInfo(jenv, hUser, TokenGroups)) ) {
		errMsg = "Unable to query user's groups";
		goto exit;
	}

	ptgs = (PTOKEN_GROUPS)lpAllGroupsData;

	klassGroup = (*jenv)->FindClass (jenv, "org/apache/harmony/auth/NTSidGroupPrincipal");
	if( NULL == klassGroup || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find NTSidGroupPrincipal";
		goto exit;
	};

	groupCtor3 = (*jenv)->GetMethodID (jenv, klassGroup, "<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
	if( NULL == groupCtor3 || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find appropriate ctor with 3 Strings at NTSidGroupPrincipal";
		goto exit;
	};
	groupCtor1 = (*jenv)->GetMethodID (jenv, klassGroup, "<init>", "(Ljava/lang/String;)V");
	if( NULL == groupCtor1 || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not find appropriate ctor at NTSidGroupPrincipal";
		goto exit;
	};

	// allocate an array 
	jgroups = (*jenv)->NewObjectArray (jenv, ptgs->GroupCount, klassGroup, NULL);

	if( NULL == jgroups || (*jenv)->ExceptionCheck (jenv) ) {
		errMsg = "Could not create array of NTSidGroupPrincipal";
		goto exit;
	};

	for( i=0; i<ptgs->GroupCount; i++ ) {

		ConvertSidToStringSid(ptgs->Groups[i].Sid, &lpStr2);

		if( !GetInfo(jenv, ptgs->Groups[i].Sid, &lpStr0, &lpStr1) ) {
			jobj1 = (*jenv)->NewObject (jenv, klassGroup, groupCtor1, (*jenv)->NewStringUTF (jenv, lpStr2));
			//printf("SET_FIELD: %d] Simple Group: %s\n", i, lpStr2 );
		}
		else {
			jobj1 = (*jenv)->NewObject (jenv, klassGroup, groupCtor3, 
				(*jenv)->NewStringUTF (jenv, lpStr2), (*jenv)->NewStringUTF (jenv, lpStr0), (*jenv)->NewStringUTF (jenv, lpStr1));
//			printf("SET_FIELD: %d] Group: %s@%s \n\t %s\n", i, lpStr0, lpStr1, lpStr2 );
		}
		if( NULL != lpStr0 ) { LocalFree(lpStr0); lpStr0 = NULL; }
		if( NULL != lpStr1 ) { LocalFree(lpStr1); lpStr1 = NULL; }
		if( NULL != lpStr2 ) { LocalFree(lpStr2); lpStr2 = NULL; }
		if( NULL == jobj1 || (*jenv)->ExceptionCheck (jenv) ) {
			goto exit;
		}
		(*jenv)->SetObjectArrayElement (jenv, jgroups, i, jobj1);
		if( (*jenv)->ExceptionCheck (jenv) ) {
			goto exit;
		}
	};
	(*jenv)->SetObjectField (jenv, thiz, jf_groups, jgroups);
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}

	//
	// step +1: get itoken
	//

	//FIXME: on NT 'SecurityImpersonation'  is not supported. 
	// Check whether we support NT - just to be sure.
	if (!DuplicateToken (hUser, SecurityImpersonation, &iToken)) {
		errMsg = "Unable to duplicate impersonation token";
		goto exit;
	};

	// printf("_SET_FIELD: iToken: %d \n", ((long)iToken) );
	(*jenv)->SetLongField (jenv, thiz, jf_token, ((jlong)iToken));
	if( (*jenv)->ExceptionCheck (jenv) ) {
		goto exit;
	}

	dwError = 0;
exit:
	dwSaveError = GetLastError();

	if( NULL != lpUserData )		LocalFree(lpUserData);
	if( NULL != lpGroupData )		LocalFree(lpGroupData);
	if( NULL != lpAllGroupsData )	LocalFree(lpAllGroupsData);
	if( NULL != lpStr0 )			LocalFree(lpStr0);
	if( NULL != lpStr1 )			LocalFree(lpStr1);
	if( NULL != lpStr2 )			LocalFree(lpStr2);
	if( NULL != lpUserSid )			LocalFree(lpUserSid);
	if( NULL != lpDomainName)		LocalFree(lpDomainName);
	//
	if( NULL != domainSid )			FreeSid(domainSid);

	if( INVALID_HANDLE_VALUE != hUser ) CloseHandle(hUser);

	if( (*jenv)->ExceptionCheck (jenv) ) {
		(*jenv)->ExceptionDescribe (jenv);
	}
	else {
		if( (0 != dwError) || (NULL!=errMsg) ) {
			if( dwError == -1 ) {
				dwError = dwSaveError;
			}
			error((LPVOID)jenv, (LPCSTR)errMsg, dwError);
		}
	}
	return;
}
Beispiel #21
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);
}
Beispiel #22
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;
}
Beispiel #23
0
void GetTextualSid(
    PSID pSid,            // binary Sid
    PTCHAR TextualSid)    // buffer for Textual representation of Sid
{
    PSID_IDENTIFIER_AUTHORITY psia;
    DWORD dwSubAuthorities;
    DWORD dwSidRev=SID_REVISION;
    DWORD dwCounter;
    DWORD dwSidSize;

    // Validate the binary SID.

    if(!IsValidSid(pSid)) return;

    // Get the identifier authority value from the SID.

    psia = GetSidIdentifierAuthority(pSid);

    // Get the number of subauthorities in the SID.

    dwSubAuthorities = *GetSidSubAuthorityCount(pSid);

    // Compute the buffer length.
    // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL

    dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);

    // Add 'S' prefix and revision number to the string.

    dwSidSize= _stprintf(TextualSid, _T("S-%lu-"), dwSidRev );

    // Add SID identifier authority to the string.

    if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) {

        dwSidSize += _stprintf(TextualSid + lstrlen(TextualSid),
                    _T("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
                    (USHORT)psia->Value[0],
                    (USHORT)psia->Value[1],
                    (USHORT)psia->Value[2],
                    (USHORT)psia->Value[3],
                    (USHORT)psia->Value[4],
                    (USHORT)psia->Value[5]);

    } else {

        dwSidSize += _stprintf(TextualSid + lstrlen(TextualSid),
                     _T("%lu"),
                    (ULONG)(psia->Value[5]      )   +
                    (ULONG)(psia->Value[4] <<  8)   +
                    (ULONG)(psia->Value[3] << 16)   +
                    (ULONG)(psia->Value[2] << 24)   );
    }

    // Add SID subauthorities to the string.
    //
    for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++) {
        dwSidSize+= _stprintf(TextualSid + dwSidSize, _T("-%lu"),
                    *GetSidSubAuthority(pSid, dwCounter) );
    }
}
Beispiel #24
0
NTSTATUS NTAPI
LsaApLogonUserEx (PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logon_type,
		  PVOID auth, PVOID client_auth_base, ULONG auth_len,
		  PVOID *pbuf, PULONG pbuf_len, PLUID logon_id,
		  PNTSTATUS sub_stat, PLSA_TOKEN_INFORMATION_TYPE tok_type,
		  PVOID *tok, PUNICODE_STRING *account,
		  PUNICODE_STRING *authority, PUNICODE_STRING *machine)
{
  DWORD checksum, i;
  PDWORD csp, csp_end;
  NTSTATUS stat;
  SECPKG_CLIENT_INFO clinf;
  PLSA_TOKEN_INFORMATION_V2 tokinf;

  cyglsa_t *authinf = (cyglsa_t *) auth;

  /* Check if the caller has the SeTcbPrivilege, otherwise refuse service. */
  stat = funcs->GetClientInfo (&clinf);
  if (stat != STATUS_SUCCESS)
    {
      cyglsa_printf ("GetClientInfo failed: 0x%08lx\n", stat);
      return stat;
    }
  if (!clinf.HasTcbPrivilege)
    {
      cyglsa_printf ("Client has no TCB privilege.  Access denied.\n");
      return STATUS_ACCESS_DENIED;
    }

  /* Make a couple of validity checks. */
  if (auth_len < sizeof *authinf
      || authinf->magic != CYG_LSA_MAGIC
      || !authinf->username[0]
      || !authinf->domain[0])
    {
      cyglsa_printf ("Invalid authentication parameter.\n");
      return STATUS_INVALID_PARAMETER;
    }
  checksum = CYG_LSA_MAGIC;
  csp = (PDWORD) &authinf->username;
  csp_end = (PDWORD) ((PBYTE) authinf + auth_len);
  while (csp < csp_end)
    checksum += *csp++;
  if (authinf->checksum != checksum)
    {
      cyglsa_printf ("Invalid checksum.\n");
      return STATUS_INVALID_PARAMETER_3;
    }

  /* Set account to username and authority to domain resp. machine name.
     The name of the logon account name as returned by LookupAccountSid
     is created from here as "authority\account". */
  authinf->username[UNLEN] = '\0';
  authinf->domain[MAX_DOMAIN_NAME_LEN] = '\0';
  if (account && !(*account = uni_alloc (authinf->username,
  					 wcslen (authinf->username))))
    {
      cyglsa_printf ("No memory trying to create account.\n");
      return STATUS_NO_MEMORY;
    }
  if (authority && !(*authority = uni_alloc (authinf->domain,
					     wcslen (authinf->domain))))
    {
      cyglsa_printf ("No memory trying to create authority.\n");
      return STATUS_NO_MEMORY;
    }
  if (machine)
    {
      WCHAR mach[MAX_COMPUTERNAME_LENGTH + 1];
      DWORD msize = MAX_COMPUTERNAME_LENGTH + 1;
      if (!GetComputerNameW (mach, &msize))
        wcscpy (mach, L"UNKNOWN");
      if (!(*machine = uni_alloc (mach, wcslen (mach))))
	{
	  cyglsa_printf ("No memory trying to create machine.\n");
	  return STATUS_NO_MEMORY;
	}
    }
  /* Create a fake buffer in pbuf which is free'd again in the client.
     Windows 2000 tends to crash when setting this pointer to NULL. */
  if (pbuf)
    {
#ifdef JUST_ANOTHER_NONWORKING_SOLUTION
      cygprf_t prf;
      WCHAR sam_username[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
      SECURITY_STRING sam_user, prefix;
      PUCHAR user_auth;
      ULONG user_auth_size;
      WCHAR flatname[UNLEN + 1];
      UNICODE_STRING flatnm;
      TOKEN_SOURCE ts;
      HANDLE token;
#endif /* JUST_ANOTHER_NONWORKING_SOLUTION */

      stat = funcs->AllocateClientBuffer (request, 64UL, pbuf);
      if (!LSA_SUCCESS (stat))
	{
	  cyglsa_printf ("AllocateClientBuffer failed: 0x%08lx\n", stat);
	  return stat;
	}
#ifdef JUST_ANOTHER_NONWORKING_SOLUTION
      prf.magic_pre = MAGIC_PRE;
      prf.token = NULL;
      prf.magic_post = MAGIC_POST;

#if 0
      /* That's how it was supposed to work according to MSDN... */
      wcscpy (sam_username, authinf->domain);
      wcscat (sam_username, L"\\");
      wcscat (sam_username, authinf->username);
#else
      /* That's the only solution which worked, and then it only worked
         for machine local accounts.  No domain authentication possible.
	 STATUS_NO_SUCH_USER galore! */
      wcscpy (sam_username, authinf->username);
#endif
      RtlInitUnicodeString (&sam_user, sam_username);
      RtlInitUnicodeString (&prefix, L"");
      RtlInitEmptyUnicodeString (&flatnm, flatname,
				 (UNLEN + 1) * sizeof (WCHAR));

      stat = funcs->GetAuthDataForUser (&sam_user, SecNameSamCompatible,
					NULL, &user_auth,
					&user_auth_size, &flatnm);
      if (!NT_SUCCESS (stat))
	{
	  char sam_u[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
	  wcstombs (sam_u, sam_user.Buffer, sizeof (sam_u));
	  cyglsa_printf ("GetAuthDataForUser (%u,%u,%s) failed: 0x%08lx\n",
		  sam_user.Length, sam_user.MaximumLength, sam_u, stat);
	  return stat;
	}

      memcpy (ts.SourceName, "MSYS.2", 6);
      ts.SourceIdentifier.HighPart = 0;
      ts.SourceIdentifier.LowPart = 0x0104;
      RtlInitEmptyUnicodeString (&flatnm, flatname,
				 (UNLEN + 1) * sizeof (WCHAR));
      stat = funcs->ConvertAuthDataToToken (user_auth, user_auth_size,
					    SecurityDelegation, &ts,
					    Interactive, *authority,
					    &token, logon_id, &flatnm,
					    sub_stat);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("ConvertAuthDataToToken failed: 0x%08lx\n", stat);
	  return stat;
	}

      stat = funcs->DuplicateHandle (token, &prf.token);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("DuplicateHandle failed: 0x%08lx\n", stat);
	  return stat;
	}
      
      stat = funcs->CopyToClientBuffer (request, sizeof prf, *pbuf, &prf);
      if (!NT_SUCCESS (stat))
	{
	  cyglsa_printf ("CopyToClientBuffer failed: 0x%08lx\n", stat);
	  return stat;
	}
      funcs->FreeLsaHeap (user_auth);
#endif /* JUST_ANOTHER_NONWORKING_SOLUTION */
    }
  if (pbuf_len)
    *pbuf_len = 64UL;

  /* A PLSA_TOKEN_INFORMATION_V2 is allocated in one piece, so... */
#if defined (__x86_64__) || defined (_M_AMD64)
    {
      /* ...on 64 bit systems we have to convert the incoming 32 bit offsets
	 into 64 bit pointers.  That requires to re-evaluate the size of the
	 outgoing tokinf structure and a somewhat awkward procedure to copy
	 the information over. */
      LONG_PTR base;
      PBYTE tptr;
      DWORD size, newsize;
      PSID src_sid;
      PCYG_TOKEN_GROUPS src_grps;
      PTOKEN_GROUPS grps;
      PTOKEN_PRIVILEGES src_privs;
      PACL src_acl;

      base = (LONG_PTR) &authinf->inf;

      newsize = authinf->inf_size;
      newsize += sizeof (TOKEN_USER) - sizeof (CYG_TOKEN_USER); /* User SID */
      newsize += sizeof (PTOKEN_GROUPS) - sizeof (OFFSET); /* Groups */
      src_grps = (PCYG_TOKEN_GROUPS) (base + authinf->inf.Groups);
      newsize += src_grps->GroupCount		  /* Group SIDs */
      		 * (sizeof (SID_AND_ATTRIBUTES)
		    - sizeof (CYG_SID_AND_ATTRIBUTES));
      newsize += sizeof (PSID) - sizeof (OFFSET); /* Primary Group SID */
      newsize += sizeof (PTOKEN_PRIVILEGES) - sizeof (OFFSET); /* Privileges */
      newsize += 0; /* Owner SID */
      newsize += sizeof (PACL) - sizeof (OFFSET); /* Default DACL */

      if (!(tokinf = funcs->AllocateLsaHeap (newsize)))
	return STATUS_NO_MEMORY;
      tptr = (PBYTE)(tokinf + 1);

      tokinf->ExpirationTime = authinf->inf.ExpirationTime;
      /* User SID */
      src_sid = (PSID) (base + authinf->inf.User.User.Sid);
      size = GetLengthSid (src_sid);
      CopySid (size, (PSID) tptr, src_sid);
      tokinf->User.User.Sid = (PSID) tptr;
      tptr += size;
      tokinf->User.User.Attributes = authinf->inf.User.User.Attributes;
      /* Groups */
      grps = (PTOKEN_GROUPS) tptr;
      tokinf->Groups = grps;
      grps->GroupCount = src_grps->GroupCount;
      tptr += sizeof grps->GroupCount
	      + grps->GroupCount * sizeof (SID_AND_ATTRIBUTES);
      /* Group SIDs */
      for (i = 0; i < src_grps->GroupCount; ++i)
	{
	  src_sid = (PSID) (base + src_grps->Groups[i].Sid);
	  size = GetLengthSid (src_sid);
	  CopySid (size, (PSID) tptr, src_sid);
	  tokinf->Groups->Groups[i].Sid = (PSID) tptr;
	  tptr += size;
	  tokinf->Groups->Groups[i].Attributes = src_grps->Groups[i].Attributes;
	}
      /* Primary Group SID */
      src_sid = (PSID) (base + authinf->inf.PrimaryGroup.PrimaryGroup);
      size = GetLengthSid (src_sid);
      CopySid (size, (PSID) tptr, src_sid);
      tokinf->PrimaryGroup.PrimaryGroup = (PSID) tptr;
      tptr += size;
      /* Privileges */
      src_privs = (PTOKEN_PRIVILEGES) (base + authinf->inf.Privileges);
      size = sizeof src_privs->PrivilegeCount
	     + src_privs->PrivilegeCount * sizeof (LUID_AND_ATTRIBUTES);
      memcpy (tptr, src_privs, size);
      tokinf->Privileges = (PTOKEN_PRIVILEGES) tptr;
      tptr += size;
      /* Owner */
      tokinf->Owner.Owner = NULL;
      /* Default DACL */
      src_acl = (PACL) (base + authinf->inf.DefaultDacl.DefaultDacl);
      size = src_acl->AclSize;
      memcpy (tptr, src_acl, size);
      tokinf->DefaultDacl.DefaultDacl = (PACL) tptr;
    }
#else
    {
      /* ...on 32 bit systems we just allocate tokinf with the same size as
         we get, copy the whole structure and convert offsets into pointers. */

      /* Allocate LUID for usage in the logon SID on Windows 2000.  This is
	 not done in the 64 bit code above for hopefully obvious reasons... */
      LUID logon_sid_id;

      if (must_create_logon_sid && !AllocateLocallyUniqueId (&logon_sid_id))
	return STATUS_INSUFFICIENT_RESOURCES;

      if (!(tokinf = funcs->AllocateLsaHeap (authinf->inf_size)))
	return STATUS_NO_MEMORY;
      memcpy (tokinf, &authinf->inf, authinf->inf_size);

      /* User SID */
      tokinf->User.User.Sid = (PSID)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->User.User.Sid);
      /* Groups */
      tokinf->Groups = (PTOKEN_GROUPS)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->Groups);
      /* Group SIDs */
      for (i = 0; i < tokinf->Groups->GroupCount; ++i)
	{
	  tokinf->Groups->Groups[i].Sid = (PSID)
		((PBYTE) tokinf + (LONG_PTR) tokinf->Groups->Groups[i].Sid);
	  if (must_create_logon_sid
	      && tokinf->Groups->Groups[i].Attributes & SE_GROUP_LOGON_ID
	      && *GetSidSubAuthorityCount (tokinf->Groups->Groups[i].Sid) == 3
	      && *GetSidSubAuthority (tokinf->Groups->Groups[i].Sid, 0)
		 == SECURITY_LOGON_IDS_RID)
	    {
	      *GetSidSubAuthority (tokinf->Groups->Groups[i].Sid, 1)
	      = logon_sid_id.HighPart;
	      *GetSidSubAuthority (tokinf->Groups->Groups[i].Sid, 2)
	      = logon_sid_id.LowPart;
	    }
	}

      /* Primary Group SID */
      tokinf->PrimaryGroup.PrimaryGroup = (PSID)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->PrimaryGroup.PrimaryGroup);
      /* Privileges */
      tokinf->Privileges = (PTOKEN_PRIVILEGES)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->Privileges);
      /* Owner SID */
      tokinf->Owner.Owner = NULL;
      /* Default DACL */
      tokinf->DefaultDacl.DefaultDacl = (PACL)
	      ((PBYTE) tokinf + (LONG_PTR) tokinf->DefaultDacl.DefaultDacl);

    }
#endif

  *tok = (PVOID) tokinf;
  *tok_type = LsaTokenInformationV2;

  print_tokinf (tokinf, authinf->inf_size, authinf, &authinf->inf,
		(PVOID)((LONG_PTR) &authinf->inf + authinf->inf_size));

  /* Create logon session. */
  if (!AllocateLocallyUniqueId (logon_id))
    {
      funcs->FreeLsaHeap (*tok);
      *tok = NULL;
      cyglsa_printf ("AllocateLocallyUniqueId failed: Win32 error %lu\n",
		     GetLastError ());
      return STATUS_INSUFFICIENT_RESOURCES;
    }
  stat = funcs->CreateLogonSession (logon_id);
  if (stat != STATUS_SUCCESS)
    {
      funcs->FreeLsaHeap (*tok);
      *tok = NULL;
      cyglsa_printf ("CreateLogonSession failed: 0x%08lx\n", stat);
      return stat;
    }

  cyglsa_printf ("BINGO!!!\n", stat);
  return STATUS_SUCCESS;
}
Beispiel #25
0
BOOL GetProcessIntegrityLevel(HANDLE hProcess, PDWORD pIntegrityLevel, 
   PDWORD pPolicy, PDWORD pResourceIntegrityLevel, PDWORD pResourcePolicy) {
   
   HANDLE hToken = NULL;
   if (!OpenProcessToken(hProcess, TOKEN_READ, &hToken)) {
      return(FALSE);
   }

   BOOL bReturn = FALSE;
   
   // First, compute the size of the buffer to get the Integrity level
   DWORD dwNeededSize = 0;
   if (!GetTokenInformation(
      hToken, TokenIntegrityLevel, NULL, 0, &dwNeededSize)) {

      PTOKEN_MANDATORY_LABEL pTokenInfo = NULL;
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
         // Second, allocate a memory block with the the required size 
         pTokenInfo = (PTOKEN_MANDATORY_LABEL)LocalAlloc(0, dwNeededSize);
         if (pTokenInfo != NULL) {
            // And finally, ask for the integrity level
            if (GetTokenInformation(hToken, TokenIntegrityLevel, pTokenInfo, 
               dwNeededSize, &dwNeededSize)) {

               *pIntegrityLevel = 
                  *GetSidSubAuthority(
                     pTokenInfo->Label.Sid, 
                     (*GetSidSubAuthorityCount(pTokenInfo->Label.Sid)-1)
                     );
               bReturn = TRUE;
            }
          
            // Don't forget to free the memory
            LocalFree(pTokenInfo);
         }
      }
   }

   // Try to get the policy if the integrity level was available
   if (bReturn) {
      *pPolicy = TOKEN_MANDATORY_POLICY_OFF;
      dwNeededSize = sizeof(DWORD);
      GetTokenInformation(hToken, TokenMandatoryPolicy, pPolicy, 
         dwNeededSize, &dwNeededSize);
   }
   
   // Look for the resource policy
   *pResourceIntegrityLevel = 0; // 0 means none explicitely set
   *pResourcePolicy = 0;
   
   PACL pSACL = NULL;
   PSECURITY_DESCRIPTOR pSD = NULL;
   DWORD dwResult = ERROR_SUCCESS;
   
   // Look for the no-read-up/no-write-up policy in the SACL
   if (hToken != NULL) {
      dwResult = 
         GetSecurityInfo(
            hProcess, SE_KERNEL_OBJECT,
            LABEL_SECURITY_INFORMATION,
            NULL, NULL, NULL, 
            &pSACL, &pSD
          );
      if (dwResult == ERROR_SUCCESS) {
         if (pSACL != NULL) {
            SYSTEM_MANDATORY_LABEL_ACE* pACE = NULL;
            if ((pSACL->AceCount > 0) && (GetAce(pSACL, 0, (PVOID*)&pACE))) {
               if (pACE != NULL) {
                  SID* pSID = (SID*)(&pACE->SidStart);
                  *pResourceIntegrityLevel = pSID->SubAuthority[0];
                  *pResourcePolicy = pACE->Mask;
               }
            }
         }
      }
      
      // Cleanup memory allocated on our behalf
      if (pSD != NULL) LocalFree(pSD); 
   }


   // Don't forget to close the token handle.
   CloseHandle(hToken);

   return(bReturn);   
}
BOOL
LookupUserGroupFromRid(
    LPWSTR TargetComputer,
    DWORD Rid,
    LPWSTR Name,
    PDWORD cchName
    )
{
    PUSER_MODALS_INFO_2 umi2;
    NET_API_STATUS nas;

    UCHAR SubAuthorityCount;
    PSID pSid;
    SID_NAME_USE snu;

    WCHAR DomainName[DNLEN+1];
    DWORD cchDomainName = DNLEN;
    BOOL bSuccess = FALSE; // assume failure

    //
    // get the account domain Sid on the target machine
    // note: if you were looking up multiple sids based on the same
    // account domain, only need to call this once.
    //

    nas = NetUserModalsGet(TargetComputer, 2, (LPBYTE *)&umi2);

    if(nas != NERR_Success) {
        SetLastError(nas);
        return FALSE;
    }

    SubAuthorityCount = *GetSidSubAuthorityCount
                        (umi2->usrmod2_domain_id);

    //
    // allocate storage for new Sid. account domain Sid + account Rid
    //

    pSid = (PSID)HeapAlloc(GetProcessHeap(), 0,
            GetSidLengthRequired((UCHAR)(SubAuthorityCount + 1)));

    if(pSid != NULL) {

        if(InitializeSid(
                pSid,
                GetSidIdentifierAuthority(umi2->usrmod2_domain_id),
                (BYTE)(SubAuthorityCount+1)
                )) {

            DWORD SubAuthIndex = 0;

            //
            // copy existing subauthorities from account domain Sid into
            // new Sid
            //

            for( ; SubAuthIndex < SubAuthorityCount ; SubAuthIndex++) {
                *GetSidSubAuthority(pSid, SubAuthIndex) =
                *GetSidSubAuthority(umi2->usrmod2_domain_id,
                                    SubAuthIndex);
            }

            //
            // append Rid to new Sid
            //

            *GetSidSubAuthority(pSid, SubAuthorityCount) = Rid;

            bSuccess = LookupAccountSidW(
                    TargetComputer,
                    pSid,
                    Name,
                    cchName,
                    DomainName,
                    &cchDomainName,
                    &snu
                    );
        }

        HeapFree(GetProcessHeap(), 0, pSid);
    }

    NetApiBufferFree(umi2);

    return bSuccess;
}
Beispiel #27
0
void RegistryLogAceSidStart(PSID SidStart)
{
	LogIncIndent();

	if (FALSE == IsValidSid(SidStart))
	{
		LOG(L"Invalid Sid given, cannot parse\n");
		LogDecIndent();
		return;
	}
	LPTSTR stringSid = NULL;
	if(FALSE == ConvertSidToStringSid(SidStart,&stringSid))
	{
		LOG(L"Could not convert SID to SIDString\n");
		LogDecIndent();
		return;
	}
	LOG(L"SID = %s\n",stringSid);

	PSID_IDENTIFIER_AUTHORITY sidia = GetSidIdentifierAuthority(SidStart);

	PUCHAR pSubAuthorityCount = GetSidSubAuthorityCount(SidStart);

	UCHAR counter = 0;
	for(; counter < *pSubAuthorityCount ; counter++)
	{
		PDWORD pSidSubAuthority = GetSidSubAuthority(SidStart,counter);
		BYTE nullauthorityValue[6] = SECURITY_NULL_SID_AUTHORITY;
		BYTE worldauthorityValue[6] = SECURITY_WORLD_SID_AUTHORITY;
		BYTE localauthorityValue[6] = SECURITY_LOCAL_SID_AUTHORITY;
		BYTE creatorauthorityValue[6] = SECURITY_CREATOR_SID_AUTHORITY;
		BYTE ntauthorityValue[6] = SECURITY_NT_AUTHORITY;

		if(memcmp(sidia->Value,nullauthorityValue,6) == 0)
		{
			switch(*pSidSubAuthority)
			{
			case SECURITY_NULL_RID:
				LOG(L"SECURITY_NULL\n");
				break;
			default:
				RegistryLogGeneralRIDS(L"SECURITY_NULL_SID_AUTHORITY",*pSidSubAuthority);
				break;
			};
		}
		else if (memcmp(sidia->Value,worldauthorityValue,6) == 0)
		{
			switch(*pSidSubAuthority)
			{
			case SECURITY_WORLD_RID:
				LOG(L"EVERYONE\n");
				break;	
			default:
				RegistryLogGeneralRIDS(L"SECURITY_WORLD_SID_AUTHORITY",*pSidSubAuthority);
				break;
			};
		}
		else if (memcmp(sidia->Value,localauthorityValue,6) == 0)
		{
			switch(*pSidSubAuthority)
			{	
			case SECURITY_LOCAL_RID:
				LOG(L"SECURITY_LOCAL_SID_AUTHORITY SECURITY_LOCAL_RID\n");
				break;
			case SECURITY_LOCAL_LOGON_RID:
				LOG(L"SECURITY_LOCAL_SID_AUTHORITY SECURITY_LOCAL_LOGON_RID\n");
				break;		
			default:
				RegistryLogGeneralRIDS(L"SECURITY_LOCAL_SID_AUTHORITY",*pSidSubAuthority);
				break;
			};
		}
		else if (memcmp(sidia->Value,creatorauthorityValue,6) == 0)
		{
			switch(*pSidSubAuthority)
			{	
			case SECURITY_CREATOR_OWNER_RID:
				LOG(L"CREATOR_OWNER\n");
				//LOG(L"SECURITY_CREATOR_SID_AUTHORITY SECURITY_CREATOR_OWNER_RID\n");
				break;
			case SECURITY_CREATOR_GROUP_RID:
				LOG(L"CREATOR_GROUP\n");
				//LOG(L"SECURITY_CREATOR_SID_AUTHORITY SECURITY_CREATOR_GROUP_RID\n");
				break;		
			default:
				RegistryLogGeneralRIDS(L"SECURITY_CREATOR_SID_AUTHORITY",*pSidSubAuthority);
				break;
			};
		}
		else if (memcmp(sidia->Value,ntauthorityValue,6) == 0)
		{
			switch(*pSidSubAuthority)
			{	
			case SECURITY_DIALUP_RID:
				LOG(L"DIALUP\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_DIALUP_RID: Users who log on to terminals using a dial-up modem. This is a group identifier\n");
				break;
			case SECURITY_NETWORK_RID:
				LOG(L"NETWORK\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_NETWORK_RID: Users who log on across a network. This is a group identifier\n");
				break;		
			case SECURITY_BATCH_RID:
				LOG(L"BATCH\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_BATCH_RID: Users who log on using a batch queue facility. This is a group identifier\n");
				break;
			case SECURITY_INTERACTIVE_RID:
				LOG(L"INTERACTIVE\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_INTERACTIVE_RID: Users who log on for interactive operation. This is a group identifier\n");
				break;	
			case SECURITY_LOGON_IDS_RID:
				LOG(L"LOGON_IDS\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_LOGON_IDS_RID: A logon session\n");
				break;
			case SECURITY_SERVICE_RID:
				LOG(L"SERVICE\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_SERVICE_RID: Accounts authorized to log on as a service. This is a group identifier\n");
				break;		
			case SECURITY_ANONYMOUS_LOGON_RID:
				LOG(L"ANONYMOUS\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_ANONYMOUS_LOGON_RID: Anonymous logon, or null session logon\n");
				break;
			case SECURITY_PROXY_RID:
				LOG(L"PROXY\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_PROXY_RID: Proxy\n");
				break;	
			case SECURITY_ENTERPRISE_CONTROLLERS_RID:
				LOG(L"ENTERPRISE_CONTROLLERS\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_ENTERPRISE_CONTROLLERS_RID: Enterprise controllers\n");
				break;
			case SECURITY_PRINCIPAL_SELF_RID:
				LOG(L"PRINCIPAL_SELF\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_PRINCIPAL_SELF_RID: The PRINCIPAL_SELF security identifier\n");
				break;		
			case SECURITY_AUTHENTICATED_USER_RID:
				LOG(L"AUTHENTICATED_USER\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_AUTHENTICATED_USER_RID: The authenticated users\n");
				break;
			case SECURITY_RESTRICTED_CODE_RID:
				LOG(L"RESTRICTED_CODE\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_RESTRICTED_CODE_RID: Restricted code\n");
				break;	
			case SECURITY_TERMINAL_SERVER_RID:
				LOG(L"TERMINAL_SERVER\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_TERMINAL_SERVER_RID: Terminal Services\n");
				break;
			case SECURITY_LOCAL_SYSTEM_RID:
				LOG(L"LOCAL_SYSTEM\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_LOCAL_SYSTEM_RID: A special account used by the operating system\n");
				break;		
			case SECURITY_NT_NON_UNIQUE:
				LOG(L"NT_NON_UNIQUE\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_NT_NON_UNIQUE: SIDS are not unique\n");
				break;
			case SECURITY_BUILTIN_DOMAIN_RID:
				LOG(L"BUILTIN_DOMAIN\n");
				//LOG(L"SECURITY_NT_AUTHORITY SECURITY_BUILTIN_DOMAIN_RID: Buildin Domain\n");
				break;	
			default:
				RegistryLogGeneralRIDS(L"SECURITY_NT_AUTHORITY",*pSidSubAuthority);
				break;
			};
		}
	}
	LogDecIndent();
}
Beispiel #28
0
void
initialize (void)
{

    ULONG SidWithZeroSubAuthorities;
    ULONG SidWithOneSubAuthority;
    ULONG SidWithThreeSubAuthorities;
    ULONG SidWithFourSubAuthorities;

    SID_IDENTIFIER_AUTHORITY NullSidAuthority    = SECURITY_NULL_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY WorldSidAuthority   = SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY LocalSidAuthority   = SECURITY_LOCAL_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY CreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;

    SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;


    //
    //  The following SID sizes need to be allocated
    //

    SidWithZeroSubAuthorities  = GetSidLengthRequired( 0 );
    SidWithOneSubAuthority     = GetSidLengthRequired( 1 );
    SidWithThreeSubAuthorities = GetSidLengthRequired( 3 );
    SidWithFourSubAuthorities  = GetSidLengthRequired( 4 );

    //
    //  Allocate and initialize the universal SIDs
    //

    NullSid         = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);
    WorldSid        = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);
    LocalSid        = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);
    CreatorOwnerSid = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);

    InitializeSid( NullSid,    &NullSidAuthority, 1 );
    InitializeSid( WorldSid,   &WorldSidAuthority, 1 );
    InitializeSid( LocalSid,   &LocalSidAuthority, 1 );
    InitializeSid( CreatorOwnerSid, &CreatorSidAuthority, 1 );

    *(GetSidSubAuthority( NullSid, 0 ))         = SECURITY_NULL_RID;
    *(GetSidSubAuthority( WorldSid, 0 ))        = SECURITY_WORLD_RID;
    *(GetSidSubAuthority( LocalSid, 0 ))        = SECURITY_LOCAL_RID;
    *(GetSidSubAuthority( CreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;

    //
    // Allocate and initialize the NT defined SIDs
    //

    NtAuthoritySid  = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithZeroSubAuthorities);
    DialupSid       = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);
    NetworkSid      = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);
    BatchSid        = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);
    InteractiveSid  = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);
    LocalSystemSid  = (PSID)RtlAllocateHeap( RtlProcessHeap(), 0,SidWithOneSubAuthority);

    InitializeSid( NtAuthoritySid,   &NtAuthority, 0 );
    InitializeSid( DialupSid,        &NtAuthority, 1 );
    InitializeSid( NetworkSid,       &NtAuthority, 1 );
    InitializeSid( BatchSid,         &NtAuthority, 1 );
    InitializeSid( InteractiveSid,   &NtAuthority, 1 );
    InitializeSid( LocalSystemSid,   &NtAuthority, 1 );

    *(GetSidSubAuthority( DialupSid,       0 )) = SECURITY_DIALUP_RID;
    *(GetSidSubAuthority( NetworkSid,      0 )) = SECURITY_NETWORK_RID;
    *(GetSidSubAuthority( BatchSid,        0 )) = SECURITY_BATCH_RID;
    *(GetSidSubAuthority( InteractiveSid,  0 )) = SECURITY_INTERACTIVE_RID;
    *(GetSidSubAuthority( LocalSystemSid,  0 )) = SECURITY_LOCAL_SYSTEM_RID;


    //
    // Initialize the well known privilege values
    //

    SeCreateTokenPrivilege =
        RtlConvertLongToLargeInteger(SE_CREATE_TOKEN_PRIVILEGE);
    SeAssignPrimaryTokenPrivilege =
        RtlConvertLongToLargeInteger(SE_ASSIGNPRIMARYTOKEN_PRIVILEGE);
    SeLockMemoryPrivilege =
        RtlConvertLongToLargeInteger(SE_LOCK_MEMORY_PRIVILEGE);
    SeIncreaseQuotaPrivilege =
        RtlConvertLongToLargeInteger(SE_INCREASE_QUOTA_PRIVILEGE);
    SeUnsolicitedInputPrivilege =
        RtlConvertLongToLargeInteger(SE_UNSOLICITED_INPUT_PRIVILEGE);
    SeTcbPrivilege =
        RtlConvertLongToLargeInteger(SE_TCB_PRIVILEGE);
    SeSecurityPrivilege =
        RtlConvertLongToLargeInteger(SE_SECURITY_PRIVILEGE);
    SeTakeOwnershipPrivilege =
        RtlConvertLongToLargeInteger(SE_TAKE_OWNERSHIP_PRIVILEGE);
    SeLoadDriverPrivilege =
        RtlConvertLongToLargeInteger(SE_LOAD_DRIVER_PRIVILEGE);
    SeCreatePagefilePrivilege =
        RtlConvertLongToLargeInteger(SE_CREATE_PAGEFILE_PRIVILEGE);
    SeIncreaseBasePriorityPrivilege =
        RtlConvertLongToLargeInteger(SE_INC_BASE_PRIORITY_PRIVILEGE);
    SeSystemProfilePrivilege =
        RtlConvertLongToLargeInteger(SE_SYSTEM_PROFILE_PRIVILEGE);
    SeSystemtimePrivilege =
        RtlConvertLongToLargeInteger(SE_SYSTEMTIME_PRIVILEGE);
    SeProfileSingleProcessPrivilege =
        RtlConvertLongToLargeInteger(SE_PROF_SINGLE_PROCESS_PRIVILEGE);
    SeCreatePermanentPrivilege =
        RtlConvertLongToLargeInteger(SE_CREATE_PERMANENT_PRIVILEGE);
    SeBackupPrivilege =
        RtlConvertLongToLargeInteger(SE_BACKUP_PRIVILEGE);
    SeRestorePrivilege =
        RtlConvertLongToLargeInteger(SE_RESTORE_PRIVILEGE);
    SeShutdownPrivilege =
        RtlConvertLongToLargeInteger(SE_SHUTDOWN_PRIVILEGE);
    SeDebugPrivilege =
        RtlConvertLongToLargeInteger(SE_DEBUG_PRIVILEGE);
    SeAuditPrivilege =
        RtlConvertLongToLargeInteger(SE_AUDIT_PRIVILEGE);
    SeSystemEnvironmentPrivilege =
        RtlConvertLongToLargeInteger(SE_SYSTEM_ENVIRONMENT_PRIVILEGE);
    SeChangeNotifyPrivilege =
        RtlConvertLongToLargeInteger(SE_CHANGE_NOTIFY_PRIVILEGE);
    SeRemoteShutdownPrivilege =
        RtlConvertLongToLargeInteger(SE_REMOTE_SHUTDOWN_PRIVILEGE);


}
Beispiel #29
0
//
//   函数: GetProcessIntegrityLevel()
//
//   用途:此函数获取当前线程的完整性级别。完整性级别只有在Windows Vista及后
//   续版本的Windows中有效。所以在Windows Vista之前的版本中执行GetProcessIntegrityLevel, 
//   它会抛出一个C++异常。
//
//   返回值:返回当前进程的完整性级别。它可能是以下某一个值。
//
//     SECURITY_MANDATORY_UNTRUSTED_RID (SID: S-1-16-0x0)
//     表示不被信任的级别。它被用于一个匿名组成员起动的进程。这时大多数
//     写入操作被禁止。
//
//     SECURITY_MANDATORY_LOW_RID (SID: S-1-16-0x1000)
//     表示低完整性级别。它被用于保护模式下的IE浏览器。这时大多数系统中对
//     象(包括文件及注册表键值)的写入操作被禁止。
//
//     SECURITY_MANDATORY_MEDIUM_RID (SID: S-1-16-0x2000)
//     表示中完整性级别。它被用于在UAC开启时启动普通应用程序。
//
//
//     SECURITY_MANDATORY_HIGH_RID (SID: S-1-16-0x3000)
//     表示高完整性级别。它被用于用户通过UAC提升权限启动一个管理员应用程序。
//     或则当UAC关闭时,管理员用户启动一个普通程序。
//
//
//     SECURITY_MANDATORY_SYSTEM_RID (SID: S-1-16-0x4000)
//     表示系统完整性级别。它被用于服务或则其他系统级别的应用程序(比如
//     Wininit, Winlogon, Smss,等等)
//
//
//   异常:如果此函数出错,它抛出一个包含Win32相关错误代码的C++ DWORD异常。
//   比如在Windows Vista之前的Windows中调用GetProcessIntegrityLevel,被抛
//   出的错误代码为ERROR_INVALID_PARAMETER。
// 
//   调用示例:
//     try 
//     {
//         DWORD dwIntegrityLevel = GetProcessIntegrityLevel();
//     }
//     catch (DWORD dwError)
//     {
//         wprintf(L"GetProcessIntegrityLevel 失败 w/err %lu\n", dwError);
//     }
//
DWORD GetProcessIntegrityLevel()
{
    DWORD dwIntegrityLevel = 0;
    DWORD dwError = ERROR_SUCCESS;
    HANDLE hToken = NULL;
    DWORD cbTokenIL = 0;
    PTOKEN_MANDATORY_LABEL pTokenIL = NULL;

    // 使用TOKEN_QUERY打开线程的主访问令牌。
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // 查询令牌完整性级别信息的大小。注意:我们预期得到一个FALSE结果及错误
    // ERROR_INSUFFICIENT_BUFFER, 这是由于我们在GetTokenInformation输入一个
    // 空缓冲。同时,在cbTokenIL中我们会得知完整性级别信息的大小。
    if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &cbTokenIL))
    {
        if (ERROR_INSUFFICIENT_BUFFER != GetLastError())
        {
            // 当进程运行于Windows Vista之前的系统中,GetTokenInformation返回
            // FALSE和错误码ERROR_INVALID_PARAMETER。这是由于这些操作系统不支
            // 持TokenElevation。
            dwError = GetLastError();
            goto Cleanup;
        }
    }

    // 现在我们为完整性级别信息分配一个缓存。
    pTokenIL = (TOKEN_MANDATORY_LABEL *)LocalAlloc(LPTR, cbTokenIL);
    if (pTokenIL == NULL)
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // 获得令牌完整性级别信息。
    if (!GetTokenInformation(hToken, TokenIntegrityLevel, pTokenIL, 
        cbTokenIL, &cbTokenIL))
    {
        dwError = GetLastError();
        goto Cleanup;
    }

    // 完整性级别SID为S-1-16-0xXXXX形式。(例如:S-1-16-0x1000表示为低完整性
    // 级别的SID)。而且有且仅有一个次级授权信息。
    dwIntegrityLevel = *GetSidSubAuthority(pTokenIL->Label.Sid, 0);

Cleanup:
    // 集中清理所有已分配的内存资源

    if (hToken)
    {
        CloseHandle(hToken);
        hToken = NULL;
    }
    if (pTokenIL)
    {
        LocalFree(pTokenIL);
        pTokenIL = NULL;
        cbTokenIL = 0;
    }

    // 一旦有任何异常发生,抛出错误。
    if (ERROR_SUCCESS != dwError)
    {
        throw dwError;
    }

    return dwIntegrityLevel;
}
Beispiel #30
-1
static int
TestplatformChmod(
    const char *nativePath,
    int pmode)
{
    static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION
	    | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
    static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE
	    | FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA
	    | FILE_WRITE_DATA | DELETE;

    /*
     * References to security functions (only available on NT and later).
     */

    const BOOL set_readOnly = !(pmode & 0222);
    BOOL acl_readOnly_found = FALSE, curAclPresent, curAclDefaulted;
    SID_IDENTIFIER_AUTHORITY userSidAuthority = {
	SECURITY_WORLD_SID_AUTHORITY
    };
    BYTE *secDesc = 0;
    DWORD secDescLen, attr, newAclSize;
    ACL_SIZE_INFORMATION ACLSize;
    PACL curAcl, newAcl = 0;
    WORD j;
    SID *userSid = 0;
    char *userDomain = 0;
    int res = 0;

    /*
     * Process the chmod request.
     */

    attr = GetFileAttributesA(nativePath);

    /*
     * nativePath not found
     */

    if (attr == 0xffffffff) {
	res = -1;
	goto done;
    }

    /*
     * If nativePath is not a directory, there is no special handling.
     */

    if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
	goto done;
    }

    /*
     * Set the result to error, if the ACL change is successful it will be
     * reset to 0.
     */

    res = -1;

    /*
     * Read the security descriptor for the directory. Note the first call
     * obtains the size of the security descriptor.
     */

    if (!GetFileSecurityA(nativePath, infoBits, NULL, 0, &secDescLen)) {
	DWORD secDescLen2 = 0;

	if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
	    goto done;
	}

	secDesc = (BYTE *) ckalloc(secDescLen);
	if (!GetFileSecurityA(nativePath, infoBits,
		(PSECURITY_DESCRIPTOR) secDesc, secDescLen, &secDescLen2)
		|| (secDescLen < secDescLen2)) {
	    goto done;
	}
    }

    /*
     * Get the World SID.
     */

    userSid = (SID *) ckalloc(GetSidLengthRequired((UCHAR) 1));
    InitializeSid(userSid, &userSidAuthority, (BYTE) 1);
    *(GetSidSubAuthority(userSid, 0)) = SECURITY_WORLD_RID;

    /*
     * If curAclPresent == false then curAcl and curAclDefaulted not valid.
     */

    if (!GetSecurityDescriptorDacl((PSECURITY_DESCRIPTOR) secDesc,
	    &curAclPresent, &curAcl, &curAclDefaulted)) {
	goto done;
    }
    if (!curAclPresent || !curAcl) {
	ACLSize.AclBytesInUse = 0;
	ACLSize.AceCount = 0;
    } else if (!GetAclInformation(curAcl, &ACLSize, sizeof(ACLSize),
	    AclSizeInformation)) {
	goto done;
    }

    /*
     * Allocate memory for the new ACL.
     */

    newAclSize = ACLSize.AclBytesInUse + sizeof(ACCESS_DENIED_ACE)
	    + GetLengthSid(userSid) - sizeof(DWORD);
    newAcl = (ACL *) ckalloc(newAclSize);

    /*
     * Initialize the new ACL.
     */

    if (!InitializeAcl(newAcl, newAclSize, ACL_REVISION)) {
	goto done;
    }

    /*
     * Add denied to make readonly, this will be known as a "read-only tag".
     */

    if (set_readOnly && !AddAccessDeniedAce(newAcl, ACL_REVISION,
	    readOnlyMask, userSid)) {
	goto done;
    }

    acl_readOnly_found = FALSE;
    for (j = 0; j < ACLSize.AceCount; j++) {
	LPVOID pACE2;
	ACE_HEADER *phACE2;

	if (!GetAce(curAcl, j, &pACE2)) {
	    goto done;
	}

	phACE2 = (ACE_HEADER *) pACE2;

	/*
	 * Do NOT propagate inherited ACEs.
	 */

	if (phACE2->AceFlags & INHERITED_ACE) {
	    continue;
	}

	/*
	 * Skip the "read-only tag" restriction (either added above, or it is
	 * being removed).
	 */

	if (phACE2->AceType == ACCESS_DENIED_ACE_TYPE) {
	    ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *) phACE2;

	    if (pACEd->Mask == readOnlyMask
		    && EqualSid(userSid, (PSID) &pACEd->SidStart)) {
		acl_readOnly_found = TRUE;
		continue;
	    }
	}

	/*
	 * Copy the current ACE from the old to the new ACL.
	 */

	if (!AddAce(newAcl, ACL_REVISION, MAXDWORD, (PACL *) pACE2,
		((PACE_HEADER) pACE2)->AceSize)) {
	    goto done;
	}
    }

    /*
     * Apply the new ACL.
     */

    if (set_readOnly == acl_readOnly_found || SetNamedSecurityInfoA(
	    (LPSTR) nativePath, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
	    NULL, NULL, newAcl, NULL) == ERROR_SUCCESS) {
	res = 0;
    }

  done:
    if (secDesc) {
	ckfree((char *) secDesc);
    }
    if (newAcl) {
	ckfree((char *) newAcl);
    }
    if (userSid) {
	ckfree((char *) userSid);
    }
    if (userDomain) {
	ckfree((char *) userDomain);
    }

    if (res != 0) {
	return res;
    }

    /*
     * Run normal chmod command.
     */

    return chmod(nativePath, pmode);
}