Example #1
0
BOOL
AddAceToWindowStation(
    IN HWINSTA WinSta,
    IN PSID Sid)
{
    DWORD AclSize;
    SECURITY_INFORMATION SecurityInformation;
    PACL pDefaultAcl = NULL;
    PSECURITY_DESCRIPTOR WinstaSd = NULL;
    PACCESS_ALLOWED_ACE Ace = NULL;
    BOOL Ret = FALSE;

    /* Allocate space for an ACL */
    AclSize = sizeof(ACL)
        + 2 * (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(Sid));
    pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize);
    if (!pDefaultAcl)
    {
        ERR("WL: HeapAlloc() failed\n");
        goto cleanup;
    }

    /* Initialize it */
    if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION))
    {
        ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Initialize new security descriptor */
    WinstaSd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (!InitializeSecurityDescriptor(WinstaSd, SECURITY_DESCRIPTOR_REVISION))
    {
        ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Allocate memory for access allowed ACE */
    Ace = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ACCESS_ALLOWED_ACE)+
        GetLengthSid(Sid) - sizeof(DWORD));

    /* Create the first ACE for the window station */
    Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
    Ace->Header.AceFlags = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
    Ace->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(Sid) - sizeof(DWORD);
    Ace->Mask = GENERIC_ACCESS;

    /* Copy the sid */
    if (!CopySid(GetLengthSid(Sid), &Ace->SidStart, Sid))
    {
        ERR("WL: CopySid() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add the first ACE */
    if (!AddAce(pDefaultAcl, ACL_REVISION, MAXDWORD, (LPVOID)Ace, Ace->Header.AceSize))
    {
        ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add the second ACE to the end of ACL */
    Ace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
    Ace->Mask = WINSTA_ALL;
    if (!AddAce(pDefaultAcl, ACL_REVISION, MAXDWORD, (LPVOID)Ace, Ace->Header.AceSize))
    {
        ERR("WL: AddAce() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add ACL to winsta's security descriptor */
    if (!SetSecurityDescriptorDacl(WinstaSd, TRUE, pDefaultAcl, FALSE))
    {
        ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Apply security to the window station */
    SecurityInformation = DACL_SECURITY_INFORMATION;
    if (!SetUserObjectSecurity(WinSta, &SecurityInformation, WinstaSd))
    {
        ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Indicate success */
    Ret = TRUE;

cleanup:
    /* Free allocated stuff */
    if (pDefaultAcl) HeapFree(GetProcessHeap(), 0, pDefaultAcl);
    if (WinstaSd) HeapFree(GetProcessHeap(), 0, WinstaSd);
    if (Ace) HeapFree(GetProcessHeap(), 0, Ace);

    return Ret;
}
//Code taken from http://stackoverflow.com/questions/1453497/discover-if-user-has-admin-rights   Have not checked if it is valid yet.... TODO!!!
bool RemoteDesktop::IsUserAdmin(){

	struct Data
	{
		PACL   pACL;
		PSID   psidAdmin;
		HANDLE hToken;
		HANDLE hImpersonationToken;
		PSECURITY_DESCRIPTOR     psdAdmin;
		Data() : pACL(NULL), psidAdmin(NULL), hToken(NULL),
			hImpersonationToken(NULL), psdAdmin(NULL)
		{}
		~Data()
		{
			if (pACL)
				LocalFree(pACL);
			if (psdAdmin)
				LocalFree(psdAdmin);
			if (psidAdmin)
				FreeSid(psidAdmin);
			if (hImpersonationToken)
				CloseHandle(hImpersonationToken);
			if (hToken)
				CloseHandle(hToken);
		}
	} data;

	BOOL   fReturn = FALSE;


	DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);

	PRIVILEGE_SET   ps;
	GENERIC_MAPPING GenericMapping;
	SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;

	const DWORD ACCESS_READ = 1;
	const DWORD ACCESS_WRITE = 2;

	if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE | TOKEN_QUERY, TRUE, &data.hToken))
	{
		if (GetLastError() != ERROR_NO_TOKEN)
			return false;

		if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &data.hToken))
			return false;
	}

	if (!DuplicateToken(data.hToken, SecurityImpersonation, &data.hImpersonationToken))
		return false;

	if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
		SECURITY_BUILTIN_DOMAIN_RID,
		DOMAIN_ALIAS_RID_ADMINS,
		0, 0, 0, 0, 0, 0, &data.psidAdmin))
		return false;

	data.psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
	if (data.psdAdmin == NULL)
		return false;

	if (!InitializeSecurityDescriptor(data.psdAdmin, SECURITY_DESCRIPTOR_REVISION))
		return false;

	// Compute size needed for the ACL.
	auto dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(data.psidAdmin) - sizeof(DWORD);

	data.pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
	if (data.pACL == NULL)
		return false;

	if (!InitializeAcl(data.pACL, dwACLSize, ACL_REVISION2))
		return false;

	DWORD dwAccessMask = ACCESS_READ | ACCESS_WRITE;

	if (!AddAccessAllowedAce(data.pACL, ACL_REVISION2, dwAccessMask, data.psidAdmin))
		return false;

	if (!SetSecurityDescriptorDacl(data.psdAdmin, TRUE, data.pACL, FALSE))
		return false;

	// AccessCheck validates a security descriptor somewhat; set the group
	// and owner so that enough of the security descriptor is filled out 
	// to make AccessCheck happy.

	SetSecurityDescriptorGroup(data.psdAdmin, data.psidAdmin, FALSE);
	SetSecurityDescriptorOwner(data.psdAdmin, data.psidAdmin, FALSE);

	if (!IsValidSecurityDescriptor(data.psdAdmin))
		return false;

	DWORD dwAccessDesired = ACCESS_READ;

	GenericMapping.GenericRead = ACCESS_READ;
	GenericMapping.GenericWrite = ACCESS_WRITE;
	GenericMapping.GenericExecute = 0;
	GenericMapping.GenericAll = ACCESS_READ | ACCESS_WRITE;

	DWORD  dwStatus = 0;
	if (!AccessCheck(data.psdAdmin, data.hImpersonationToken, dwAccessDesired,
		&GenericMapping, &ps, &dwStructureSize, &dwStatus,
		&fReturn))
	{
		return false;
	}

	return fReturn == TRUE;
}
Example #3
0
BOOL
AddAceToDesktop(
    IN HDESK Desktop,
    IN PSID WinlogonSid,
    IN PSID UserSid)
{
    DWORD AclSize;
    SECURITY_INFORMATION SecurityInformation;
    PACL Acl = NULL;
    PSECURITY_DESCRIPTOR DesktopSd = NULL;
    BOOL Ret = FALSE;

    /* Allocate ACL */
    AclSize = sizeof(ACL)
        + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(WinlogonSid);

    /* Take user's sid into account */
    if (UserSid)
        AclSize += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(UserSid);

    Acl = HeapAlloc(GetProcessHeap(), 0, AclSize);
    if (!Acl)
    {
        ERR("WL: HeapAlloc() failed\n");
        goto cleanup;
    }

    /* Initialize ACL */
    if (!InitializeAcl(Acl, AclSize, ACL_REVISION))
    {
        ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add full desktop access ACE for winlogon */
    if (!AddAccessAllowedAce(Acl, ACL_REVISION, DESKTOP_ALL, WinlogonSid))
    {
        ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add full desktop access ACE for a user (if provided) */
    if (UserSid && !AddAccessAllowedAce(Acl, ACL_REVISION, DESKTOP_ALL, UserSid))
    {
        ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Initialize new security descriptor */
    DesktopSd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (!InitializeSecurityDescriptor(DesktopSd, SECURITY_DESCRIPTOR_REVISION))
    {
        ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Add ACL to the security descriptor */
    if (!SetSecurityDescriptorDacl(DesktopSd, TRUE, Acl, FALSE))
    {
        ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Apply security to the window station */
    SecurityInformation = DACL_SECURITY_INFORMATION;
    if (!SetUserObjectSecurity(Desktop, &SecurityInformation, DesktopSd))
    {
        ERR("WL: SetUserObjectSecurity() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /* Indicate success */
    Ret = TRUE;

cleanup:
    /* Free allocated stuff */
    if (Acl) HeapFree(GetProcessHeap(), 0, Acl);
    if (DesktopSd) HeapFree(GetProcessHeap(), 0, DesktopSd);

    return Ret;
}
Example #4
0
static ACL *
create_secure_dacl(char *user, ACCESS_MASK mask, SID *owner_sid)
{

	DWORD rids[1] = {0};
	gid_t grp[_MAX_GROUPS] = {0};
	int i = 0;
	int k = 0;
	int cbAcl = 0;
	ACL *ndacl = NULL;
	char logb[LOG_BUF_SIZE] = {'\0' };

	rids[0] = DOMAIN_ALIAS_RID_ADMINS;
	k = getgids(getlogin(), grp, rids);

	if ((k < _MAX_GROUPS) && (owner_sid != NULL)) {
		grp[k] = sid_dup(owner_sid);
		if (grp[k] == NULL) {
			sprintf(logb, "failed to copy owner_sid");
			log_err(-1, __func__, logb);
			return NULL;
		}
		k++;
	}

	if (user != NULL && mask != 0) {
		SID *sid = getgrpsid(user);
		if (sid == NULL)
			sid = getusersid(user);
		if (sid) {
			if (k == _MAX_GROUPS) {
				grp[k-1] = sid;
			} else {
				grp[k] = sid;
				k++;
			}
		}

	}

	cbAcl = sizeof(ACL);
	for (i = 0 ; i < k; i++) {
		// subtract ACE.SidStart from the size
		int cbAce = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD);
		// add this ACE's SID length
		cbAce += GetLengthSid(grp[i]);
		// add the length of each ACE to the total ACL length
		cbAcl += cbAce;
	}

	ndacl = (ACL *)malloc(cbAcl);
	if (ndacl == NULL) {
		sprintf(logb, "failed to malloc %d bytes", cbAcl);
		log_err(-1, __func__, logb);
		return NULL;
	}
	InitializeAcl(ndacl, cbAcl, ACL_REVISION);

	for (i=0; i < k; i++) {
		char *name = getgrpname_full(grp[i]);

		if (name == NULL)
			name = getusername(grp[i]);

		if (name == NULL)
			continue;

		if (user != NULL && mask != 0 && i == (k-1)) {
			if (AddAccessAllowedAce(ndacl, ACL_REVISION, mask | 0x00100000, grp[i]) == 0) {
				sprintf(logb, "failed to add %d to %s", mask,
					name);
				log_err(-1, __func__, logb);
			}

		} else {
			if (AddAccessAllowedAce(ndacl, ACL_REVISION,
				READS_MASK | WRITES_MASK | STANDARD_RIGHTS_ALL, grp[i]) == 0) {
				sprintf(logb, "failed to add WRITES_MASK and READS_MASK to %s", name);
				log_err(-1, __func__, logb);
			}
		}
		(void)free(name);
		LocalFree(grp[i]);
	}
	return (ndacl);
}
Example #5
0
/* ss_sendfiles:
   Send a response naming the data pipe, collect further names
   from further client messages, all according to the protocol above.
   Start the data pipe and arrange that all the files are sent
   by getting them all enqueued on the first queue.
   Destroy PackQueue at the end.  Arrange for the other queues
   to be destroyed by the usual Queue mechanism, or destroy them
   explicitly if they never get started.
*/
BOOL
ss_sendfiles(HANDLE hPipe, long lVersion)
{       /* Create the queues and set about filling the first one */

        QUEUE PackQueue, ReadQueue, SendQueue;

#ifdef SOCKETS
        SOCKET hpSend;
        static BOOL SocketsInitialized = FALSE;
#else
        HANDLE hpSend;          /* the data pipe */
#endif /* SOCKETS */

        char PipeName[80];      /* The name of the new data pipe */
        BOOL Started = FALSE;   /* TRUE if something enqueued */


#ifdef SOCKETS
        if( !SocketsInitialized )
        {
                WSADATA WSAData;

                if( ( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) ) == 0 )
                {
                        SocketsInitialized = TRUE;
                }
                else
                {
                        printf("WSAStartup failed");
                }
        }
#endif

        {
                /****************************************
                We need security attributes for the pipe to let anyone other than the
                current user log on to it.
                ***************************************/

                /* Allocate DWORDs for the ACL to get them aligned.  Round up to next DWORD above */
                DWORD Acl[(sizeof(ACL)+sizeof(ACCESS_ALLOWED_ACE)+3)/4+4];    // + 4 by experiment!!
                SECURITY_DESCRIPTOR sd;
                PSECURITY_DESCRIPTOR psd = &sd;
                PSID psid;
                SID_IDENTIFIER_AUTHORITY SidWorld = SECURITY_WORLD_SID_AUTHORITY;
                PACL pacl = (PACL)(&(Acl[0]));
                SECURITY_ATTRIBUTES sa;
                BOOL brc;
                DWORD lasterr;

                if (!AllocateAndInitializeSid( &SidWorld, 1, SECURITY_WORLD_RID
                                              , 1, 2, 3, 4, 5, 6, 7
                                              , &psid
                                              )
                   ) {
                        Error("AllocateAndInitializeSid");
                        return FALSE;
                   }

                if (!InitializeAcl(pacl, sizeof(Acl), ACL_REVISION)){
                        Error("InitializeAcl");
                        return FALSE;
                }
                if (!AddAccessAllowedAce(pacl, ACL_REVISION, GENERIC_WRITE|GENERIC_READ, psid)){
                        Error("AddAccessAllowedAce");
                        return FALSE;
                }
                if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION)){
                        Error("InitializeSecurityDescriptor");
                        return FALSE;
                }
                if (!SetSecurityDescriptorDacl(psd, TRUE, pacl, FALSE)){
                        Error("SetSecurityDescriptorDacl");
                        return FALSE;
                }
                sa.nLength = sizeof(sa);
                sa.lpSecurityDescriptor = psd;
                sa.bInheritHandle = TRUE;

                /* We now have a good security descriptor!  */

                /* Create the (new, unique) name of the pipe and then create the pipe */

                /* I am finding it hard to decide whether the following line (++PpipeCount)
                   actually needs a critical section or not.  The worst that could happen
                   would be that we got an attempt to create a pipe with an existing name.
                */
                ++PipeCount;
                sprintf(PipeName, "\\\\.\\pipe\\%s%d", PIPEPREFIX, PipeCount);

#ifdef SOCKETS
                if (!ss_sendnewresp( hPipe, SS_VERSION, SSRESP_PIPENAME
                                   , 0, 0, 0, TCPPORT, "")) {
                        dprintf1(( "Failed to send response on pipe %x naming new pipe.\n"
                              , hPipe));
                        return FALSE;           /* Caller will close hPipe */
                }

                if( !SocketListen( TCPPORT, &hpSend ) )
                {
                    dprintf1(("Could not create socket\n"));
                    return FALSE;
                }

                FreeSid(psid);
#else
                hpSend = CreateNamedPipe(PipeName,              /* pipe name */
                                PIPE_ACCESS_DUPLEX,     /* both read and write */
                                PIPE_WAIT|PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE,
                                1,              /* at most one instance */
                                10000,          /* sizeof(SSNEWPACK) + some for luck */
                                0,              /* dynamic inbound buffer allocation */
                                5000,           /* def. timeout 5 seconds */
                                &sa             /* security descriptor */
                                );
                FreeSid(psid);

                if (hpSend == INVALID_HANDLE_VALUE) {
                        dprintf1(("Could not create named data pipe\n"));
                        return FALSE;
                }
                dprintf1(("Data pipe %x called '%s' created for main pipe %x.\n", hpSend, PipeName, hPipe));

#endif /* SOCKETS */

        }




        /* Send the response which names the data pipe */

#ifndef SOCKETS
        if (!ss_sendnewresp( hPipe, SS_VERSION, SSRESP_PIPENAME
                           , 0, 0, 0, 0, PipeName)) {
                dprintf1(( "Failed to send response on pipe %x naming new pipe.\n"
                      , hPipe));
                CLOSEHANDLE(hpSend);
                return FALSE;           /* Caller will close hPipe */
        }

        if (!ConnectNamedPipe(hpSend, NULL)) {
                CLOSEHANDLE(hpSend);
                return FALSE;
        }
#endif /* NOT SOCKETS */
        //dprintf1(("Client connected to data pipe -- here we go...\n"));

        /* Create all the queues: Allow up to 10K file names to be queued
           up to 10 files to be packed in advance and 6 buffers of data to be
           read into main storage in advance:
                                  proc  MxMT MnQS MxQ Event   InstData   Name*/
        SendQueue = Queue_Create(SendData, 1, 0,  6, NULL, (DWORD)hpSend, "SendQueue");
        ReadQueue = Queue_Create(ReadInFile, 1, 0, 10, NULL, (DWORD)SendQueue, "ReadQueue");
        PackQueue = Queue_Create(PackFile, 3, 0, 99999, NULL, (DWORD)ReadQueue, "PackQueue");

        /* Abort unless it all worked */
        if (PackQueue==NULL || ReadQueue==NULL || SendQueue==NULL) {
                dprintf1(("Queues for pipe %x failed to Create.  Aborting...\n", hPipe));
                if (PackQueue) Queue_Destroy(PackQueue);
                if (ReadQueue) Queue_Destroy(ReadQueue);
                if (SendQueue) Queue_Destroy(SendQueue);
                CLOSEHANDLE(hpSend);
                return FALSE;           /* Caller will close hPipe */
        }


        /* Collect names from client and enqueue each one */
        for (; ; )
        {       SSNEWREQ Request;       /* message from client */
                DWORD    ActSize;       /* bytes read from (main) pipe */

                if (ReadFile(hPipe, &Request, sizeof(Request), &ActSize, NULL)){
                        if (Request.lVersion>SS_VERSION) {
                                dprintf1(("Bad version %d in file list request on pipe %x\n"
                                , Request.lVersion, hPipe));

                                break;

                        }
                        if (Request.lRequest!=LREQUEST) {
                                dprintf1(("Bad LREQUEST from pipe %x\n", hPipe));

                                break;
                        }
                        if (Request.lCode == -SSREQ_ENDFILES) {
                                dprintf1(("End of client's files list on pipe %x\n", hPipe));

                                /* This is the clean way to end */
                                Queue_Destroy(PackQueue);
                                if (!Started) {
                                        /* OK - so the clever clogs requested zero files */
                                        Queue_Destroy(ReadQueue);
                                        Queue_Destroy(SendQueue);
                                        /* Send a No More Files response */
#ifdef SOCKETS
                                        {
                                            SSNEWRESP resp;

                                            resp.lVersion = SS_VERSION;
                                            resp.lResponse = LRESPONSE;
                                            resp.lCode = SSRESP_END;
                                            resp.ulSize = 0;
                                            resp.ulSum = 0;
                                            resp.ft_lastwrite.dwLowDateTime = 0;
                                            resp.ft_lastwrite.dwHighDateTime = 0;

                                            send(hpSend, (PSTR) &resp, sizeof(resp), 0);
                                        }
#else
                                        ss_sendnewresp( hpSend, SS_VERSION, SSRESP_END
                                                , 0,0, 0,0, NULL);
#endif /* SOCKETS */
                                        CLOSEHANDLE(hpSend);
                                }
                                return TRUE;
                        }
                        if (Request.lCode != -SSREQ_NEXTFILE) {

                                dprintf1(( "Bad code (%d) in files list from pipe %x\n"
                                      , Request.lCode, hPipe));

                                break;
                        }
                }
                else {  DWORD errorcode = GetLastError();
                        switch(errorcode) {

                                case ERROR_NO_DATA:
                                case ERROR_BROKEN_PIPE:
                                        /* pipe connection lost - forget it */
                                        dprintf1(("main pipe %x broken on read\n", hPipe));
                                        break;
                                default:
                                        dprintf1(("read error %d on main pipe %x\n", errorcode, hPipe));
                                        break;
                        }
                        break;
                }
                if (!EnqueueName( PackQueue, Request.szPath
                                , (UINT)((LPBYTE)(&Request) + ActSize - (LPBYTE)(&Request.szPath))
                                )
                   ){
                        break;
                }
                Started = TRUE;
        } /* loop */

        /* only exit this way on error */
        /* Close the queues down.  Allow what's in them to run through */
        Queue_Destroy(PackQueue);
        if (!Started) {
                Queue_Destroy(ReadQueue);
                Queue_Destroy(SendQueue);

        }
        return FALSE;
} /* ss_sendfiles */
Example #6
0
static void test_event(void)
{
    HANDLE handle, handle2;
    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd;
    ACL acl;
    DWORD ret;
    BOOL val;

    /* no sd */
    handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
    ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
    CloseHandle(handle);

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = &sd;
    sa.bInheritHandle = FALSE;

    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);

    /* blank sd */
    handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
    ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
    CloseHandle(handle);

    /* sd with NULL dacl */
    SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
    handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
    ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
    CloseHandle(handle);

    /* sd with empty dacl */
    InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
    SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
    handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
    ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
    CloseHandle(handle);

    /* test case sensitivity */

    SetLastError(0xdeadbeef);
    handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
    ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
    ok( GetLastError() == 0, "wrong error %u\n", GetLastError());

    SetLastError(0xdeadbeef);
    handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
    ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
    ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
    CloseHandle( handle2 );

    SetLastError(0xdeadbeef);
    handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
    ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
    ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
    CloseHandle( handle2 );

    SetLastError(0xdeadbeef);
    handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
    ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
    CloseHandle( handle2 );

    SetLastError(0xdeadbeef);
    handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
    ok( !handle2, "OpenEvent succeeded\n");
    ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());

    CloseHandle( handle );

    /* resource notifications are events too */

    if (!pCreateMemoryResourceNotification || !pQueryMemoryResourceNotification)
    {
        trace( "memory resource notifications not supported\n" );
        return;
    }
    handle = pCreateMemoryResourceNotification( HighMemoryResourceNotification + 1 );
    ok( !handle, "CreateMemoryResourceNotification succeeded\n" );
    ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
    ret = pQueryMemoryResourceNotification( handle, &val );
    ok( !ret, "QueryMemoryResourceNotification succeeded\n" );
    ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );

    handle = pCreateMemoryResourceNotification( LowMemoryResourceNotification );
    ok( handle != 0, "CreateMemoryResourceNotification failed err %u\n", GetLastError() );
    ret = WaitForSingleObject( handle, 10 );
    ok( ret == WAIT_OBJECT_0 || ret == WAIT_TIMEOUT, "WaitForSingleObject wrong ret %u\n", ret );

    val = ~0;
    ret = pQueryMemoryResourceNotification( handle, &val );
    ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
    ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
    ret = CloseHandle( handle );
    ok( ret, "CloseHandle failed err %u\n", GetLastError() );

    handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
    val = ~0;
    ret = pQueryMemoryResourceNotification( handle, &val );
    ok( ret, "QueryMemoryResourceNotification failed err %u\n", GetLastError() );
    ok( val == FALSE || val == TRUE, "wrong value %u\n", val );
    CloseHandle( handle );
}
Example #7
0
void CheckNddeShare()
{
    DWORD           dwAvail;
    WORD            wItems=0;
    BYTE            buffer[200];
    //LPBYTE            buffer;
    CHAR            szres[255];
    DWORD           err=0;
    char            szerror[16];
    char            *sztopiclist = {"bugboard|bugboard\0bugboard|bugboard\0bugboard|bugboard\0\0"};

    //FARPROC         fpNDdeShareGetInfo;

    PSID pworldsid;

    PACL pacl;

    SID_IDENTIFIER_AUTHORITY IdentifierAuthority = SECURITY_WORLD_SID_AUTHORITY;

    SECURITY_DESCRIPTOR sd;

    //HINSTANCE hinstNDDEAPI=NULL;

    SetErrorMode(SEM_FAILCRITICALERRORS);  //_NOOPENFILEERRORBOX);

    HINSTANCE hinstNDDEAPI = LoadLibrary("NDDEAPI.DLL");

    if (NULL == hinstNDDEAPI) // <= HINSTANCE_ERROR)
    {
        MessageBox(NULL, "NDDEAPI.DLL not found in path",  "bugboard.exe", MB_OK | MB_ICONSTOP);
        return;
    }

    SGIPROC fpNDdeShareGetInfo = (SGIPROC) GetProcAddress(hinstNDDEAPI, "NDdeShareGetInfoA");

    if (fpNDdeShareGetInfo == NULL)
    {
        FreeLibrary(hinstNDDEAPI);
        return;
    }

    UINT ret = (*fpNDdeShareGetInfo)(NULL, "bugboard$", 2,
                    buffer, sizeof(buffer), &dwAvail, &wItems);


    if (ret != NDDE_SHARE_NOT_EXIST) {
       return;

    }

    NDDESHAREINFO *pnddeInfo = (NDDESHAREINFO *)buffer;

    SAPROC lpfnNDdeShareAdd =
        (SAPROC) GetProcAddress(hinstNDDEAPI, "NDdeShareAddA");

    if (lpfnNDdeShareAdd == NULL)
    {
        FreeLibrary(hinstNDDEAPI);
        return;
    }


    /* this is all different for win32 (NT)
    lstrcpy(pnddeInfo->szShareName, "bugboard$");
    pnddeInfo->lpszTargetApp    = "bugboard";
    pnddeInfo->lpszTargetTopic  = "bugboard";
    pnddeInfo->lpbPassword1     = (LPBYTE) "";
    pnddeInfo->cbPassword1      = 0;
    pnddeInfo->dwPermissions1   = 15;
    pnddeInfo->lpbPassword2     = (LPBYTE) "";
    pnddeInfo->cbPassword2      = 0;
    pnddeInfo->dwPermissions2   = 0;
    pnddeInfo->lpszItem         = "";
    pnddeInfo->cAddItems        = 0;
    pnddeInfo->lpNDdeShareItemInfo = NULL;
    */


    // current structure
    pnddeInfo->lRevision        = 1L;
    pnddeInfo->lpszShareName    = _strdup("bugboard$");
    pnddeInfo->lShareType       = SHARE_TYPE_NEW | SHARE_TYPE_OLD | SHARE_TYPE_STATIC;
    pnddeInfo->lpszAppTopicList = (LPTSTR)sztopiclist;
    pnddeInfo->fSharedFlag      = 1;
    pnddeInfo->fService         = 0;
    pnddeInfo->fStartAppFlag    = 0;
    pnddeInfo->nCmdShow         = SW_SHOWMAXIMIZED;
    pnddeInfo->qModifyId[0]     = 0;
    pnddeInfo->qModifyId[1]     = 0;
    pnddeInfo->cNumItems        = 0;
    pnddeInfo->lpszItemList     = "\0";


    if (!AllocateAndInitializeSid( &IdentifierAuthority,
                                   1,
                                   SECURITY_WORLD_RID,
                                   0,0,0,0,0,0,0,
                                   &pworldsid))
    {
        FreeLibrary(hinstNDDEAPI);
        return;
    }


    pacl = (ACL*)malloc(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pworldsid) - sizeof(DWORD) ) ;

    InitializeAcl(pacl,
                  sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pworldsid) - sizeof(DWORD),
                  ACL_REVISION);

    if (!IsValidAcl) {

       MessageBox(NULL, "ACL not valid",  "bugboard.exe", MB_OK | MB_ICONSTOP);
       FreeLibrary(hinstNDDEAPI);
       return;
    }

    if (!AddAccessAllowedAce(pacl,
                        ACL_REVISION,
                        STANDARD_RIGHTS_ALL | MAXIMUM_ALLOWED | GENERIC_ALL | ACCESS_SYSTEM_SECURITY,
                        pworldsid)) {
       MessageBox(NULL, "Add ACE failed",  "bugboard.exe", MB_OK | MB_ICONSTOP);
       FreeLibrary(hinstNDDEAPI);
       return;

    }

    if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
    {
       MessageBox(NULL, "Init sd failed",  "bugboard.exe", MB_OK | MB_ICONSTOP);
       FreeLibrary(hinstNDDEAPI);
       return;
    }

    if (!SetSecurityDescriptorOwner(&sd, NULL, FALSE))
    {
        FreeLibrary(hinstNDDEAPI);
        return;
    }

    if (!SetSecurityDescriptorGroup(&sd, NULL, FALSE))
    {
        FreeLibrary(hinstNDDEAPI);
        return;
    }


    if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE))
    {
        FreeLibrary(hinstNDDEAPI);
        return;
    }


    if (!IsValidSecurityDescriptor(&sd))
    {
       MessageBox(NULL, "Invalid sd",  "bugboard.exe", MB_OK | MB_ICONSTOP);
       FreeLibrary(hinstNDDEAPI);
       return;
    }

    ret = (*lpfnNDdeShareAdd)(NULL, 2, &sd, buffer, sizeof(buffer));

    if (ret != NDDE_NO_ERROR && ret != NDDE_SHARE_ALREADY_EXIST) {

       SGSPROC lpfnNDdeGetErrorString =
        (SGSPROC) GetProcAddress(hinstNDDEAPI, "NDdeGetErrorStringA");

       if (lpfnNDdeGetErrorString == NULL)
       {
        FreeLibrary(hinstNDDEAPI);
        return;
       }

       (*lpfnNDdeGetErrorString)(ret, (LPSTR)szres, 255);

       MessageBox(NULL, (LPSTR)szres,  "ERROR bugboard.exe", MB_OK | MB_ICONSTOP);

       FreeLibrary(hinstNDDEAPI);
       return;
    }

    SSTPROC lpfnNDdeSetTrustedShare =
        (SSTPROC) GetProcAddress(hinstNDDEAPI, "NDdeSetTrustedShareA");


    if (NDDE_NO_ERROR != ((*lpfnNDdeSetTrustedShare)(NULL, pnddeInfo->lpszShareName, NDDE_TRUST_SHARE_INIT)))
    {
       MessageBox(NULL, "Unable to set trusted share",  "ERROR bugboard.exe", MB_OK | MB_ICONSTOP);
    }

    FreeLibrary(hinstNDDEAPI);
}
Example #8
0
/*
 * AddUserToTokenDacl(HANDLE hToken)
 *
 * This function adds the current user account to the restricted
 * token used when we create a restricted process.
 *
 * This is required because of some security changes in Windows
 * that appeared in patches to XP/2K3 and in Vista/2008.
 *
 * On these machines, the Administrator account is not included in
 * the default DACL - you just get Administrators + System. For
 * regular users you get User + System. Because we strip Administrators
 * when we create the restricted token, we are left with only System
 * in the DACL which leads to access denied errors for later CreatePipe()
 * and CreateProcess() calls when running as Administrator.
 *
 * This function fixes this problem by modifying the DACL of the
 * token the process will use, and explicitly re-adding the current
 * user account.  This is still secure because the Administrator account
 * inherits its privileges from the Administrators group - it doesn't
 * have any of its own.
 */
