Пример #1
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;
}
Пример #2
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));
    }
} 
Пример #3
0
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;
}
Пример #4
0
BOOL make_relative_sid(PSID* answer, PSID base, ULONG relative_id)
{
  int     count;
  int     i;

  if (answer == NULL)
    return print_error(L"Error in make_relative_sid: answer is NULL.\n");

  if (base == NULL)
    return print_error(L"Error in make_relative_sid: base is NULL.\n");

  if (!IsValidSid(base))
    return print_error(L"Error in make_relative_sid: base is not a valid SID.\n");

  count = *GetSidSubAuthorityCount(base);
  if (count > 7)
    return print_error(L"Error in make_relative_sid: base has too many sub-authorities.\n");

  if (!AllocateAndInitializeSid( GetSidIdentifierAuthority(base)
                               , 1 + count
                               , 0, 0, 0, 0, 0, 0, 0, 0, answer))
    return win_error(GetLastError(), L"AllocateAndInitializeSid");

  for(i=0; i<count; i++)
  {
    *GetSidSubAuthority(*answer, i) = *GetSidSubAuthority(base, i);
  }

  *GetSidSubAuthority(*answer, count) = relative_id;

  return TRUE;
}
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);
}
Пример #6
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;
	}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
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));
      }
}
Пример #11
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;
}
Пример #12
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;
}
Пример #13
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;
      }
    }