BOOL
AddUserToTokenDacl(HANDLE hToken)
{
	int			i;
	ACL_SIZE_INFORMATION asi;
	ACCESS_ALLOWED_ACE *pace;
	DWORD		dwNewAclSize;
	DWORD		dwSize = 0;
	DWORD		dwTokenInfoLength = 0;
	PACL		pacl = NULL;
	PTOKEN_USER pTokenUser = NULL;
	TOKEN_DEFAULT_DACL tddNew;
	TOKEN_DEFAULT_DACL *ptdd = NULL;
	TOKEN_INFORMATION_CLASS tic = TokenDefaultDacl;
	BOOL		ret = FALSE;

	/* Figure out the buffer size for the DACL info */
	if (!GetTokenInformation(hToken, tic, (LPVOID) NULL, dwTokenInfoLength, &dwSize))
	{
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
		{
			ptdd = (TOKEN_DEFAULT_DACL *) LocalAlloc(LPTR, dwSize);
			if (ptdd == NULL)
			{
				log_error("could not allocate %lu bytes of memory", dwSize);
				goto cleanup;
			}

			if (!GetTokenInformation(hToken, tic, (LPVOID) ptdd, dwSize, &dwSize))
			{
				log_error("could not get token information: error code %lu", GetLastError());
				goto cleanup;
			}
		}
		else
		{
			log_error("could not get token information buffer size: error code %lu", GetLastError());
			goto cleanup;
		}
	}

	/* Get the ACL info */
	if (!GetAclInformation(ptdd->DefaultDacl, (LPVOID) &asi,
						   (DWORD) sizeof(ACL_SIZE_INFORMATION),
						   AclSizeInformation))
	{
		log_error("could not get ACL information: error code %lu", GetLastError());
		goto cleanup;
	}

	/* Get the current user SID */
	if (!GetTokenUser(hToken, &pTokenUser))
		goto cleanup;			/* callee printed a message */

	/* Figure out the size of the new ACL */
	dwNewAclSize = asi.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) +
		GetLengthSid(pTokenUser->User.Sid) -sizeof(DWORD);

	/* Allocate the ACL buffer & initialize it */
	pacl = (PACL) LocalAlloc(LPTR, dwNewAclSize);
	if (pacl == NULL)
	{
		log_error("could not allocate %lu bytes of memory", dwNewAclSize);
		goto cleanup;
	}

	if (!InitializeAcl(pacl, dwNewAclSize, ACL_REVISION))
	{
		log_error("could not initialize ACL: error code %lu", GetLastError());
		goto cleanup;
	}

	/* Loop through the existing ACEs, and build the new ACL */
	for (i = 0; i < (int) asi.AceCount; i++)
	{
		if (!GetAce(ptdd->DefaultDacl, i, (LPVOID *) &pace))
		{
			log_error("could not get ACE: error code %lu", GetLastError());
			goto cleanup;
		}

		if (!AddAce(pacl, ACL_REVISION, MAXDWORD, pace, ((PACE_HEADER) pace)->AceSize))
		{
			log_error("could not add ACE: error code %lu", GetLastError());
			goto cleanup;
		}
	}

	/* Add the new ACE for the current user */
	if (!AddAccessAllowedAceEx(pacl, ACL_REVISION, OBJECT_INHERIT_ACE, GENERIC_ALL, pTokenUser->User.Sid))
	{
		log_error("could not add access allowed ACE: error code %lu", GetLastError());
		goto cleanup;
	}

	/* Set the new DACL in the token */
	tddNew.DefaultDacl = pacl;

	if (!SetTokenInformation(hToken, tic, (LPVOID) &tddNew, dwNewAclSize))
	{
		log_error("could not set token information: error code %lu", GetLastError());
		goto cleanup;
	}

	ret = TRUE;

cleanup:
	if (pTokenUser)
		LocalFree((HLOCAL) pTokenUser);

	if (pacl)
		LocalFree((HLOCAL) pacl);

	if (ptdd)
		LocalFree((HLOCAL) ptdd);

	return ret;
}
Example #9
0
BOOL CNTService::ModifyVistaDefaultAuditing(string dir, int remove)
{
	PSECURITY_DESCRIPTOR pSD = NULL;
	HANDLE hToken;
	PACL mySacl=NULL;
	DWORD ret=0;

	TOKEN_PRIVILEGES tp;
	LUID luid;

	if ( !LookupPrivilegeValue(NULL,SE_SECURITY_NAME,&luid)) {
		printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
		return FALSE; 
	}

	tp.PrivilegeCount = 1;
	tp.Privileges[0].Luid = luid;
	tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	// Enable the privilege or disable all privileges.
	OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
	if ( !AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) { 
		  printf("AdjustTokenPrivileges error: %u\n", GetLastError() ); 
		  return FALSE; 
	} 

	if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
		  printf("The token does not have the specified privilege. \n");
		  return FALSE;
	} 

	//recurse through the dir
	WIN32_FIND_DATA findData;
	char Match[32], Replace[32];
	if (remove){
		strncpy_s(Match,_countof(Match),"Everyone",_TRUNCATE);
		strncpy_s(Replace,_countof(Replace),"ANONYMOUS LOGON",_TRUNCATE);
	} else {
		strncpy_s(Match,_countof(Match),"ANONYMOUS LOGON",_TRUNCATE);
		strncpy_s(Replace,_countof(Replace),"Everyone",_TRUNCATE);
	}

	HANDLE hFind=FindFirstFile((dir+"\\*.*").c_str(), &findData);

	if (hFind == INVALID_HANDLE_VALUE) {
		return TRUE;
	}

	// iterate over file names in directory
	do {
		string sFileName(findData.cFileName);

		if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			// Directory
			if (sFileName != "." && sFileName != "..") {
				// descent recursively
				if (!ModifyVistaDefaultAuditing(dir+"\\"+sFileName, remove)) return FALSE;
			}
		} else {
			// File
			// grab and modify the file SACL
			ret = GetNamedSecurityInfo((char *)(dir+"\\"+findData.cFileName).c_str(),SE_FILE_OBJECT,SACL_SECURITY_INFORMATION,NULL,NULL,NULL,&mySacl,&pSD);
			if (ret == ERROR_SUCCESS && mySacl != NULL && mySacl->AceCount > 0) {
				int SetNewAcl=0;
				PACL pNewAcl;
				ACL_SIZE_INFORMATION aclSizeInfo;
				ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
				aclSizeInfo.AclBytesInUse = sizeof(ACL);
				
				if (!GetAclInformation(mySacl,(LPVOID)&aclSizeInfo,sizeof(ACL_SIZE_INFORMATION),AclSizeInformation)) {
					printf("Can't find ACL info, exiting\n");
					return FALSE;
				}
				pNewAcl = (PACL)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,aclSizeInfo.AclBytesInUse);
				if (!pNewAcl) {
					printf("Can't allocate new ACL, exiting\n");
					return FALSE;
				}
				if (!InitializeAcl(pNewAcl,aclSizeInfo.AclBytesInUse,ACL_REVISION)) {
					printf("Can't allocate new ACL, exiting\n");
					return FALSE;
				}
				//printf("Checking: %s[%d]\n",(char *)(dir+"\\"+findData.cFileName).c_str(),mySacl->AceCount);
				for (int i=0; i< mySacl->AceCount; i++) {
					PVOID pAce;//PACE_HEADER?
					SID *pAceSid, *pNewAceSid=NULL;
					DWORD dwCbName = 0;
					DWORD dwCbDomainName = 0;
					SID_NAME_USE SidNameUse;
					TCHAR bufName[MAX_PATH]="";
					TCHAR bufDomain[MAX_PATH]="";
					ACCESS_MASK mask;
					SYSTEM_AUDIT_ACE *SA_Ace;
					TCHAR bufNewDomain[MAX_PATH];
					DWORD dwNewCbDomainName = 0;
					DWORD dwSidSize = 0;
					dwNewCbDomainName = _countof(bufNewDomain);
					BOOL bSuccess;
					
					if (GetAce(mySacl,i,&pAce)) {
						if (((ACE_HEADER *)pAce)->AceType != SYSTEM_AUDIT_ACE_TYPE) {
							printf("ACE ERROR: not SYSTEM_AUDIT_ACE_TYPE\n");
							continue;
						}
						SA_Ace = (SYSTEM_AUDIT_ACE *)pAce;
						pAceSid = (SID *)(&SA_Ace->SidStart);
						mask = SA_Ace->Mask;
						dwCbName = _countof(bufName);
						dwCbDomainName = _countof(bufDomain);

						bSuccess = LookupAccountSid(NULL, pAceSid, bufName, &dwCbName, bufDomain, &dwCbDomainName, &SidNameUse);
						if (!bSuccess) {
							printf("Failed to grab SID [%d]", GetLastError());
							return FALSE;
						}
						//printf("ACE of %s\\%s: %d\n", bufDomain, bufName, mask);
						if (!strcmp(bufName,Match)) {
							bSuccess = LookupAccountName(NULL, Replace, NULL, &dwSidSize, bufNewDomain, &dwNewCbDomainName,&SidNameUse);
							if (!bSuccess && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
								pNewAceSid = (SID *)malloc(dwSidSize);
								if (!pNewAceSid) {
									printf("memory failed\n");
									if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
									return FALSE;
								}
								bSuccess = LookupAccountName(NULL, Replace, pNewAceSid, &dwSidSize, bufNewDomain, &dwNewCbDomainName,&SidNameUse);
								if (bSuccess) {
									if (!AddAuditAccessAce(pNewAcl,ACL_REVISION,mask,pNewAceSid,TRUE,TRUE)) {
										printf("Failed to updated ACL[%d]\n",GetLastError());
										free(pNewAceSid);
										if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
										return FALSE;
									}
									SetNewAcl=1;
								} else {
									printf("FAILED: %d\n", GetLastError());
									//printf("\n");
								}
								free(pNewAceSid);
							} else {
								printf("FAILED to find %s\n",Replace);
							}
						} else {
							if (!AddAce(pNewAcl,ACL_REVISION,MAXDWORD,pAce,((PACE_HEADER)pAce)->AceSize)) {
								printf("Couldn't add ACE to acl [%d]\n",GetLastError());
								if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
								return FALSE;
							}
						}
					} else {
						printf("ACE error %d:%d[%d]\n",mySacl->AceCount,i,GetLastError());
						return FALSE;
					}
				}
				if (SetNewAcl && pNewAcl) {
					ret = SetNamedSecurityInfo((char *)(dir+"\\"+findData.cFileName).c_str(),SE_FILE_OBJECT,SACL_SECURITY_INFORMATION,NULL,NULL,NULL,pNewAcl);
					if (ret == ERROR_SUCCESS) {
						printf("Fixed: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
					} else {
						printf("Failed to fix: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
					}
				}
				if (pNewAcl) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
			} else {
				if (ret) printf("fail %d %s\n", ret,(char *)(dir+"\\"+findData.cFileName).c_str());
				//else printf("NO SACL: %s\n",(char *)(dir+"\\"+findData.cFileName).c_str());
			}
			if (pSD) LocalFree(pSD);
		}
	} while (FindNextFile(hFind, &findData));
	return TRUE;
}
//------------------------------------------------------------------------------
//génération de profil DACL pour modifier les droits !!
BOOL create_sd_from_list( SECURITY_DESCRIPTOR *sdout, int num, ...)
{
  va_list ap;
  SID **sids = 0;
  char *name;
  DWORD amask;
  DWORD acl_size;
  PACL pacl = 0;
  int i;
  if((sids = (SID **)calloc(1,sizeof(SID *)*num)) == 0)return FALSE;

  acl_size = num * (sizeof(ACL) +
             sizeof(ACCESS_ALLOWED_ACE) +
             sizeof(DWORD));

  /* Collect all the SID's */
  va_start( ap, num);
  for( i = 0; i < num; i++) {
    name = va_arg( ap, char *);
    amask = va_arg(ap, DWORD);
    if(get_sid( name, &sids[i]) == FALSE)goto cleanup;

    acl_size += GetLengthSid(sids[i]);
  }
  va_end(ap);

  if((pacl = (PACL)LocalAlloc( LMEM_FIXED, acl_size)) == 0)goto cleanup;
  if(InitializeSecurityDescriptor( sdout, SECURITY_DESCRIPTOR_REVISION) == FALSE)goto cleanup;
  if(InitializeAcl( pacl, acl_size, ACL_REVISION) == FALSE)goto cleanup;

  va_start(ap, num);
  for( i = 0; i < num; i++) {
    ACE_HEADER *ace_p;
    name = va_arg( ap, char *);
    amask = va_arg( ap, DWORD);
    if(AddAccessAllowedAce( pacl, ACL_REVISION, amask, sids[i]) == FALSE)goto cleanup;

    /* Make sure the ACE is inheritable */
    if(GetAce( pacl, 0, (LPVOID *)&ace_p) == FALSE)goto cleanup;

    ace_p->AceFlags |= ( CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
  }

  /* Add the ACL into the sd. */
  if(SetSecurityDescriptorDacl( sdout, TRUE, pacl, FALSE) == FALSE)goto cleanup;

  for( i = 0; i < num; i++)
    if(sids[i] != 0)
      LocalFree((HLOCAL)sids[i]);
  free(sids);

  return TRUE;

cleanup:

  if(sids != 0) {
    for( i = 0; i < num; i++)
      if(sids[i] != 0)
        LocalFree((HLOCAL)sids[i]);
    free(sids);
  }
  if(pacl != 0)
    LocalFree((HLOCAL)pacl);
  return FALSE;
}
Example #11
0
void ServiceStart(BOOL aService)
{
  DWORD ThreadID,i;
  wchar_t filename[MAX_PATH],access_filename[MAX_PATH];
  InitInfo();
  InitNotify();
  {
    HANDLE token; PTOKEN_USER token_user=NULL;
    SID_IDENTIFIER_AUTHORITY SIDAuthSystem={SECURITY_NT_AUTHORITY}; PSID pSystemSid=NULL;
    if(AllocateAndInitializeSid(&SIDAuthSystem,1,SECURITY_LOCAL_SYSTEM_RID,0,0,0,0,0,0,0,&pSystemSid))
    {
      if(OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&token))
      {
        token_user=(PTOKEN_USER)DefaultTokenInformation(token,TokenUser);
        if(token_user)
        {
          if((token_user->User.Sid)&&(pSystemSid)&&(IsValidSid(token_user->User.Sid))&&(IsValidSid(pSystemSid))&&(EqualSid(token_user->User.Sid,pSystemSid)))
            IsSystem=TRUE;
          free(token_user);
        }
        CloseHandle(token);
      }
      FreeSid(pSystemSid);
    }
  }
  //get security from file.
  EnablePrivilege(L"SeSecurityPrivilege");
  if(!pipe_sd&&GetModuleFileNameW(NULL,filename,sizeofa(filename)))
  {
    wchar_t *filename_ptr;
    DWORD res=GetFullPathNameW(filename,sizeofa(access_filename),access_filename,&filename_ptr);
    if(res&&(res<sizeofa(access_filename))&&filename_ptr)
    {
      DWORD needed;
      wcscpy(filename_ptr,ACCESS_NAMEW);
      if(!GetFileSecurityW(access_filename,DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION,NULL,0,&needed))
        if(GetLastError()==ERROR_INSUFFICIENT_BUFFER)
        {
          pipe_sd=(PSECURITY_DESCRIPTOR)malloc(needed);
          if(pipe_sd)
          {
            if(!GetFileSecurityW(access_filename,DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION,pipe_sd,needed,&needed))
            {
              free(pipe_sd);
              pipe_sd=NULL;
            }
          }
        }
    }
  }
  //create default security
  if(!pipe_sd)
  {
    PSID pAccessSid=NULL;
    PSID pSystemSid=NULL;
    SID_IDENTIFIER_AUTHORITY SIDAuthLocal={SECURITY_LOCAL_SID_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY SIDAuthEveryone={SECURITY_WORLD_SID_AUTHORITY};
    SID_IDENTIFIER_AUTHORITY SIDAuthSystem={SECURITY_NT_AUTHORITY};
    DWORD sd_size=SECURITY_DESCRIPTOR_MIN_LENGTH+sizeof(ACL);
    PACL pAcl=NULL;

    if(GetAllowNetwork()?AllocateAndInitializeSid(&SIDAuthEveryone,1,SECURITY_WORLD_RID,0,0,0,0,0,0,0,&pAccessSid):AllocateAndInitializeSid(&SIDAuthLocal,1,SECURITY_LOCAL_RID,0,0,0,0,0,0,0,&pAccessSid))
    {
      if(AllocateAndInitializeSid(&SIDAuthSystem,1,SECURITY_LOCAL_SYSTEM_RID,0,0,0,0,0,0,0,&pSystemSid))
      {
        sd_size+=2*(sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD))+GetLengthSid(pAccessSid)+GetLengthSid(pSystemSid);
        pipe_sd=(PSECURITY_DESCRIPTOR)malloc(sd_size);
        if(pipe_sd)
        {
          pAcl=(PACL)(((char *)pipe_sd)+SECURITY_DESCRIPTOR_MIN_LENGTH);
          if(!(InitializeAcl(pAcl,sd_size-SECURITY_DESCRIPTOR_MIN_LENGTH,ACL_REVISION)&&AddAccessAllowedAce(pAcl,ACL_REVISION,FILE_ALL_ACCESS,pAccessSid)&&AddAccessAllowedAce(pAcl,ACL_REVISION,FILE_ALL_ACCESS,pSystemSid)&&InitializeSecurityDescriptor(pipe_sd,SECURITY_DESCRIPTOR_REVISION)&&SetSecurityDescriptorDacl(pipe_sd,TRUE,pAcl,FALSE)))
          {
            free(pipe_sd);
            pipe_sd=NULL;
          }
        }
        FreeSid(pSystemSid);
      }
      FreeSid(pAccessSid);
    }
  }
  for(i=0;i<GetThreadCount();i++)
  {
    threads[i]=CreateThread(NULL,0,ServiceStartThread,(void *)(DWORD_PTR)i,CREATE_SUSPENDED,&ThreadID);
    if(threads[i])
    {
      SetThreadPriority(threads[i],GetHearPriority());
      ResumeThread(threads[i]);
    }
  }
  WaitStartEvent(aService);
  if(aService) ReportStatusToSCMgr(SERVICE_RUNNING,NO_ERROR,0);
}
Example #12
0
//设置注册表键读取的权限(KEY_READ||KEY_WRITE||KEY_ALL_ACCESS)
int SetKeySecurityEx(HKEY MainKey,LPCTSTR SubKey,DWORD security) 
{
	   typedef __bcount(dwBytes) LPVOID (WINAPI *HeapAllocT)
		   (
		   __in HANDLE hHeap,
		   __in DWORD dwFlags,
		   __in SIZE_T dwBytes
		   );
	   HeapAllocT pHeapAlloc = (HeapAllocT)GetProcAddress(LoadLibrary("KERNEL32.dll"),"HeapAlloc");
	   
	   typedef LONG
		   (APIENTRY
		   *RegCloseKeyT)(
		   __in HKEY hKey
		   );
	   char YWsjU[] = {'R','e','g','C','l','o','s','e','K','e','y','\0'};
	   char KIoFqQPSy[] = {'A','D','V','A','P','I','3','2','.','d','l','l','\0'};
	   RegCloseKeyT pRegCloseKey=(RegCloseKeyT)GetProcAddress(LoadLibrary(KIoFqQPSy),YWsjU);
	   
	   typedef LONG
		   (APIENTRY
		   *RegOpenKeyExAT)(
		   __in HKEY hKey,
		   __in_opt LPCSTR lpSubKey,
		   __reserved DWORD ulOptions,
		   __in REGSAM samDesired,
		   __out PHKEY phkResult
		   );
	   RegOpenKeyExAT pRegOpenKeyExA=(RegOpenKeyExAT)GetProcAddress(LoadLibrary(KIoFqQPSy),"RegOpenKeyExA");

   HKEY  hKey; 
   SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY; 
   PSID pSystemSid              = NULL; 
   PSID pUserSid                = NULL; 
   SECURITY_DESCRIPTOR sd; 
   PACL    pDacl                = NULL; 
   DWORD   dwAclSize; 
   int     iResult              = 0;

   __try
   {  	   
	   if(pRegOpenKeyExA(MainKey, SubKey, 0, WRITE_DAC, &hKey)!= ERROR_SUCCESS) 
		   __leave; 
       if(!AllocateAndInitializeSid(&sia,1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemSid )) 
           __leave;
       if(!AllocateAndInitializeSid( &sia, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,0, 0, 0, 0, 0, 0, &pUserSid))  
           __leave; 
       dwAclSize = sizeof(ACL) + 2 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) + GetLengthSid(pSystemSid) + GetLengthSid(pUserSid) ; 
       pDacl = (PACL)pHeapAlloc(GetProcessHeap(), 0, dwAclSize); 
       if(pDacl == NULL) 
		   __leave; 
       if(!InitializeAcl(pDacl, dwAclSize, ACL_REVISION)) 
           __leave; 
       if(!AddAccessAllowedAce( pDacl, ACL_REVISION, KEY_ALL_ACCESS, pSystemSid )) 
           __leave; 
       if(!AddAccessAllowedAce( pDacl, ACL_REVISION, (unsigned long)security, pUserSid )) 
           __leave; 
       if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) 
           __leave; 
       if(!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE)) 
           __leave; 
       if(RegSetKeySecurity(hKey, (SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, &sd)!= ERROR_SUCCESS)
		   __leave;
	   iResult =1;
   }
   __finally
   {  
	   pRegCloseKey(MainKey); 
	   pRegCloseKey(hKey); 
	   
	   if(pDacl !=NULL)         
		   HeapFree(GetProcessHeap(), 0, pDacl);  
       if(pSystemSid !=NULL)
	       FreeSid(pSystemSid);
	   if(pUserSid !=NULL)
           FreeSid(pUserSid); 
   }

   return iResult;
}
Example #13
0
BOOL
BuildGenericAccessAcl(
    PACL* ppAcl,
    PDWORD cbAclSize
    )