Пример #14
0
//
// Function	: sidToText
// Role		: Converts a binary SID to a nice one
// Notes	: http://win32.mvps.org/security/dumpacl/dumpacl.cpp
//
const char *sidToTextTok( PSID psid )
{
	// S-rev- + SIA + subauthlen*maxsubauth + terminator
	static char buf[15 + 12 + 12*SID_MAX_SUB_AUTHORITIES + 1];
	char *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 += _snprintf_s( p, 15 + 12 + 12*SID_MAX_SUB_AUTHORITIES + 1, &buf[sizeof buf] - p, "S-%lu-", 0x0f & *( (byte *) psid ) );

	if ( ( psia->Value[0] != 0 ) || ( psia->Value[1] != 0 ) )
		p += _snprintf_s( p,15 + 12 + 12*SID_MAX_SUB_AUTHORITIES + 1, &buf[sizeof buf] - 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] );
	else
		p += _snprintf_s( p, 15 + 12 + 12*SID_MAX_SUB_AUTHORITIES + 1, &buf[sizeof buf] - p, "%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 += _snprintf_s( p, 15 + 12 + 12*SID_MAX_SUB_AUTHORITIES + 1,&buf[sizeof buf] - p, "-%lu", *GetSidSubAuthority( psid, i ) );

	return buf;
}
Пример #15
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;
}
Пример #16
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;
}
Пример #17
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) );
    }
}
Пример #18
0
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);   
}
Пример #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;
}
Пример #20
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);   
}
Пример #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);
}
Пример #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;
}
Пример #23
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();
}
Пример #24
0
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;
}
Пример #25
0
void vsyslog(int pri, const char *fmt, va_list ap)
/* 
 * Purpose:
 *		Does the actual logging to the NT event log.
 *		This is actually never called directly by the user
 *		but always through syslog()
 *
 * Precondition: 
 *		dto. syslog()
 *
 * Postcondition:
 *		dto. syslog()
 *
 * Mods:
 *		05/11/97	(CVP)
 */
{

	char *aszMsg[1], *p;
	WORD nt_prio = 0;
	
	BYTE sidBuffer[SLG_BUFSIZE];
	PSID psid = (PSID) &sidBuffer;
	PSID PNtSid_ = NULL;
	DWORD sidBufferSize = SLG_BUFSIZE * sizeof(BYTE);
	TCHAR domainBuffer[SLG_BUFSIZE];
	DWORD domainBufferSize = SLG_BUFSIZE * sizeof(TCHAR);
	SID_NAME_USE snu;
	UCHAR SubAuthorityCount = 0;
	BOOL retBOOL = TRUE;
	DWORD SubAuthIndex = 0;

	int saved_errno = 0;
	int nt_pid = _getpid();
	char tbuf[SLG_BUFSIZE];
	char fmt_cpy[SLG_BUFSIZE];
	DWORD bufsize = SLG_BUFSIZE;
	BOOL resBOOL = 0;
	char ch, *t1, *t2;
	DWORD retDWORD = 0;

	saved_errno = errno;
	
	/* 
	 * Username retrieval 
	 */
	if (*username == 0) {
		retBOOL = GetUserName(username, &bufsize); 
		if (retBOOL == 0) {
			SLG_DEBUG(fprintf(SLG_DEBUG_OUT, SLG01, GetLastError()));
			SLG_PANIC();
		}
	}

	ZeroMemory(sidBuffer, SLG_BUFSIZE);
	LookupAccountName(
			NULL, 
			username, 
			sidBuffer,
			&sidBufferSize,
			domainBuffer, 
			&domainBufferSize,
			&snu);

	SubAuthorityCount = *GetSidSubAuthorityCount(psid);

	retBOOL = AllocateAndInitializeSid (
		GetSidIdentifierAuthority(psid),
		SubAuthorityCount,
		0,0,0,0,0,0,0,0,
		&PNtSid_
		);
			
	if (retBOOL != 0) {
		for( ; SubAuthIndex < SubAuthorityCount ; SubAuthIndex++) {
                *GetSidSubAuthority(PNtSid_, SubAuthIndex) =
                *GetSidSubAuthority(psid, SubAuthIndex);
		}
	}
/*
 * in case of error, PNtSid_ will remain NULL, 
 * which is OK anyway
 */

	(void)sprintf(tbuf, "[pid %d / user %s]  ", nt_pid, username);
	for (p = tbuf; *p; ++p);

/*
 * build the message
 * substitute error message for %m 
 */

	for (t1 = fmt_cpy; ch = *fmt; ++fmt) {
		if (ch == '%' && fmt[1] == 'm') {
			++fmt;
			for (t2 = strerror(saved_errno); *t1 = *t2++; ++t1);
		}
		else
			*t1++ = ch;
	}
	*t1 = '\0';

	vsprintf(p, fmt_cpy, ap);
	aszMsg[0] = tbuf;

/*
 * consider the event types:
 *		EVENTLOG_ERROR_TYPE 
 *		EVENTLOG_WARNING_TYPE 
 *		EVENTLOG_INFORMATION_TYPE
 *
 */

	switch(pri) {
	case LOG_EMERG:												/* system is unusable */
	case LOG_ALERT:												/* action must be taken immediately */
	case LOG_CRIT:												/* critical conditions */
	case LOG_ERR:													/* error conditions */
		nt_prio = EVENTLOG_ERROR_TYPE;
		break;
	case LOG_WARNING:											/* warning conditions */
	case LOG_NOTICE:											/* normal but significant condition */
		nt_prio = EVENTLOG_WARNING_TYPE;
		break;
	case LOG_INFO:												/* informational */
	case LOG_DEBUG:												/* debug-level messages */
		nt_prio = EVENTLOG_INFORMATION_TYPE;
		break;
	}

 
	if (!ReportEvent(
				h,										/* event log handle            */ 
        nt_prio,							/* event type                  */ 
        SLG_ONE,							/* category identifier         */ 
        SLG_01,								/* event identifier            */ 
        PNtSid_,							/* user security identifier    */ 
        1,                    /* one substitution string     */ 
        0,                    /* no data                     */ 
        (LPTSTR *) aszMsg,    /* address of string array     */ 
        NULL)                 /* address of data             */ 
	) {
			SLG_DEBUG(fprintf(SLG_DEBUG_OUT, SLG02));
			SLG_PANIC(); 
	}
}