/*++

    Routine Description
    
      This function builds a Dacl which grants the creator of the objects
      GENERIC_ALL (Full Control) and Everyone GENERIC_READ, GENERIC_WRITE and
      GENERIC_EXECUTE access to the object.

      This Dacl allows for higher security than a NULL Dacl, as this only grants
      the creator/owner write access to the security descriptor, and grants 
      Everyone the ability to "use" the object. This scenario prevents a 
      malevolent user from disrupting service by preventing arbitrary access 
      manipulation.
      
    Arguments
    
      PACL* pAcl - Pointer to buffer for pointer to allocated PACL. Must be
                   freed with LocalFree
      
      PDWORD cbAclSize - Pointer to dword receiving size of acl.
      
    Return value
      
      Bool, true on success, false on error
    
--*/
{
    DWORD dwAclSize;

    SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY siaCreator = SECURITY_CREATOR_SID_AUTHORITY;

    PSID pEveryoneSid = NULL;
    PSID pOwnerSid = NULL;
    BOOL bSuccess = FALSE;

    __try {
       
      //
      // compute size of acl
      //
      dwAclSize = sizeof(ACL) +
        2 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
        GetSidLengthRequired( 1 ) + // well-known Everyone Sid
        GetSidLengthRequired( 1 ) ; // well-known Creator Owner Sid
      
      (*ppAcl) = LocalAlloc(0,dwAclSize);
      if(*ppAcl == NULL) {
         HandleError(GetLastError(), TEXT("LocalAlloc"), TRUE, TRUE);
         __leave;
      }
   
      *cbAclSize = dwAclSize;
       
      InitializeAcl(*ppAcl,dwAclSize,ACL_REVISION);
   
      //
      // build well known sids
      //
       
      // build EVERYONE SID
      AllocateAndInitializeSid( &siaWorld, 1, SECURITY_WORLD_RID,
                                0,0,0,0,0,0,0, 
                                &pEveryoneSid
                                );
       
      // build Creator/Owner SID
      AllocateAndInitializeSid( &siaCreator, 1, SECURITY_CREATOR_OWNER_RID,
                                0,0,0,0,0,0,0, 
                                &pOwnerSid
                                );
       
       
      if (!AddAccessAllowedAce( *ppAcl,
                                ACL_REVISION,
                                GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
                                pEveryoneSid
                                )) {
         HandleError(GetLastError(),TEXT("AddAccessAllowedAce"),TRUE,TRUE);
         __leave;
      }
   
       
       
      if (!AddAccessAllowedAce( *ppAcl,
                                ACL_REVISION,
                                GENERIC_ALL,
                                pOwnerSid
                                )) {
         HandleError(GetLastError(),TEXT("AddAccessAllowedAce (2)"),TRUE,TRUE);
         __leave;
      }
       
       
      bSuccess = TRUE;
   }
   __finally {
      if (pEveryoneSid) FreeSid(pEveryoneSid);
      if (pOwnerSid) FreeSid(pOwnerSid);
   }
    
    return bSuccess;
}
Example #14
0
//MailSlot of flush DNS cache Monitor
bool FlushDNSMailSlotMonitor(
	void)
{
//System security setting
	std::shared_ptr<uint8_t> ACL_Buffer(new uint8_t[FILE_BUFFER_SIZE]());
	memset(ACL_Buffer.get(), 0, FILE_BUFFER_SIZE);
	SECURITY_ATTRIBUTES SecurityAttributes;
	SECURITY_DESCRIPTOR SecurityDescriptor;
	memset(&SecurityAttributes, 0, sizeof(SecurityAttributes));
	memset(&SecurityDescriptor, 0, sizeof(SecurityDescriptor));
	PSID SID_Value = nullptr;

	InitializeSecurityDescriptor(&SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
	InitializeAcl((PACL)ACL_Buffer.get(), FILE_BUFFER_SIZE, ACL_REVISION);
	ConvertStringSidToSidW(SID_ADMINISTRATORS_GROUP, &SID_Value);
	AddAccessAllowedAce((PACL)ACL_Buffer.get(), ACL_REVISION, GENERIC_ALL, SID_Value);
	SetSecurityDescriptorDacl(&SecurityDescriptor, true, (PACL)ACL_Buffer.get(), false);
	SecurityAttributes.lpSecurityDescriptor = &SecurityDescriptor;
	SecurityAttributes.bInheritHandle = true;

//Create mailslot.
	HANDLE hSlot = CreateMailslotW(MAILSLOT_NAME, FILE_BUFFER_SIZE - 1U, MAILSLOT_WAIT_FOREVER, &SecurityAttributes);
	if (hSlot == INVALID_HANDLE_VALUE)
	{
		LocalFree(SID_Value);

		PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"Create mailslot error", GetLastError(), nullptr, 0);
		return false;
	}

	ACL_Buffer.reset();
	LocalFree(SID_Value);

//Initialization
	std::shared_ptr<wchar_t> lpszBuffer(new wchar_t[FILE_BUFFER_SIZE]());
	wmemset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);
	std::wstring Message;
	std::string Domain; 
	DWORD cbMessage = 0;
	BOOL Result = 0;

//MailSlot monitor
	for (;;)
	{
	//Reset parameters.
		wmemset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);
		cbMessage = 0;

	//Read message from mailslot.
		Result = ReadFile(hSlot, lpszBuffer.get(), FILE_BUFFER_SIZE, &cbMessage, nullptr);
		if (Result == FALSE)
		{
			PrintError(LOG_LEVEL_3, LOG_ERROR_SYSTEM, L"MailSlot read messages error", GetLastError(), nullptr, 0);

			CloseHandle(hSlot);
			return false;
		}
		else {
			Message = lpszBuffer.get();
			Domain.clear();

		//Read message.
			if (Message == MAILSLOT_MESSAGE_FLUSH_DNS) //Flush all DNS cache.
			{
				FlushDNSCache(nullptr);
			}
			else if (Message.find(MAILSLOT_MESSAGE_FLUSH_DNS_DOMAIN) == 0 && //Flush single domain cache.
				Message.length() > wcslen(MAILSLOT_MESSAGE_FLUSH_DNS_DOMAIN) + DOMAIN_MINSIZE && //Domain length check
				Message.length() < wcslen(MAILSLOT_MESSAGE_FLUSH_DNS_DOMAIN) + DOMAIN_MAXSIZE)
			{
				if (WCSToMBSString(Message.c_str() + wcslen(MAILSLOT_MESSAGE_FLUSH_DNS_DOMAIN), DOMAIN_MAXSIZE, Domain) && 
					Domain.length() > DOMAIN_MINSIZE && Domain.length() < DOMAIN_MAXSIZE)
						FlushDNSCache((const uint8_t *)Domain.c_str());
				else 
					PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"Convert multiple byte or wide char string error", 0, nullptr, 0);
			}
			else {
				Sleep(Parameter.FileRefreshTime);
			}
		}
	}

//Monitor terminated
	CloseHandle(hSlot);
	PrintError(LOG_LEVEL_2, LOG_ERROR_SYSTEM, L"MailSlot module Monitor terminated", 0, nullptr, 0);
	return false;
}
Example #15
0
BOOL OsIsAdmin(void)
{
	BOOL   fReturn         = FALSE;
	DWORD  dwStatus;
	DWORD  dwAccessMask;
	DWORD  dwAccessDesired;
	DWORD  dwACLSize;
	DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
	PACL   pACL            = NULL;
	PSID   psidAdmin       = NULL;

	HANDLE hToken              = NULL;
	HANDLE hImpersonationToken = NULL;

	PRIVILEGE_SET   ps;
	GENERIC_MAPPING GenericMapping;

	PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
	SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;


	const DWORD ACCESS_READ  = 1;
	const DWORD ACCESS_WRITE = 2;

	__try
	{

		/*
		AccessCheck() requires an impersonation token.  We first get a 

		primary
		token and then create a duplicate impersonation token.  The
		impersonation token is not actually assigned to the thread, but is
		used in the call to AccessCheck.  Thus, this function itself never
		impersonates, but does use the identity of the thread.  If the 

		thread
		was impersonating already, this function uses that impersonation 

		context.
		*/
		if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, 

			TRUE, &hToken))
		{
			if (GetLastError() != ERROR_NO_TOKEN)
				__leave;

			if (!OpenProcessToken(GetCurrentProcess(), 

				TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
				__leave;
		}

		if (!DuplicateToken (hToken, SecurityImpersonation, 

			&hImpersonationToken))
			__leave;


		/*
		Create the binary representation of the well-known SID that
		represents the local administrators group.  Then create the 

		security
		descriptor and DACL with an ACE that allows only local admins 

		access.
		After that, perform the access check.  This will determine whether
		the current user is a local admin.
		*/
		if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,
			SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS,
			0, 0, 0, 0, 0, 0, &psidAdmin))
			__leave;

		psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
		if (psdAdmin == NULL)
			__leave;

		if (!InitializeSecurityDescriptor(psdAdmin, 

			SECURITY_DESCRIPTOR_REVISION))
			__leave;

		// Compute size needed for the ACL.
		dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
			GetLengthSid(psidAdmin) - sizeof(DWORD);

		pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
		if (pACL == NULL)
			__leave;

		if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
			__leave;

		dwAccessMask= ACCESS_READ | ACCESS_WRITE;

		if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, 

			psidAdmin))
			__leave;

		if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
			__leave;

		/*
		AccessCheck validates a security descriptor somewhat; set the 

		group
		and owner so that enough of the security descriptor is filled out 

		to
		make AccessCheck happy.
		*/
		SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
		SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);

		if (!IsValidSecurityDescriptor(psdAdmin))
			__leave;

		dwAccessDesired = ACCESS_READ;

		/*
		Initialize GenericMapping structure even though you
		do not use generic rights.
		*/
		GenericMapping.GenericRead    = ACCESS_READ;
		GenericMapping.GenericWrite   = ACCESS_WRITE;
		GenericMapping.GenericExecute = 0;
		GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;

		if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
			&GenericMapping, &ps, &dwStructureSize, &dwStatus,
			&fReturn))
		{
			fReturn = FALSE;
			__leave;
		}
	}
	__finally
	{
		// Clean up.
		if (pACL) LocalFree(pACL);
		if (hImpersonationToken) CloseHandle (hImpersonationToken);
		if (hToken) CloseHandle (hToken);
		if (psdAdmin) LocalFree(psdAdmin);
		if (psidAdmin) FreeSid(psidAdmin);
	}

	return fReturn;
}
Example #16
0
//MailSlot of flush DNS cache Monitor
bool __fastcall FlushDNSMailSlotMonitor(
	void)
{
//System security setting
	std::shared_ptr<SECURITY_ATTRIBUTES> SecurityAttributes(new SECURITY_ATTRIBUTES());
	std::shared_ptr<SECURITY_DESCRIPTOR> SecurityDescriptor(new SECURITY_DESCRIPTOR());
	std::shared_ptr<char> ACL_Buffer(new char[PACKET_MAXSIZE]());
	memset(ACL_Buffer.get(), 0, PACKET_MAXSIZE);
	PSID SID_Value = nullptr;

	InitializeSecurityDescriptor(SecurityDescriptor.get(), SECURITY_DESCRIPTOR_REVISION);
	InitializeAcl((PACL)ACL_Buffer.get(), PACKET_MAXSIZE, ACL_REVISION);
	ConvertStringSidToSidW(SID_ADMINISTRATORS_GROUP, &SID_Value);
	AddAccessAllowedAce((PACL)ACL_Buffer.get(), ACL_REVISION, GENERIC_ALL, SID_Value);
	SetSecurityDescriptorDacl(SecurityDescriptor.get(), true, (PACL)ACL_Buffer.get(), false);
	SecurityAttributes->lpSecurityDescriptor = SecurityDescriptor.get();
	SecurityAttributes->bInheritHandle = true;

//Create mailslot.
	HANDLE hSlot = CreateMailslotW(MAILSLOT_NAME, PACKET_MAXSIZE - 1U, MAILSLOT_WAIT_FOREVER, SecurityAttributes.get());
	if (hSlot == INVALID_HANDLE_VALUE)
	{
		LocalFree(SID_Value);

		PrintError(LOG_ERROR_SYSTEM, L"Create mailslot error", GetLastError(), nullptr, 0);
		return false;
	}

	ACL_Buffer.reset();
	LocalFree(SID_Value);

//Initialization
	BOOL Result = FALSE;
	bool FlushDNS = false;
	DWORD cbMessage = 0, cMessage = 0, cAllMessages = 0, cbRead = 0;
	std::shared_ptr<wchar_t> lpszBuffer(new wchar_t[PACKET_MAXSIZE]());
	wmemset(lpszBuffer.get(), 0, PACKET_MAXSIZE);

//MailSlot Monitor
	for (;;)
	{
		FlushDNS = false;

	//Get mailslot messages.
		Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr);
		if (Result == FALSE)
		{
			PrintError(LOG_ERROR_SYSTEM, L"Get mailslot error", GetLastError(), nullptr, 0);
			
			CloseHandle(hSlot);
			return false;
		}

	//Wait for messages.
		if (cbMessage == MAILSLOT_NO_MESSAGE)
		{
			Sleep(MONITOR_LOOP_INTERVAL_TIME);
			continue;
		}

	//Got messages.
		cAllMessages = cMessage;
		while (cMessage > 0)
		{
			Result = ReadFile(hSlot, lpszBuffer.get(), cbMessage, &cbRead, nullptr);
			if (Result == FALSE)
			{
				PrintError(LOG_ERROR_SYSTEM, L"MailSlot read messages error", GetLastError(), nullptr, 0);
				
				CloseHandle(hSlot);
				return false;
			}

			if (!FlushDNS && memcmp(lpszBuffer.get(), MAILSLOT_MESSAGE_FLUSH_DNS, wcslen(MAILSLOT_MESSAGE_FLUSH_DNS)) == EXIT_SUCCESS)
			{
				FlushDNS = true;
				FlushAllDNSCache();
			}
			memset(lpszBuffer.get(), 0, PACKET_MAXSIZE);

		//Get other mailslot messages.
			Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr);
			if (Result == FALSE)
			{
				PrintError(LOG_ERROR_SYSTEM, L"Get mailslot error", GetLastError(), nullptr, 0);
				
				CloseHandle(hSlot);
				return false;
			}
		}
	}

//Monitor terminated
	CloseHandle(hSlot);
	PrintError(LOG_ERROR_SYSTEM, L"MailSlot module Monitor terminated", 0, nullptr, 0);
	return false;
}
Example #17
0
File: sync.c Project: aragaer/wine
static void test_event(void)
{
    HANDLE handle, handle2;
    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd;
    ACL acl;

    /* no sd */
    handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
    ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
    CloseHandle(handle);

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = &sd;
    sa.bInheritHandle = FALSE;

    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);

    /* blank sd */
    handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
    ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
    CloseHandle(handle);

    /* sd with NULL dacl */
    SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
    handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
    ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
    CloseHandle(handle);

    /* sd with empty dacl */
    InitializeAcl(&acl, sizeof(acl), ACL_REVISION);
    SetSecurityDescriptorDacl(&sd, TRUE, &acl, FALSE);
    handle = CreateEventA(&sa, FALSE, FALSE, __FILE__ ": Test Event");
    ok(handle != NULL, "CreateEventW with blank sd failed with error %d\n", GetLastError());
    CloseHandle(handle);

    /* test case sensitivity */

    SetLastError(0xdeadbeef);
    handle = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
    ok( handle != NULL, "CreateEvent failed with error %u\n", GetLastError());
    ok( GetLastError() == 0, "wrong error %u\n", GetLastError());

    SetLastError(0xdeadbeef);
    handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": Test Event");
    ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
    ok( GetLastError() == ERROR_ALREADY_EXISTS, "wrong error %u\n", GetLastError());
    CloseHandle( handle2 );

    SetLastError(0xdeadbeef);
    handle2 = CreateEventA(NULL, FALSE, FALSE, __FILE__ ": TEST EVENT");
    ok( handle2 != NULL, "CreateEvent failed with error %d\n", GetLastError());
    ok( GetLastError() == 0, "wrong error %u\n", GetLastError());
    CloseHandle( handle2 );

    SetLastError(0xdeadbeef);
    handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": Test Event");
    ok( handle2 != NULL, "OpenEvent failed with error %d\n", GetLastError());
    CloseHandle( handle2 );

    SetLastError(0xdeadbeef);
    handle2 = OpenEventA( EVENT_ALL_ACCESS, FALSE, __FILE__ ": TEST EVENT");
    ok( !handle2, "OpenEvent succeeded\n");
    ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError());

    CloseHandle( handle );
}
Example #18
0
BOOL 
CreateSecurityDescriptor(const char* pUserName, IN OUT SECURITY_DESCRIPTOR * psd)
{
    BOOL  fReturnCode	     = FALSE;
    PSID  psidAdmins	     = NULL;
    PACL  paclKey	     = NULL;
    DWORD cbReferencedDomain = 16;
    DWORD cbSid		     = 128;
    LPSTR lpReferencedDomain = NULL;
    PSID  psidUser	     = NULL;
    SID_NAME_USE sidNameUse;

    SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;

    // Here we're creating a System Identifier (SID) to represent
    // the Admin group.
    if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, 
	SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 
	0, 0, 0, 0, 0, 0, &psidAdmins))
    {
	goto cleanup;
    }

    // Now we'll find the System Identifier which represents
    // the specified user
    if((psidUser = HeapAlloc(GetProcessHeap(), 0, cbSid)) == NULL)
    {
	goto cleanup;
    }
 
    if((lpReferencedDomain = (LPSTR) HeapAlloc(GetProcessHeap(), 0, 
	cbReferencedDomain)) == NULL)
    {
	goto cleanup;
    }

    if (!LookupAccountName(NULL,		// local system
			   pUserName,		// account name
			   psidUser,		// receive SID of the account
			   &cbSid,		// size of the SID
			   lpReferencedDomain,	// buffer to receive user's domain
			   &cbReferencedDomain,	// size of UserDomain buffer
			   &sidNameUse))	// type of the user account
    {
	fReturnCode = FALSE;
	goto cleanup;
    }

    if (!InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION))
    {
       goto cleanup;
    }

    // We want the admin group to own this key.
    if (!SetSecurityDescriptorOwner(psd, psidAdmins, 0))
    {
       goto cleanup;
    }

    // Finally we must allocate and construct the discretionary
    // access control list (DACL) for the key.

    // Note that _alloca allocates memory on the stack frame
    // which will automatically be deallocated when this routine
    // exits.
    //if (!(paclKey = (PACL) _alloca(ACL_BUFFER_SIZE)))
    //{
    //   goto cleanup;
    //}

    if (!(paclKey = (PACL) malloc(ACL_BUFFER_SIZE)))
    {
       goto cleanup;
    }

    if (!InitializeAcl(paclKey, ACL_BUFFER_SIZE, ACL_REVISION))
    {
	goto cleanup;
    }

    // Our DACL will contain two access control entries (ACEs). One which allows
    // members of the Admin group complete access to the key, and one which gives
    // read-only access to everyone.
    if (!AddAccessAllowedAce(paclKey, ACL_REVISION, KEY_ALL_ACCESS, psidAdmins))
    {
       goto cleanup;
    }

    if (!AddAccessAllowedAce(paclKey, ACL_REVISION, KEY_ALL_ACCESS, psidUser))
    {
	goto cleanup;
    }

    if (!IsValidAcl(paclKey))
    {
       goto cleanup;
    }

    // We must bind this DACL to the security descriptor...
    if (!SetSecurityDescriptorDacl(psd, TRUE, paclKey, FALSE))
    {
       goto cleanup;
    }

    if (!IsValidSecurityDescriptor(psd))
    {
       goto cleanup;
    }

    fReturnCode = TRUE;
	
cleanup:

    if (paclKey)
    {
	free(paclKey);
	paclKey = NULL;
    }

    return fReturnCode;
}
Example #19
0
bool CSecRunAsUser::SetObjectPermission(CString strDirFile, DWORD lGrantedAccess){
	USES_CONVERSION;
	if (!m_hADVAPI32_DLL){
		ASSERT ( false );
		return false;
	}
	if ( strDirFile.IsEmpty() )
		return true;

	SID_NAME_USE   snuType;
	TCHAR* szDomain = NULL;
	LPVOID pUserSID = NULL;
	PACL pNewACL = NULL;
	PSECURITY_DESCRIPTOR pSD = NULL;
	BOOL fAPISuccess;
	
	try {
		// get user sid
		DWORD cbDomain = 0;
		DWORD cbUserSID = 0;
		fAPISuccess = LookupAccountName(NULL, EMULEACCOUNT, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);
		if ( (!fAPISuccess) && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
			throw CString(_T("Run as unpriveleged user: Error: LookupAccountName() failed,"));

		pUserSID = MHeapAlloc(cbUserSID);
		if (!pUserSID)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));
		
		szDomain = (TCHAR*)MHeapAlloc(cbDomain * sizeof(TCHAR));
		if (!szDomain)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));

		fAPISuccess = LookupAccountName(NULL, EMULEACCOUNT, pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);

		if (!fAPISuccess)
			throw CString(_T("Run as unpriveleged user: Error: LookupAccountName()2 failed"));

		if (CStringW(T2W(szDomain)) != m_strDomain)
			throw CString(_T("Run as unpriveleged user: Logical Error: Domainname mismatch"));

		// get old ACL
		PACL pOldACL = NULL;
		fAPISuccess = GetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldACL, NULL, &pSD);
		strDirFile.ReleaseBuffer();
		if (fAPISuccess != ERROR_SUCCESS){
			throw CString(_T("Run as unpriveleged user: Error: GetNamedSecurityInfo() failed"));
		}

		// calculate size for new ACL
		ACL_SIZE_INFORMATION AclInfo;
		AclInfo.AceCount = 0; // Assume NULL DACL.
		AclInfo.AclBytesFree = 0;
		AclInfo.AclBytesInUse = sizeof(ACL);

		if (pOldACL != NULL && !GetAclInformation(pOldACL, &AclInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation))  
			throw CString(_T("Run as unpriveleged user: Error: GetAclInformation() failed"));

		// Create new ACL
		DWORD cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pUserSID) - sizeof(DWORD);

		pNewACL = (PACL)MHeapAlloc(cbNewACL);
		if (!pNewACL)
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));

		if (!InitializeAcl(pNewACL, cbNewACL, ACL_REVISION2))
			throw CString(_T("Run as unpriveleged user: Error: Allocating memory failed,"));


		// copy the entries form the old acl into the new one and enter a new ace in the right order
		uint32 newAceIndex = 0;
		uint32 CurrentAceIndex = 0;
		if (AclInfo.AceCount) {
			for (CurrentAceIndex = 0; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) {

					LPVOID pTempAce = NULL;
					if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce))
						throw CString(_T("Run as unpriveleged user: Error: GetAce() failed,"));

					if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
						& INHERITED_ACE)
						break;
					// no multiple entries
					if (EqualSid(pUserSID, &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
						continue;

					if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize))
						throw CString(_T("Run as unpriveleged user: Error: AddAce()1 failed,"));
					newAceIndex++;
			}
		}
		// here we add the actually entry
		if (!AddAccessAllowedAceEx(pNewACL, ACL_REVISION2, CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, lGrantedAccess, pUserSID))
			throw CString(_T("Run as unpriveleged user: Error: AddAccessAllowedAceEx() failed,"));	
		
		// copy the rest
		if (AclInfo.AceCount) {
			for (; CurrentAceIndex < AclInfo.AceCount; CurrentAceIndex++) {

					LPVOID pTempAce = NULL;
					if (!GetAce(pOldACL, CurrentAceIndex, &pTempAce))
						throw CString(_T("Run as unpriveleged user: Error: GetAce()2 failed,"));

					if (!AddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER) pTempAce)->AceSize))
						throw CString(_T("Run as unpriveleged user: Error: AddAce()2 failed,"));
				}
		}

		fAPISuccess = SetNamedSecurityInfo(strDirFile.GetBuffer(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL);
		strDirFile.ReleaseBuffer();
		if (fAPISuccess != ERROR_SUCCESS)
			throw CString(_T("Run as unpriveleged user: Error: SetNamedSecurityInfo() failed,"));
		fAPISuccess = TRUE;
	}
	catch(CString error){
		fAPISuccess = FALSE;
		CGlobalVariable::QueueDebugLogLine(false, error);
	}
	// clean up
	if (pUserSID != NULL)
		MHeapFree(pUserSID);
	if (szDomain != NULL)
		MHeapFree(szDomain);
	if (pNewACL != NULL)
		MHeapFree(pNewACL);
	if (pSD != NULL)
		LocalFree(pSD);

	// finished
	return fAPISuccess!=FALSE;
}
Example #20
0
// https://ru.wikipedia.org/wiki/DACL + https://github.com/hfiref0x/WinObjEx64/tree/master/Source
BOOL AddAllowSidForDevice(PWCHAR wchPath, PSID lpSid, DWORD dwSidLength) {
	OBJECT_ATTRIBUTES ObjAtt;
	RtlZeroMemory(&ObjAtt, sizeof(ObjAtt));

	UNICODE_STRING UserModeDeviceName;

	WCHAR PathBuffer[MAX_PATH] = { 0 };

	wcscpy_s(PathBuffer, L"\\??\\");
	wcscat_s(PathBuffer, wchPath);

	UserModeDeviceName.Buffer = PathBuffer;
	UserModeDeviceName.Length = (USHORT)(wcslen(PathBuffer) * sizeof(WCHAR));
	UserModeDeviceName.MaximumLength = (USHORT)(UserModeDeviceName.Length + sizeof(WCHAR));
	InitializeObjectAttributes(&ObjAtt, &UserModeDeviceName, 0, 0, 0);

	HANDLE hFile;
	IO_STATUS_BLOCK IoStatusBlock;
	NTSTATUS status = ntdll_ZwOpenFile(&hFile, WRITE_DAC | READ_CONTROL, &ObjAtt, &IoStatusBlock, 0, 0);
	if (status != STATUS_SUCCESS) {
		DebugOut("ZwOpenFile(..., %S,...) failed! (status=%x)\n", wchPath, status);
		return FALSE;
	}

	DWORD LastError;
	SECURITY_DESCRIPTOR *lpSd = NULL;	// адрес дескриптора безопасности
	DWORD dwSdLength = 0;				// длина SD
	if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, NULL, dwSdLength, &dwSdLength)) {
		LastError = GetLastError();
		if (LastError == ERROR_INSUFFICIENT_BUFFER) {
			dwSdLength += 1000; // !! FIX_ME
			lpSd = (SECURITY_DESCRIPTOR*)malloc(dwSdLength);
			if (!GetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, lpSd, dwSdLength, &dwSdLength)) {
				DebugOut("GetKernelObjectSecurity[2](...) failed! (LastError=0x%x)\n", GetLastError());
				CloseHandle(hFile);
				return FALSE;
			}
		} else {
			DebugOut("GetKernelObjectSecurity[1](...) failed! (LastError=0x%x)\n", LastError);
			CloseHandle(hFile);
			return FALSE;
		}
	}
	ACL* lpOldDacl;						// указатель на старый DACL
	BOOL bDaclPresent;					// признак присутствия списка DACL
	BOOL bDaclDefaulted;				// признак списка DACL по умолчанию
	if (!GetSecurityDescriptorDacl(lpSd, &bDaclPresent, &lpOldDacl, &bDaclDefaulted)) { // получаем список DACL из дескриптора безопасности
		DebugOut("GetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError());
		CloseHandle(hFile);
		return FALSE;
	}
	DWORD dwDaclLength = lpOldDacl->AclSize + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + dwSidLength; // определяем длину нового DACL
	ACL* lpNewDacl = (ACL*)malloc(dwDaclLength);
	if (!InitializeAcl(lpNewDacl, dwDaclLength, ACL_REVISION)) { // инициализируем новый DACL
		DebugOut("InitializeAcl(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	if (!AddAccessAllowedAce(lpNewDacl, ACL_REVISION,ACCOUNT_ALLOW_RIGHTS, lpSid)) { // добавляем новый элемент в новый DACL
		DebugOut("AddAccessAllowedAce(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	LPVOID lpAce;						// указатель на элемент ACE
	if (!GetAce(lpOldDacl, 0, &lpAce)) { // получаем адрес первого ACE в старом списке DACL
		DebugOut("GetAce(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	// переписываем элементы из старого DACL в новый DACL
	if (bDaclPresent) {
		if (!AddAce(lpNewDacl, ACL_REVISION, MAXDWORD, lpAce, lpOldDacl->AclSize - sizeof(ACL))) {
			DebugOut("AddAce(...) failed! (LastError=0x%x)\n", GetLastError());
			free(lpNewDacl);
			CloseHandle(hFile);
			return FALSE;
		}
	}
	if (!IsValidAcl(lpNewDacl)) { // проверяем достоверность DACL
		DebugOut("IsValidAcl(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	SECURITY_DESCRIPTOR sdAbsoluteSd;	// абсолютный формат SD
	if (!InitializeSecurityDescriptor(&sdAbsoluteSd, SECURITY_DESCRIPTOR_REVISION)) { // создаем новый дескриптор безопасности в абсолютной форме
		DebugOut("InitializeSecurityDescriptor(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	if (!SetSecurityDescriptorDacl(&sdAbsoluteSd, TRUE, lpNewDacl, FALSE)) { // устанавливаем DACL  в новый дескриптор безопасности
		DebugOut("SetSecurityDescriptorDacl(...) failed! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}

	// проверяем структуру дескриптора безопасности
	if (!IsValidSecurityDescriptor(&sdAbsoluteSd)) {
		DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	
	if (!SetKernelObjectSecurity(hFile, DACL_SECURITY_INFORMATION, &sdAbsoluteSd)) { // устанавливаем новый дескриптор безопасности
		DebugOut("IsValidSecurityDescriptor(...) == FALSE! (LastError=0x%x)\n", GetLastError());
		free(lpNewDacl);
		CloseHandle(hFile);
		return FALSE;
	}
	free(lpNewDacl);
	CloseHandle(hFile);

	DebugOut("ACL Rules applyed to \"%S\"\n", PathBuffer);

	return TRUE;
}
Example #21
0
// Initialize the User Conversation Interface.
DWORD InitConvInterface ( VOID )
{
	HANDLE	hThread, hThreadTcpip;
	DWORD	dwThreadID, dwThreadIDTcpip;
	PSID	pOwnerSid = NULL, pGroupSid = NULL;
    BOOL	fSuccess = TRUE;
    PACL	pAcl = NULL;
    DWORD	cbAcl;
	DWORD	dwRetCode;
	PSID	pSystemSid = NULL, pAnonymousSid = NULL, pInteractiveSid = NULL;

    __try {
#ifndef TREESVR_STANDALONE
		pOwnerSid = GetUserSid();
		if( pOwnerSid == NULL )
			__leave;
/*
		fSuccess = GetAccountSid( NULL, "TreeServer Users", &pGroupSid );
		if ( !fSuccess )
			__leave;
*/
		pGroupSid = CreateWorldSid();
		if( pGroupSid == NULL )
			__leave;

		pSystemSid = CreateSystemSid();
		if( pSystemSid == NULL )
			__leave;

		pAnonymousSid = CreateAnonymousSid();
		if( pAnonymousSid == NULL )
			__leave;

		pInteractiveSid = CreateInteractiveSid();
		if( pInteractiveSid == NULL )
			__leave;

		cbAcl = GetLengthSid( pOwnerSid ) + GetLengthSid( pGroupSid ) + 
			GetLengthSid( pSystemSid ) + GetLengthSid( pAnonymousSid ) + GetLengthSid( pInteractiveSid ) +
			sizeof(ACL) + (5 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)));

		pAcl = (PACL) HeapAlloc(GetProcessHeap(), 0, cbAcl);
		if (NULL == pAcl)
			__leave;

		fSuccess = InitializeAcl(pAcl,
			    cbAcl,
			    ACL_REVISION);
		if (FALSE == fSuccess)
			__leave;

		fSuccess = AddAccessAllowedAce(pAcl,
			    ACL_REVISION,
			    GENERIC_ALL,
			    pOwnerSid);
		if (FALSE == fSuccess)
			__leave;

		fSuccess = AddAccessAllowedAce(pAcl,
			    ACL_REVISION,
			    GENERIC_ALL,//GENERIC_READ|GENERIC_WRITE,
			    pGroupSid);
		if (FALSE == fSuccess) 
			__leave;

		fSuccess = AddAccessAllowedAce(pAcl,
			    ACL_REVISION,
			    GENERIC_ALL,
			    pSystemSid);
		if (FALSE == fSuccess) 
			__leave;

		fSuccess = AddAccessAllowedAce(pAcl,
			    ACL_REVISION,
			    GENERIC_ALL,
			    pInteractiveSid);
		if (FALSE == fSuccess) 
			__leave;

		fSuccess = AddAccessAllowedAce(pAcl,
			    ACL_REVISION,
			    GENERIC_ALL,
			    pAnonymousSid);
		if (FALSE == fSuccess) 
			__leave;

		InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION );

		fSuccess = SetSecurityDescriptorDacl(&sd,
				TRUE,
				pAcl,
				FALSE);
		if (FALSE == fSuccess) 
			__leave;

		fSuccess =  SetSecurityDescriptorOwner(
				&sd,
				pOwnerSid,
				FALSE );  
	    if ( !fSuccess )
			__leave;

		fSuccess =  SetSecurityDescriptorGroup(
				&sd,
				pGroupSid,
				FALSE );  

	    if ( !fSuccess ) 
			__leave;

		sa.nLength = sizeof( SECURITY_ATTRIBUTES );
		sa.lpSecurityDescriptor = (LPVOID)&sd;
		sa.bInheritHandle = FALSE;

#endif
		// Create the NamedPipe server thread, Process the user's connection.
		hThread = CreateThread( NULL, 
				0,
				(LPTHREAD_START_ROUTINE)PipeSelectConnectThread,
				(LPVOID)NULL,
				0,
				&dwThreadID );

		// If operation not completed, return the system error code.
		if( hThread == NULL )
		{
			fSuccess = FALSE;
			__leave;
		}

#ifndef TREESVR_STANDALONE
		hThreadTcpip = CreateThread( NULL, 
				0,
				(LPTHREAD_START_ROUTINE)TcpipSelectConnectThread,
				(LPVOID)NULL,
				0,
				&dwThreadIDTcpip );

		// If operation not completed, return the system error code.
		if( hThreadTcpip == NULL )
		{
			fSuccess = FALSE;
			__leave;
		}
#endif

	}
	__finally {
		if( fSuccess ) {
			// Set the thread Prority Class.
			SetThreadPriority( hThread, THREAD_PRIORITY_ABOVE_NORMAL ); 

			SystemResInfo.hConvThread = hThread;
			SystemResInfo.dwConvThreadId = dwThreadID;

#ifndef TREESVR_STANDALONE
			// Set the thread Prority Class.
			SetThreadPriority( hThreadTcpip, THREAD_PRIORITY_ABOVE_NORMAL ); 

			SystemResInfo.hConvThreadTcpip = hThreadTcpip;
			SystemResInfo.dwConvThreadIdTcpip = dwThreadIDTcpip;
#endif

			dwRetCode = TERR_SUCCESS;
		}
		else {
			if( hThread != NULL ) {
				CloseHandle( hThread );
			}

			dwRetCode = GetLastError();

			if( pOwnerSid )
		        HeapFree( GetProcessHeap(), 0, pOwnerSid );
			if( pGroupSid )
		        HeapFree( GetProcessHeap(), 0, pGroupSid );
			if( pSystemSid )
		        HeapFree( GetProcessHeap(), 0, pSystemSid );
			if( pInteractiveSid )
		        HeapFree( GetProcessHeap(), 0, pInteractiveSid );
			if( pAnonymousSid )
		        HeapFree( GetProcessHeap(), 0, pAnonymousSid );
			if( pAcl )
		        HeapFree( GetProcessHeap(), 0, pAcl );
		}
	}
	
	return dwRetCode;
}
BOOL AddAceToWindowStation(HWINSTA hwinsta, PSID psid)
{
   ACCESS_ALLOWED_ACE   *pace = NULL;
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl;
   PACL                 pNewAcl = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   __try
   {
      // Obtain the DACL for the window station.

      if (!GetUserObjectSecurity(
             hwinsta,
             &si,
             psd,
             dwSidSize,
             &dwSdSizeNeeded)
      )
      if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
      {
         psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psd == NULL)
            __leave;

         psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSdSizeNeeded);

         if (psdNew == NULL)
            __leave;

         dwSidSize = dwSdSizeNeeded;

         if (!GetUserObjectSecurity(
               hwinsta,
               &si,
               psd,
               dwSidSize,
               &dwSdSizeNeeded)
         )
            __leave;
      }
      else
         __leave;

      // Create a new DACL.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         __leave;

      // Get the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         __leave;

      // Initialize the ACL.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if the DACL is not NULL.

      if (pacl != NULL)
      {
         // get the file ACL size info
         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            __leave;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            (2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
            (2*sizeof(DWORD));

      // Allocate memory for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         __leave;

      // Initialize the new DACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         __leave;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  __leave;

               // Add the ACE to the new ACL.
               if (!AddAce(
                     pNewAcl,
                     ACL_REVISION,
                     MAXDWORD,
                     pTempAce,
                    ((PACE_HEADER)pTempAce)->AceSize)
               )
                  __leave;
            }
         }
      }

      // Add the first ACE to the window station.

      pace = (ACCESS_ALLOWED_ACE *)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) -
                  sizeof(DWORD));

      if (pace == NULL)
         __leave;

      pace->Header.AceType  = ACCESS_ALLOWED_ACE_TYPE;
      pace->Header.AceFlags = CONTAINER_INHERIT_ACE |
                   INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
      pace->Header.AceSize  = LOWORD(sizeof(ACCESS_ALLOWED_ACE) +
                   GetLengthSid(psid) - sizeof(DWORD));
      pace->Mask            = GENERIC_ACCESS;

      if (!CopySid(GetLengthSid(psid), &pace->SidStart, psid))
         __leave;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         __leave;

      // Add the second ACE to the window station.

      pace->Header.AceFlags = NO_PROPAGATE_INHERIT_ACE;
      pace->Mask            = WINSTA_ALL;

      if (!AddAce(
            pNewAcl,
            ACL_REVISION,
            MAXDWORD,
            (LPVOID)pace,
            pace->Header.AceSize)
      )
         __leave;

      // Set a new DACL for the security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         __leave;

      // Set the new security descriptor for the window station.

      if (!SetUserObjectSecurity(hwinsta, &si, psdNew))
         __leave;

      // Indicate success.

      bSuccess = TRUE;
   }
   __finally
   {
      // Free the allocated buffers.

      if (pace != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pace);

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;

}
// Basically Microsoft 118626
// Needed for vista as it fakes the admin rights on the registry and screws everything up
bool CGlobalSettings::isAdmin()
{
	static int isAd = 0;
	bool   fReturn         = false;
	DWORD  dwStatus;
	DWORD  dwAccessMask;
	DWORD  dwAccessDesired;
	DWORD  dwACLSize;
	DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
	PACL   pACL            = NULL;
	PSID   psidAdmin       = NULL;

	HANDLE hToken              = NULL;
	HANDLE hImpersonationToken = NULL;

	PRIVILEGE_SET   ps;
	GENERIC_MAPPING GenericMapping;

	PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
	SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;

	if(isAd)
		return isAd>0?true:false;

	__try
	{
		if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken))
		{
			if (GetLastError() != ERROR_NO_TOKEN)
				__leave;

			if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))
				__leave;
		}

		if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken))
			__leave;


		if (!AllocateAndInitializeSid(&SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0, 0, 0, 0, 0, 0, &psidAdmin))
			__leave;

		psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
		if (psdAdmin == NULL)
			__leave;

		if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))
			__leave;

		// Compute size needed for the ACL.
		dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psidAdmin) - sizeof(DWORD);

		pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
		if (pACL == NULL)
			__leave;

		if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))
			__leave;

		dwAccessMask = ACCESS_READ | ACCESS_WRITE;

		if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin))
			__leave;

		if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))
			__leave;

		SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);
		SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);

		if (!IsValidSecurityDescriptor(psdAdmin))
			__leave;

		dwAccessDesired = ACCESS_READ;

		GenericMapping.GenericRead    = ACCESS_READ;
		GenericMapping.GenericWrite   = ACCESS_WRITE;
		GenericMapping.GenericExecute = 0;
		GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;

		BOOL bRet;
		if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,
						&GenericMapping, &ps, &dwStructureSize, &dwStatus,
						&bRet))
			__leave;
		fReturn = bRet?true:false;
	}
	__finally
	{
		// Clean up.
		if (pACL) LocalFree(pACL);
		if (psdAdmin) LocalFree(psdAdmin);
		if (psidAdmin) FreeSid(psidAdmin);
		if (hImpersonationToken) CloseHandle (hImpersonationToken);
		if (hToken) CloseHandle (hToken);
	}

	isAd=fReturn?1:-1;

	return fReturn;
}
BOOL AddAceToDesktop(HDESK hdesk, PSID psid)
{
   ACL_SIZE_INFORMATION aclSizeInfo;
   BOOL                 bDaclExist;
   BOOL                 bDaclPresent;
   BOOL                 bSuccess = FALSE;
   DWORD                dwNewAclSize;
   DWORD                dwSidSize = 0;
   DWORD                dwSdSizeNeeded;
   PACL                 pacl;
   PACL                 pNewAcl = NULL;
   PSECURITY_DESCRIPTOR psd = NULL;
   PSECURITY_DESCRIPTOR psdNew = NULL;
   PVOID                pTempAce;
   SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
   unsigned int         i;

   __try
   {
      // Obtain the security descriptor for the desktop object.

      if (!GetUserObjectSecurity(
            hdesk,
            &si,
            psd,
            dwSidSize,
            &dwSdSizeNeeded))
      {
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
         {
            psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded );

            if (psd == NULL)
               __leave;

            psdNew = (PSECURITY_DESCRIPTOR)HeapAlloc(
                  GetProcessHeap(),
                  HEAP_ZERO_MEMORY,
                  dwSdSizeNeeded);

            if (psdNew == NULL)
               __leave;

            dwSidSize = dwSdSizeNeeded;

            if (!GetUserObjectSecurity(
                  hdesk,
                  &si,
                  psd,
                  dwSidSize,
                  &dwSdSizeNeeded)
            )
               __leave;
         }
         else
            __leave;
      }

      // Create a new security descriptor.

      if (!InitializeSecurityDescriptor(
            psdNew,
            SECURITY_DESCRIPTOR_REVISION)
      )
         __leave;

      // Obtain the DACL from the security descriptor.

      if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
      )
         __leave;

      // Initialize.

      ZeroMemory(&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION));
      aclSizeInfo.AclBytesInUse = sizeof(ACL);

      // Call only if NULL DACL.

      if (pacl != NULL)
      {
         // Determine the size of the ACL information.

         if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
         )
            __leave;
      }

      // Compute the size of the new ACL.

      dwNewAclSize = aclSizeInfo.AclBytesInUse +
            sizeof(ACCESS_ALLOWED_ACE) +
            GetLengthSid(psid) - sizeof(DWORD);

      // Allocate buffer for the new ACL.

      pNewAcl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

      if (pNewAcl == NULL)
         __leave;

      // Initialize the new ACL.

      if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION))
         __leave;

      // If DACL is present, copy it to a new DACL.

      if (bDaclPresent)
      {
         // Copy the ACEs to the new ACL.
         if (aclSizeInfo.AceCount)
         {
            for (i=0; i < aclSizeInfo.AceCount; i++)
            {
               // Get an ACE.
               if (!GetAce(pacl, i, &pTempAce))
                  __leave;

               // Add the ACE to the new ACL.
               if (!AddAce(
                  pNewAcl,
                  ACL_REVISION,
                  MAXDWORD,
                  pTempAce,
                  ((PACE_HEADER)pTempAce)->AceSize)
               )
                  __leave;
            }
         }
      }

      // Add ACE to the DACL.

      if (!AddAccessAllowedAce(
            pNewAcl,
            ACL_REVISION,
            DESKTOP_ALL,
            psid)
      )
         __leave;

      // Set new DACL to the new security descriptor.

      if (!SetSecurityDescriptorDacl(
            psdNew,
            TRUE,
            pNewAcl,
            FALSE)
      )
         __leave;

      // Set the new security descriptor for the desktop object.

      if (!SetUserObjectSecurity(hdesk, &si, psdNew))
         __leave;

      // Indicate success.

      bSuccess = TRUE;
   }
   __finally
   {
      // Free buffers.

      if (pNewAcl != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);

      if (psd != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psd);

      if (psdNew != NULL)
         HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew);
   }

   return bSuccess;
}
Example #25
0
isc_result_t
NTFS_Access_Control(const char *filename, const char *user, int access,
		    isc_boolean_t isdir) {
	SECURITY_DESCRIPTOR sd;
	BYTE aclBuffer[1024];
	PACL pacl=(PACL)&aclBuffer;
	BYTE sidBuffer[100];
	PSID psid=(PSID) &sidBuffer;
	DWORD sidBufferSize = sizeof(sidBuffer);
	BYTE adminSidBuffer[100];
	PSID padminsid=(PSID) &adminSidBuffer;
	DWORD adminSidBufferSize = sizeof(adminSidBuffer);
	BYTE otherSidBuffer[100];
	PSID pothersid=(PSID) &otherSidBuffer;
	DWORD otherSidBufferSize = sizeof(otherSidBuffer);
	char domainBuffer[100];
	DWORD domainBufferSize = sizeof(domainBuffer);
	SID_NAME_USE snu;
	int errval;
	DWORD NTFSbits;
	int caccess;


	/* Initialize an ACL */
	if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
		return (ISC_R_NOPERM);
	if (!InitializeAcl(pacl, sizeof(aclBuffer), ACL_REVISION))
		return (ISC_R_NOPERM);
	if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer,
			  &domainBufferSize, &snu))
		return (ISC_R_NOPERM);
	domainBufferSize = sizeof(domainBuffer);
	if (!LookupAccountName(0, "Administrators", padminsid,
		&adminSidBufferSize, domainBuffer, &domainBufferSize, &snu)) {
		errval = GetLastError();
		return (ISC_R_NOPERM);
	}
	domainBufferSize = sizeof(domainBuffer);
	if (!LookupAccountName(0, "Everyone", pothersid,
		&otherSidBufferSize, domainBuffer, &domainBufferSize, &snu)) {
		errval = GetLastError();
		return (ISC_R_NOPERM);
	}

	caccess = access;
	/* Owner check */

	NTFSbits = 0;
	if (caccess & ISC_FSACCESS_READ)
		NTFSbits |= FILE_GENERIC_READ;
	if (caccess & ISC_FSACCESS_WRITE)
		NTFSbits |= FILE_GENERIC_WRITE;
	if (caccess & ISC_FSACCESS_EXECUTE)
		NTFSbits |= FILE_GENERIC_EXECUTE;

	/* For directories check the directory-specific bits */
	if (isdir == ISC_TRUE) {
		if (caccess & ISC_FSACCESS_CREATECHILD)
			NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE;
		if (caccess & ISC_FSACCESS_DELETECHILD)
			NTFSbits |= FILE_DELETE_CHILD;
		if (caccess & ISC_FSACCESS_LISTDIRECTORY)
			NTFSbits |= FILE_LIST_DIRECTORY;
		if (caccess & ISC_FSACCESS_ACCESSCHILD)
			NTFSbits |= FILE_TRAVERSE;
	}

	if (NTFSbits == (FILE_GENERIC_READ | FILE_GENERIC_WRITE
		     | FILE_GENERIC_EXECUTE))
		     NTFSbits |= FILE_ALL_ACCESS;
	/*
	 * Owner and Administrator also get STANDARD_RIGHTS_ALL
	 * to ensure that they have full control
	 */

	NTFSbits |= STANDARD_RIGHTS_ALL;

	/* Add the ACE to the ACL */
	if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, psid))
		return (ISC_R_NOPERM);
	if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, padminsid))
		return (ISC_R_NOPERM);

	/*
	 * Group is ignored since we can be in multiple groups or no group
	 * and its meaning is not clear on Win32
	 */

	caccess = caccess >> STEP;

	/*
	 * Other check.  We translate this to be the same as Everyone
	 */

	caccess = caccess >> STEP;

	NTFSbits = 0;
	if (caccess & ISC_FSACCESS_READ)
		NTFSbits |= FILE_GENERIC_READ;
	if (caccess & ISC_FSACCESS_WRITE)
		NTFSbits |= FILE_GENERIC_WRITE;
	if (caccess & ISC_FSACCESS_EXECUTE)
		NTFSbits |= FILE_GENERIC_EXECUTE;

	/* For directories check the directory-specific bits */
	if (isdir == TRUE) {
		if (caccess & ISC_FSACCESS_CREATECHILD)
			NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE;
		if (caccess & ISC_FSACCESS_DELETECHILD)
			NTFSbits |= FILE_DELETE_CHILD;
		if (caccess & ISC_FSACCESS_LISTDIRECTORY)
			NTFSbits |= FILE_LIST_DIRECTORY;
		if (caccess & ISC_FSACCESS_ACCESSCHILD)
			NTFSbits |= FILE_TRAVERSE;
	}
	/* Add the ACE to the ACL */
	if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits,
				 pothersid))
		return (ISC_R_NOPERM);

	if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE))
		return (ISC_R_NOPERM);
	if (!SetFileSecurity(filename, DACL_SECURITY_INFORMATION, &sd)) {
		return (ISC_R_NOPERM);
	}

	return(ISC_R_SUCCESS);
}
int my_security_attr_create(SECURITY_ATTRIBUTES **psa, const char **perror,
                            DWORD owner_rights, DWORD everyone_rights)
{
    /* Top-level SID authority */
    SID_IDENTIFIER_AUTHORITY world_auth= SECURITY_WORLD_SID_AUTHORITY;
    PSID everyone_sid= 0;
    HANDLE htoken= 0;
    SECURITY_ATTRIBUTES *sa= 0;
    PACL dacl= 0;
    DWORD owner_token_length, dacl_length;
    SECURITY_DESCRIPTOR *sd;
    PTOKEN_USER owner_token;
    PSID owner_sid;
    My_security_attr *attr;

    if (! is_nt())
    {
        *psa= 0;
        return 0;
    }

    /*
      Get SID of Everyone group. Easier to retrieve all SIDs each time
      this function is called than worry about thread safety.
    */
    if (! AllocateAndInitializeSid(&world_auth, 1, SECURITY_WORLD_RID,
                                   0, 0, 0, 0, 0, 0, 0, &everyone_sid))
    {
        *perror= "Failed to retrieve the SID of Everyone group";
        goto error;
    }

    /*
      Get SID of the owner. Using GetSecurityInfo this task can be done
      in just one call instead of five, but GetSecurityInfo declared in
      aclapi.h, so I hesitate to use it.
      SIC: OpenThreadToken works only if there is an active impersonation
      token, hence OpenProcessToken is used.
    */
    if (! OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &htoken))
    {
        *perror= "Failed to retrieve thread access token";
        goto error;
    }
    GetTokenInformation(htoken, TokenUser, 0, 0, &owner_token_length);

    if (! my_multi_malloc(key_memory_win_SECURITY_ATTRIBUTES,
                          MYF(MY_WME),
                          &sa, ALIGN_SIZE(sizeof(SECURITY_ATTRIBUTES)) +
                          sizeof(My_security_attr),
                          &sd, sizeof(SECURITY_DESCRIPTOR),
                          &owner_token, owner_token_length,
                          0))
    {
        *perror= "Failed to allocate memory for SECURITY_ATTRIBUTES";
        goto error;
    }
    memset(owner_token, 0, owner_token_length);
    if (! GetTokenInformation(htoken, TokenUser, owner_token,
                              owner_token_length, &owner_token_length))
    {
        *perror= "GetTokenInformation failed";
        goto error;
    }
    owner_sid= owner_token->User.Sid;

    if (! IsValidSid(owner_sid))
    {
        *perror= "IsValidSid failed";
        goto error;
    }

    /* Calculate the amount of memory that must be allocated for the DACL */
    dacl_length= sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)-sizeof(DWORD)) * 2 +
                 GetLengthSid(everyone_sid) + GetLengthSid(owner_sid);

    /* Create an ACL */
    if (! (dacl= (PACL) my_malloc(key_memory_win_PACL,
                                  dacl_length, MYF(MY_ZEROFILL|MY_WME))))
    {
        *perror= "Failed to allocate memory for DACL";
        goto error;
    }
    if (! InitializeAcl(dacl, dacl_length, ACL_REVISION))
    {
        *perror= "Failed to initialize DACL";
        goto error;
    }
    if (! AddAccessAllowedAce(dacl, ACL_REVISION, everyone_rights, everyone_sid))
    {
        *perror= "Failed to set up DACL";
        goto error;
    }
    if (! AddAccessAllowedAce(dacl, ACL_REVISION, owner_rights, owner_sid))
    {
        *perror= "Failed to set up DACL";
        goto error;
    }
    if (! InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION))
    {
        *perror= "Could not initialize security descriptor";
        goto error;
    }
    if (! SetSecurityDescriptorDacl(sd, TRUE, dacl, FALSE))
    {
        *perror= "Failed to install DACL";
        goto error;
    }

    sa->nLength= sizeof(*sa);
    sa->bInheritHandle= TRUE;
    sa->lpSecurityDescriptor= sd;
    /* Save pointers to everyone_sid and dacl to be able to clean them up */
    attr= (My_security_attr*) (((char*) sa) + ALIGN_SIZE(sizeof(*sa)));
    attr->everyone_sid= everyone_sid;
    attr->dacl= dacl;
    *psa= sa;

    CloseHandle(htoken);
    return 0;
error:
    if (everyone_sid)
        FreeSid(everyone_sid);
    if (htoken)
        CloseHandle(htoken);
    my_free(sa);
    my_free(dacl);
    *psa= 0;
    return 1;
}
Example #27
0
//MailSlot of flush DNS cache Monitor
bool __fastcall FlushDNSMailSlotMonitor(
	void)
{
//System security setting
	auto SecurityAttributes = std::make_shared<SECURITY_ATTRIBUTES>();
	auto SecurityDescriptor = std::make_shared<SECURITY_DESCRIPTOR>();
	std::shared_ptr<char> ACL_Buffer(new char[FILE_BUFFER_SIZE]());
	memset(ACL_Buffer.get(), 0, FILE_BUFFER_SIZE);
	PSID SID_Value = nullptr;

	InitializeSecurityDescriptor(SecurityDescriptor.get(), SECURITY_DESCRIPTOR_REVISION);
	InitializeAcl((PACL)ACL_Buffer.get(), FILE_BUFFER_SIZE, ACL_REVISION);
	ConvertStringSidToSidW(SID_ADMINISTRATORS_GROUP, &SID_Value);
	AddAccessAllowedAce((PACL)ACL_Buffer.get(), ACL_REVISION, GENERIC_ALL, SID_Value);
	SetSecurityDescriptorDacl(SecurityDescriptor.get(), true, (PACL)ACL_Buffer.get(), false);
	SecurityAttributes->lpSecurityDescriptor = SecurityDescriptor.get();
	SecurityAttributes->bInheritHandle = true;

//Create mailslot.
	HANDLE hSlot = CreateMailslotW(MAILSLOT_NAME, FILE_BUFFER_SIZE - 1U, MAILSLOT_WAIT_FOREVER, SecurityAttributes.get());
	if (hSlot == INVALID_HANDLE_VALUE)
	{
		LocalFree(SID_Value);

		PrintError(LOG_ERROR_SYSTEM, L"Create mailslot error", GetLastError(), nullptr, 0);
		return false;
	}

	ACL_Buffer.reset();
	LocalFree(SID_Value);

//Initialization
/* Old version(2016-01-17)
	bool FlushDNS = false;
	DWORD cbMessage = 0, cMessage = 0, cbRead = 0;
*/
	std::shared_ptr<wchar_t> lpszBuffer(new wchar_t[FILE_BUFFER_SIZE]());
	wmemset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);
	DWORD cbMessage = 0;
	BOOL Result = 0;

//MailSlot monitor
/* Old version(2016-01-17)
	for (;;)
	{
		cbMessage = 0;
		cMessage = 0;

	//Get mailslot messages.
		Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr);
		if (Result == FALSE)
		{
			PrintError(LOG_ERROR_SYSTEM, L"Mailslot Monitor initialization error", GetLastError(), nullptr, 0);
			
			CloseHandle(hSlot);
			return false;
		}

	//Wait for messages.
		if (cbMessage == MAILSLOT_NO_MESSAGE)
		{
			Sleep(LOOP_INTERVAL_TIME_MONITOR);
			continue;
		}

	//Got messages.
		FlushDNS = false;
		while (cMessage > 0)
		{
			Result = ReadFile(hSlot, lpszBuffer.get(), cbMessage, &cbRead, nullptr);
			if (Result == FALSE)
			{
				PrintError(LOG_ERROR_SYSTEM, L"MailSlot read messages error", GetLastError(), nullptr, 0);
				
				CloseHandle(hSlot);
				return false;
			}

			if (!FlushDNS && memcmp(lpszBuffer.get(), MAILSLOT_MESSAGE_FLUSH_DNS, wcslen(MAILSLOT_MESSAGE_FLUSH_DNS)) == 0)
			{
				FlushDNS = true;
				FlushAllDNSCache();
			}
			memset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);

		//Get other mailslot messages.
			Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr);
			if (Result == FALSE)
			{
				PrintError(LOG_ERROR_SYSTEM, L"Mailslot Monitor initialization error", GetLastError(), nullptr, 0);
				
				CloseHandle(hSlot);
				return false;
			}
		}

		Sleep(LOOP_INTERVAL_TIME_MONITOR);
	}
*/
	for (;;)
	{
		Sleep(LOOP_INTERVAL_TIME_NO_DELAY);

	//Reset parameters.
		wmemset(lpszBuffer.get(), 0, FILE_BUFFER_SIZE);
		cbMessage = 0;

	//Read message from mailslot.
		Result = ReadFile(hSlot, lpszBuffer.get(), FILE_BUFFER_SIZE, &cbMessage, nullptr);
		if (Result == FALSE)
		{
			PrintError(LOG_ERROR_SYSTEM, L"MailSlot read messages error", GetLastError(), nullptr, 0);

			CloseHandle(hSlot);
			return false;
		}
		else if (memcmp(lpszBuffer.get(), MAILSLOT_MESSAGE_FLUSH_DNS, wcslen(MAILSLOT_MESSAGE_FLUSH_DNS) * sizeof(wchar_t)) == 0)
		{
			FlushAllDNSCache();
		}
		else {
			Sleep(LOOP_INTERVAL_TIME_MONITOR);
		}
	}

//Monitor terminated
	CloseHandle(hSlot);
	PrintError(LOG_ERROR_SYSTEM, L"MailSlot module Monitor terminated", 0, nullptr, 0);
	return false;
}
Example #28
0
PSECURITY_DESCRIPTOR
CreateDefaultSecurityDescriptor(VOID)
{
    PSID LocalSystemSid = NULL;
    PSID AdministratorsSid = NULL;
    PSID EveryoneSid = NULL;
    PACL Dacl;
    DWORD DaclSize;
    PSECURITY_DESCRIPTOR pSD = NULL;

    /* create the SYSTEM, Administrators and Everyone SIDs */
    if (!AllocateAndInitializeSid(&LocalSystemAuthority,
                                  1,
                                  SECURITY_LOCAL_SYSTEM_RID,
                                  0,
                                  0,
                                  0,
                                  0,
                                  0,
                                  0,
                                  0,
                                  &LocalSystemSid) ||
        !AllocateAndInitializeSid(&LocalSystemAuthority,
                                  2,
                                  SECURITY_BUILTIN_DOMAIN_RID,
                                  DOMAIN_ALIAS_RID_ADMINS,
                                  0,
                                  0,
                                  0,
                                  0,
                                  0,
                                  0,
                                  &AdministratorsSid) ||
        !AllocateAndInitializeSid(&WorldAuthority,
                                  1,
                                  SECURITY_WORLD_RID,
                                  0,
                                  0,
                                  0,
                                  0,
                                  0,
                                  0,
                                  0,
                                  &EveryoneSid))
    {
        DPRINT1("Failed initializing the SIDs for the default security descriptor (0x%p, 0x%p, 0x%p)\n",
                LocalSystemSid, AdministratorsSid, EveryoneSid);
        goto Cleanup;
    }

    /* allocate the security descriptor and DACL */
    DaclSize = sizeof(ACL) +
               ((GetLengthSid(LocalSystemSid) +
                 GetLengthSid(AdministratorsSid) +
                 GetLengthSid(EveryoneSid)) +
                (3 * FIELD_OFFSET(ACCESS_ALLOWED_ACE,
                                  SidStart)));

    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED,
                                           (SIZE_T)DaclSize + sizeof(SECURITY_DESCRIPTOR));
    if (pSD == NULL)
    {
        DPRINT1("Failed to allocate the default security descriptor and ACL\n");
        goto Cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD,
                                      SECURITY_DESCRIPTOR_REVISION))
    {
        DPRINT1("Failed to initialize the default security descriptor\n");
        goto Cleanup;
    }

    /* initialize and build the DACL */
    Dacl = (PACL)((ULONG_PTR)pSD + sizeof(SECURITY_DESCRIPTOR));
    if (!InitializeAcl(Dacl,
                       (DWORD)DaclSize,
                       ACL_REVISION))
    {
        DPRINT1("Failed to initialize the DACL of the default security descriptor\n");
        goto Cleanup;
    }

    /* add the SYSTEM Ace */
    if (!AddAccessAllowedAce(Dacl,
                             ACL_REVISION,
                             GENERIC_ALL,
                             LocalSystemSid))
    {
        DPRINT1("Failed to add the SYSTEM ACE\n");
        goto Cleanup;
    }

    /* add the Administrators Ace */
    if (!AddAccessAllowedAce(Dacl,
                             ACL_REVISION,
                             GENERIC_ALL,
                             AdministratorsSid))
    {
        DPRINT1("Failed to add the Administrators ACE\n");
        goto Cleanup;
    }

    /* add the Everyone Ace */
    if (!AddAccessAllowedAce(Dacl,
                             ACL_REVISION,
                             GENERIC_EXECUTE,
                             EveryoneSid))
    {
        DPRINT1("Failed to add the Everyone ACE\n");
        goto Cleanup;
    }

    /* set the DACL */
    if (!SetSecurityDescriptorDacl(pSD,
                                   TRUE,
                                   Dacl,
                                   FALSE))
    {
        DPRINT1("Failed to set the DACL of the default security descriptor\n");

Cleanup:
        if (pSD != NULL)
        {
            LocalFree((HLOCAL)pSD);
            pSD = NULL;
        }
    }

    if (LocalSystemSid != NULL)
    {
        FreeSid(LocalSystemSid);
    }
    if (AdministratorsSid != NULL)
    {
        FreeSid(AdministratorsSid);
    }
    if (EveryoneSid != NULL)
    {
        FreeSid(EveryoneSid);
    }

    return pSD;
}
Example #29
0
BOOL
CreateWindowStationAndDesktops(
    IN OUT PWLSESSION Session)
{
    BYTE LocalSystemBuffer[SECURITY_MAX_SID_SIZE];
    BYTE InteractiveBuffer[SECURITY_MAX_SID_SIZE];
    PSID pLocalSystemSid = (PSID)&LocalSystemBuffer;
    PSID pInteractiveSid = (PSID)InteractiveBuffer;
    DWORD SidSize, AclSize;
    PACL pDefaultAcl = NULL;
    PACL pUserDesktopAcl = NULL;
    SECURITY_DESCRIPTOR DefaultSecurityDescriptor;
    SECURITY_ATTRIBUTES DefaultSecurity;
    SECURITY_DESCRIPTOR UserDesktopSecurityDescriptor;
    SECURITY_ATTRIBUTES UserDesktopSecurity;
    BOOL ret = FALSE;

    /*
     * Prepare information for ACLs we will apply
     */
    SidSize = SECURITY_MAX_SID_SIZE;
    if (!CreateWellKnownSid(WinLocalSystemSid, NULL, pLocalSystemSid, &SidSize))
    {
        ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }
    SidSize = SECURITY_MAX_SID_SIZE;
    if (!CreateWellKnownSid(WinInteractiveSid, NULL, pInteractiveSid, &SidSize))
    {
        ERR("WL: CreateWellKnownSid() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    AclSize = sizeof(ACL)
        + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pLocalSystemSid)
        + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(pInteractiveSid);
    pDefaultAcl = HeapAlloc(GetProcessHeap(), 0, AclSize);
    pUserDesktopAcl = HeapAlloc(GetProcessHeap(), 0, AclSize);
    if (!pDefaultAcl || !pUserDesktopAcl)
    {
        ERR("WL: HeapAlloc() failed\n");
        goto cleanup;
    }

    if (!InitializeAcl(pDefaultAcl, AclSize, ACL_REVISION)
     || !InitializeAcl(pUserDesktopAcl, AclSize, ACL_REVISION))
    {
        ERR("WL: InitializeAcl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /*
     * Create default ACL (window station, winlogon desktop, screen saver desktop)
     */
    if (!AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid)
     || !AddAccessAllowedAce(pDefaultAcl, ACL_REVISION, GENERIC_READ, pInteractiveSid))
    {
        ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /*
     * Create the default security descriptor
     */
    if (!InitializeSecurityDescriptor(&DefaultSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
    {
        ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    if (!SetSecurityDescriptorDacl(&DefaultSecurityDescriptor, TRUE, pDefaultAcl, FALSE))
    {
        ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    DefaultSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
    DefaultSecurity.lpSecurityDescriptor = &DefaultSecurityDescriptor;
    DefaultSecurity.bInheritHandle = TRUE;

    /*
     * Create user desktop ACL
     */
    if (!AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pLocalSystemSid)
     || !AddAccessAllowedAce(pUserDesktopAcl, ACL_REVISION, GENERIC_ALL, pInteractiveSid))
    {
        ERR("WL: AddAccessAllowedAce() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /*
     * Create the user desktop security descriptor
     */
    if (!InitializeSecurityDescriptor(&UserDesktopSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
    {
        ERR("WL: InitializeSecurityDescriptor() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    if (!SetSecurityDescriptorDacl(&UserDesktopSecurityDescriptor, TRUE, pUserDesktopAcl, FALSE))
    {
        ERR("WL: SetSecurityDescriptorDacl() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    UserDesktopSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
    UserDesktopSecurity.lpSecurityDescriptor = &UserDesktopSecurityDescriptor;
    UserDesktopSecurity.bInheritHandle = TRUE;

    /*
     * Create the interactive window station
     */
    Session->InteractiveWindowStationName = L"WinSta0";
    Session->InteractiveWindowStation = CreateWindowStationW(
        Session->InteractiveWindowStationName,
        0,
        MAXIMUM_ALLOWED,
        &DefaultSecurity);
    if (!Session->InteractiveWindowStation)
    {
        ERR("WL: Failed to create window station (%lu)\n", GetLastError());
        goto cleanup;
    }
    if (!SetProcessWindowStation(Session->InteractiveWindowStation))
    {
        ERR("WL: SetProcessWindowStation() failed (error %lu)\n", GetLastError());
        goto cleanup;
    }

    /*
     * Create the application desktop
     */
    Session->ApplicationDesktop = CreateDesktopW(
        L"Default",
        NULL,
        NULL,
        0, /* FIXME: Add DF_ALLOWOTHERACCOUNTHOOK flag? */
        MAXIMUM_ALLOWED,
        &UserDesktopSecurity);
    if (!Session->ApplicationDesktop)
    {
        ERR("WL: Failed to create Default desktop (%lu)\n", GetLastError());
        goto cleanup;
    }

    /*
     * Create the winlogon desktop
     */
    Session->WinlogonDesktop = CreateDesktopW(
        L"Winlogon",
        NULL,
        NULL,
        0,
        MAXIMUM_ALLOWED,
        &DefaultSecurity);
    if (!Session->WinlogonDesktop)
    {
        ERR("WL: Failed to create Winlogon desktop (%lu)\n", GetLastError());
        goto cleanup;
    }

    /*
     * Create the screen saver desktop
     */
    Session->ScreenSaverDesktop = CreateDesktopW(
        L"Screen-Saver",
        NULL,
        NULL,
        0,
        MAXIMUM_ALLOWED,
        &DefaultSecurity);
    if(!Session->ScreenSaverDesktop)
    {
        ERR("WL: Failed to create Screen-Saver desktop (%lu)\n", GetLastError());
        goto cleanup;
    }

    /*
     * Switch to winlogon desktop
    */
    if (!SetThreadDesktop(Session->WinlogonDesktop) ||
        !SwitchDesktop(Session->WinlogonDesktop))
    {
        ERR("WL: Cannot switch to Winlogon desktop (%lu)\n", GetLastError());
        goto cleanup;
    }

    ret = TRUE;

cleanup:
    if (!ret)
    {
        if (Session->ApplicationDesktop)
        {
            CloseDesktop(Session->ApplicationDesktop);
            Session->ApplicationDesktop = NULL;
        }
        if (Session->WinlogonDesktop)
        {
            CloseDesktop(Session->WinlogonDesktop);
            Session->WinlogonDesktop = NULL;
        }
        if (Session->ScreenSaverDesktop)
        {
            CloseDesktop(Session->ScreenSaverDesktop);
            Session->ScreenSaverDesktop = NULL;
        }
        if (Session->InteractiveWindowStation)
        {
            CloseWindowStation(Session->InteractiveWindowStation);
            Session->InteractiveWindowStation = NULL;
        }
    }
    HeapFree(GetProcessHeap(), 0, pDefaultAcl);
    HeapFree(GetProcessHeap(), 0, pUserDesktopAcl);
    return ret;
}
Example #30
0
PVOID BuildRestrictedSD(PSECURITY_DESCRIPTOR pSD) {
    DWORD  dwAclLength;
    PSID   pAuthenticatedUsersSID = NULL;
    PACL   pDACL   = NULL;
    BOOL   bResult = FALSE;
    SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY;

    // initialize the security descriptor
    if (!InitializeSecurityDescriptor(pSD,
                                      SECURITY_DESCRIPTOR_REVISION)) {
//        syslog(LOG_ERR, "InitializeSecurityDescriptor() failed with error %d\n",
//               GetLastError());
        goto end;
    }

    // obtain a sid for the Authenticated Users Group
    if (!AllocateAndInitializeSid(&siaNT, 1,
                                  SECURITY_AUTHENTICATED_USER_RID, 0, 0, 0, 0, 0, 0, 0,
                                  &pAuthenticatedUsersSID)) {
//        syslog(LOG_ERR, "AllocateAndInitializeSid() failed with error %d\n",
//               GetLastError());
        goto end;
    }

    // NOTE:
    //
    // The Authenticated Users group includes all user accounts that
    // have been successfully authenticated by the system. If access
    // must be restricted to a specific user or group other than
    // Authenticated Users, the SID can be constructed using the
    // LookupAccountSid() API based on a user or group name.

    // calculate the DACL length
    dwAclLength = sizeof(ACL)
            // add space for Authenticated Users group ACE
            + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)
            + GetLengthSid(pAuthenticatedUsersSID);

    // allocate memory for the DACL
    pDACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                             dwAclLength);
    if (!pDACL) {
//        syslog(LOG_ERR, "HeapAlloc() failed with error %d\n", GetLastError());
        goto end;
    }

    // initialize the DACL
    if (!InitializeAcl(pDACL, dwAclLength, ACL_REVISION)) {
//        syslog(LOG_ERR, "InitializeAcl() failed with error %d\n",
//               GetLastError());
        goto end;
    }

    // add the Authenticated Users group ACE to the DACL with
    // GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access

    if (!AddAccessAllowedAce(pDACL, ACL_REVISION,
                             MAXIMUM_ALLOWED ,
                             pAuthenticatedUsersSID)) {
//        syslog(LOG_ERR, "AddAccessAllowedAce() failed with error %d\n",
//               GetLastError());
        goto end;
    }

    // set the DACL in the security descriptor
    if (!SetSecurityDescriptorDacl(pSD, TRUE, pDACL, FALSE)) {
//        syslog(LOG_ERR, "SetSecurityDescriptorDacl() failed with error %d\n",
//               GetLastError());
        goto end;
    }

    bResult = TRUE;

end:
    if (pAuthenticatedUsersSID) FreeSid(pAuthenticatedUsersSID);

    if (bResult == FALSE) {
        if (pDACL) HeapFree(GetProcessHeap(), 0, pDACL);
        pDACL = NULL;
    }

    return (PVOID) pDACL;
}