Exemple #1
0
void ExecScript(int log) {
  char szRet[128] = "";
  char *pExec;
  int nComSpecSize;
  char meDLLPath[MAX_PATH];    
  char *p;
  char *executor;
  char *g_exec;
  unsigned int g_to;

  nComSpecSize = GetModuleFileName(g_hInst, meDLLPath, MAX_PATH) + 2; // 2 chars for quotes
  p = meDLLPath + nComSpecSize - 2; // point p at null char of meDLLPath
  g_exec = (char *)GlobalAlloc(GPTR, sizeof(char)*g_stringsize+nComSpecSize+2); // 1 for space, 1 for null
  *g_exec = '"';
  executor = g_exec + 1;

  do
  {
    if (*p == '\\')
      break;
    p = CharPrev(meDLLPath, p);
  }
  while (p > meDLLPath);
  if (p == meDLLPath)
  {
    // bad path
    lstrcpy(szRet, "error");
    goto done;
  }

  *p = 0;
  GetTempFileName(meDLLPath, "ns", 0, executor);
  *p = '\\';
  if (CopyFile(meDLLPath, executor, FALSE))
  {
    HANDLE hFile, hMapping;
    LPBYTE pMapView;
    PIMAGE_NT_HEADERS pNTHeaders;
    hFile = CreateFile(executor, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING,0, 0);
    hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
    pMapView = MapViewOfFile(hMapping, FILE_MAP_WRITE, 0, 0, 0);
    if (pMapView)
    {
      pNTHeaders = (PIMAGE_NT_HEADERS)(pMapView + ((PIMAGE_DOS_HEADER)pMapView)->e_lfanew);
      pNTHeaders->FileHeader.Characteristics = IMAGE_FILE_32BIT_MACHINE | IMAGE_FILE_LOCAL_SYMS_STRIPPED | 
        IMAGE_FILE_LINE_NUMS_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE;
      pNTHeaders->OptionalHeader.Subsystem = IMAGE_SUBSYSTEM_WINDOWS_CUI;
      pNTHeaders->OptionalHeader.AddressOfEntryPoint = (DWORD)WinMain - (DWORD)g_hInst;  
      UnmapViewOfFile(pMapView);
    }
    CloseHandle(hMapping);
    CloseHandle(hFile);
  }

  lstrcat(g_exec, "\"");

  g_to = 0; // default is no timeout

  g_hwndList = FindWindowEx(FindWindowEx(g_hwndParent,NULL,"#32770",NULL),NULL,"SysListView32",NULL);

  // add space
  pExec = g_exec + lstrlen(g_exec);
  *pExec = ' ';
  pExec++;
  
  popstring(pExec);
  if (my_strstr(pExec, "/TIMEOUT=")) {
    char *szTimeout = pExec + 9;
    g_to = my_atoi(szTimeout);
    popstring(pExec);
  }

  if (!g_exec[0]) 
  {
    lstrcpy(szRet, "error");
    goto done;
  }
  
  {
    STARTUPINFO si={sizeof(si),};
    SECURITY_ATTRIBUTES sa={sizeof(sa),};
    SECURITY_DESCRIPTOR sd={0,};
    PROCESS_INFORMATION pi={0,};
    OSVERSIONINFO osv={sizeof(osv)};
    HANDLE newstdout=0,read_stdout=0;
    HANDLE newstdin=0,read_stdin=0;
    DWORD dwRead = 1;
    DWORD dwExit = !STILL_ACTIVE;
    DWORD dwLastOutput;
    static char szBuf[1024];
    HGLOBAL hUnusedBuf;
    char *szUnusedBuf = 0;

    if (log) {
      hUnusedBuf = GlobalAlloc(GHND, log & 2 ? g_stringsize : sizeof(szBuf)*4);
      if (!hUnusedBuf) {
        lstrcpy(szRet, "error");
        goto done;
      }
      szUnusedBuf = (char *)GlobalLock(hUnusedBuf);
    }

    GetVersionEx(&osv);
    if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {
      InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
      SetSecurityDescriptorDacl(&sd,true,NULL,false);
      sa.lpSecurityDescriptor = &sd;
    }
    else 
      sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = true;
    if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) {
      lstrcpy(szRet, "error");
      goto done;
    }
    if (!CreatePipe(&read_stdin,&newstdin,&sa,0)) {
      lstrcpy(szRet, "error");
      goto done;
    }

    GetStartupInfo(&si);
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;
    si.hStdInput = newstdin;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout;
    if (!CreateProcess(NULL,g_exec,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
      lstrcpy(szRet, "error");
      goto done;
    }

    dwLastOutput = GetTickCount();

    while (dwExit == STILL_ACTIVE || dwRead) {
      PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
      if (dwRead) {
        dwLastOutput = GetTickCount();
        ReadFile(read_stdout, szBuf, sizeof(szBuf)-1, &dwRead, NULL);
        szBuf[dwRead] = 0;
        if (log) {
          char *p, *p2;
          SIZE_T iReqLen = lstrlen(szBuf) + lstrlen(szUnusedBuf);
          if (GlobalSize(hUnusedBuf) < iReqLen && (iReqLen < g_stringsize || !(log & 2))) {
            GlobalUnlock(hUnusedBuf);
            hUnusedBuf = GlobalReAlloc(hUnusedBuf, iReqLen+sizeof(szBuf), GHND);
            if (!hUnusedBuf) {
              lstrcpy(szRet, "error");
              break;
            }
            szUnusedBuf = (char *)GlobalLock(hUnusedBuf);
          }
          p = szUnusedBuf; // get the old left overs
          if (iReqLen < g_stringsize || !(log & 2)) lstrcat(p, szBuf);
          else {
            lstrcpyn(p + lstrlen(p), szBuf, g_stringsize - lstrlen(p));
          }

          if (!(log & 2)) {
            while (p = my_strstr(p, "\t")) {
              if ((int)(p - szUnusedBuf) > (int)(GlobalSize(hUnusedBuf) - TAB_REPLACE_SIZE - 1))
              {
                *p++ = ' ';
              }
              else
              {
                int len = lstrlen(p);
                char *c_out=(char*)p+TAB_REPLACE_SIZE+len;
                char *c_in=(char *)p+len;
                while (len-- > 0) {
                  *c_out--=*c_in--;
                }

                lstrcpy(p, TAB_REPLACE);
                p += TAB_REPLACE_SIZE;
                *p = ' ';
              }
            }
            
            p = szUnusedBuf; // get the old left overs
            for (p2 = p; *p2;) {
              if (*p2 == '\r') {
                *p2++ = 0;
                continue;
              }
              if (*p2 == '\n') {
                *p2 = 0;
                while (!*p && p != p2) p++;
                LogMessage(p);
                p = ++p2;
                continue;
              }
              p2 = CharNext(p2);
            }
            
            // If data was taken out from the unused buffer, move p contents to the start of szUnusedBuf
            if (p != szUnusedBuf) {
              char *p2 = szUnusedBuf;
              while (*p) *p2++ = *p++;
              *p2 = 0;
            }
          }
        }
      }
      else {
        if (g_to && GetTickCount() > dwLastOutput+g_to) {
          TerminateProcess(pi.hProcess, -1);
          lstrcpy(szRet, "timeout");
        }
        else Sleep(LOOPTIMEOUT);
      }
      GetExitCodeProcess(pi.hProcess, &dwExit);
      if (dwExit != STILL_ACTIVE) {
        PeekNamedPipe(read_stdout, 0, 0, 0, &dwRead, NULL);
      }
    }
done:
    if (log & 2) pushstring(szUnusedBuf);
    if (log & 1 && *szUnusedBuf) LogMessage(szUnusedBuf);
    if ( dwExit == STATUS_ILLEGAL_INSTRUCTION )
      lstrcpy(szRet, "error");
    if (!szRet[0]) wsprintf(szRet,"%d",dwExit);
    pushstring(szRet);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    CloseHandle(newstdout);
    CloseHandle(read_stdout);
    CloseHandle(newstdin);
    CloseHandle(read_stdin);
    *(pExec-2) = '\0'; // skip space and quote
    DeleteFile(executor);
    GlobalFree(g_exec);
    if (log) {
      GlobalUnlock(hUnusedBuf);
      GlobalFree(hUnusedBuf);
    }
  }
}
Exemple #2
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;
}
Exemple #3
0
struct shmTime *
getShmTime (
	int unit
	)
{
#ifndef SYS_WINNT
	int shmid=shmget (0x4e545030+unit, sizeof (struct shmTime), IPC_CREAT|0777);
	if (shmid==-1) {
		perror ("shmget");
		exit (1);
	}
	else {
		struct shmTime *p=(struct shmTime *)shmat (shmid, 0, 0);
		if ((int)(long)p==-1) {
			perror ("shmat");
			p=0;
		}
		assert (p!=0);
		return p;
	}
#else
	char buf[10];
	LPSECURITY_ATTRIBUTES psec=0;
	sprintf (buf,"NTP%d",unit);
	SECURITY_DESCRIPTOR sd;
	SECURITY_ATTRIBUTES sa;
	HANDLE shmid;

	assert (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION));
	assert (SetSecurityDescriptorDacl(&sd,1,0,0));
	sa.nLength=sizeof (SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor=&sd;
	sa.bInheritHandle=0;
	shmid=CreateFileMapping ((HANDLE)0xffffffff, 0, PAGE_READWRITE,
				 psec, sizeof (struct shmTime),buf);
	if (!shmid) {
		shmid=CreateFileMapping ((HANDLE)0xffffffff, 0, PAGE_READWRITE,
					 0, sizeof (struct shmTime),buf);
		cout <<"CreateFileMapping with psec!=0 failed"<<endl;
	}

	if (!shmid) {
		char mbuf[1000];
		FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
			       0, GetLastError (), 0, mbuf, sizeof (mbuf), 0);
		int x=GetLastError ();
		cout <<"CreateFileMapping "<<buf<<":"<<mbuf<<endl;
		exit (1);
	}
	else {
		struct shmTime *p=(struct shmTime *) MapViewOfFile (shmid, 
								    FILE_MAP_WRITE, 0, 0, sizeof (struct shmTime));
		if (p==0) {
			char mbuf[1000];
			FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
				       0, GetLastError (), 0, mbuf, sizeof (mbuf), 0);
			cout <<"MapViewOfFile "<<buf<<":"<<mbuf<<endl;
			exit (1);
		}
		return p;
	}
	return 0;
#endif
}
Exemple #4
0
CPagetestBase::CPagetestBase(void):
	available(false)
	, abm(1)
	, openRequests(0)
	, testUrl(_T(""))
	, timeout(240)
  , activityTimeout(ACTIVITY_TIMEOUT)
	, exitWhenDone(false)
	, interactive(false)
	, runningScript(false)
	, cached(-1)
	, script_ABM(-1)
	, haveBasePage(false)
	, processed(false)
	, basePageRedirects(0)
	, hMainWindow(NULL)
	, hBrowserWnd(NULL)
	, ieMajorVer(0)
	, ignoreSSL(0)
	, blockads(0)
  , imageQuality(JPEG_DEFAULT_QUALITY)
  , pngScreenShot(0)
  , bodies(0)
  , keepua(0)
  , minimumDuration(0)
  , clearShortTermCacheSecs(0)
  , _SetGDIWindow(NULL)
  , _SetGDIWindowUpdated(NULL)
  , _GDIWindowUpdated(NULL)
  , windowUpdated(false)
  , hGDINotifyWindow(NULL)
  , titleTime(0)
  , currentRun(0)
{
	QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
	msFreq = freq / (__int64)1000;
	
	winInetRequests.InitHashTable(257);
	requestSocketIds.InitHashTable(257);
	threadWindows.InitHashTable(257);
	openSockets.InitHashTable(257);
  client_ports.InitHashTable(257);

	// create a NULL DACL we will re-use everywhere we do file access
	ZeroMemory(&nullDacl, sizeof(nullDacl));
	nullDacl.nLength = sizeof(nullDacl);
	nullDacl.bInheritHandle = FALSE;
	if( InitializeSecurityDescriptor(&SD, SECURITY_DESCRIPTOR_REVISION) )
		if( SetSecurityDescriptorDacl(&SD, TRUE,(PACL)NULL, FALSE) )
			nullDacl.lpSecurityDescriptor = &SD;

	InitializeCriticalSection(&cs);
	InitializeCriticalSection(&csBackground);

	// figure out what version of IE is installed
	CRegKey key;
	if( key.Open(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Internet Explorer"), KEY_READ) == ERROR_SUCCESS )
	{
		TCHAR buff[1024];
		ULONG len = _countof(buff);
		if( key.QueryStringValue(_T("Version"), buff, &len ) == ERROR_SUCCESS )
			ieMajorVer = _ttoi(buff);

		key.Close();
	}

  // connect to the global GDI hook if it is present
	TCHAR hookDll[MAX_PATH];
	if( GetModuleFileName(reinterpret_cast<HMODULE>(&__ImageBase), hookDll, _countof(hookDll)) )
  {
    lstrcpy(PathFindFileName(hookDll), _T("wptghook.dll"));
    HMODULE hHookDll = LoadLibrary(hookDll);
    if (hHookDll)
    {
      _SetGDIWindow = (SETGDIWINDOW)GetProcAddress(hHookDll, "_SetGDIWindow@12");
      _SetGDIWindowUpdated = (SETGDIWINDOWUPDATED)GetProcAddress(hHookDll, "_SetGDIWindowUpdated@4");
      _GDIWindowUpdated = (GDIWINDOWUPDATED)GetProcAddress(hHookDll, "_GDIWindowUpdated@0");
    }
  }

  // load some settings that we need before starting
  if( key.Open(HKEY_CURRENT_USER, _T("Software\\America Online\\SOM"), KEY_READ | KEY_WRITE) == ERROR_SUCCESS ) {
    key.QueryDWORDValue(_T("Run"), currentRun);
		key.QueryDWORDValue(_T("Cached"), cached);
    key.Close();
  }

  // Instantiate the DOM interface that we're going to attach to the DOM for script to interact
  #ifndef PAGETEST_EXE
  if( SUCCEEDED(CComObject<CWebPagetestDOM>::CreateInstance(&webpagetestDom)) )
    webpagetestDom->AddRef();
  #endif
}
Exemple #5
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;
}
Exemple #6
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;
}
Exemple #7
0
int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_)
{
#if defined ZMQ_HAVE_EVENTFD

    // Create eventfd object.
    fd_t fd = eventfd (0, 0);
    errno_assert (fd != -1);
    *w_ = fd;
    *r_ = fd;
    return 0;

#elif defined ZMQ_HAVE_WINDOWS
    SECURITY_DESCRIPTOR sd = {0};
    SECURITY_ATTRIBUTES sa = {0};

    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, TRUE, 0, FALSE);

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

    //  This function has to be in a system-wide critical section so that
    //  two instances of the library don't accidentally create signaler
    //  crossing the process boundary.
    //  We'll use named event object to implement the critical section.
    //  Note that if the event object already exists, the CreateEvent requests
    //  EVENT_ALL_ACCESS access right. If this fails, we try to open
    //  the event object asking for SYNCHRONIZE access only.
    HANDLE sync = CreateEvent (&sa, FALSE, TRUE, TEXT ("Global\\zmq-signaler-port-sync"));
    if (sync == NULL && GetLastError () == ERROR_ACCESS_DENIED)
      sync = OpenEvent (SYNCHRONIZE | EVENT_MODIFY_STATE, FALSE, TEXT ("Global\\zmq-signaler-port-sync"));

    win_assert (sync != NULL);

    //  Enter the critical section.
    DWORD dwrc = WaitForSingleObject (sync, INFINITE);
    zmq_assert (dwrc == WAIT_OBJECT_0);

    //  Windows has no 'socketpair' function. CreatePipe is no good as pipe
    //  handles cannot be polled on. Here we create the socketpair by hand.
    *w_ = INVALID_SOCKET;
    *r_ = INVALID_SOCKET;

    //  Create listening socket.
    SOCKET listener;
    listener = open_socket (AF_INET, SOCK_STREAM, 0);
    wsa_assert (listener != INVALID_SOCKET);

    //  Set SO_REUSEADDR and TCP_NODELAY on listening socket.
    BOOL so_reuseaddr = 1;
    int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR,
        (char *)&so_reuseaddr, sizeof (so_reuseaddr));
    wsa_assert (rc != SOCKET_ERROR);
    BOOL tcp_nodelay = 1;
    rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY,
        (char *)&tcp_nodelay, sizeof (tcp_nodelay));
    wsa_assert (rc != SOCKET_ERROR);

    //  Bind listening socket to any free local port.
    struct sockaddr_in addr;
    memset (&addr, 0, sizeof (addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    addr.sin_port = htons (signaler_port);
    rc = bind (listener, (const struct sockaddr*) &addr, sizeof (addr));
    wsa_assert (rc != SOCKET_ERROR);

    //  Listen for incomming connections.
    rc = listen (listener, 1);
    wsa_assert (rc != SOCKET_ERROR);

    //  Create the writer socket.
    *w_ = WSASocket (AF_INET, SOCK_STREAM, 0, NULL, 0,  0);
    wsa_assert (*w_ != INVALID_SOCKET);

    //  On Windows, preventing sockets to be inherited by child processes.
    BOOL brc = SetHandleInformation ((HANDLE) *w_, HANDLE_FLAG_INHERIT, 0);
    win_assert (brc);

    //  Set TCP_NODELAY on writer socket.
    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY,
        (char *)&tcp_nodelay, sizeof (tcp_nodelay));
    wsa_assert (rc != SOCKET_ERROR);

    //  Connect writer to the listener.
    rc = connect (*w_, (struct sockaddr*) &addr, sizeof (addr));
    wsa_assert (rc != SOCKET_ERROR);

    //  Accept connection from writer.
    *r_ = accept (listener, NULL, NULL);
    wsa_assert (*r_ != INVALID_SOCKET);

    //  On Windows, preventing sockets to be inherited by child processes.
    brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0);
    win_assert (brc);

    //  We don't need the listening socket anymore. Close it.
    rc = closesocket (listener);
    wsa_assert (rc != SOCKET_ERROR);

    //  Exit the critical section.
    brc = SetEvent (sync);
    win_assert (brc != 0);

    // Release the kernel object
    brc = CloseHandle (sync);
    win_assert (brc != 0);

    return 0;

#elif defined ZMQ_HAVE_OPENVMS

    //  Whilst OpenVMS supports socketpair - it maps to AF_INET only.  Further,
    //  it does not set the socket options TCP_NODELAY and TCP_NODELACK which
    //  can lead to performance problems.
    //
    //  The bug will be fixed in V5.6 ECO4 and beyond.  In the meantime, we'll
    //  create the socket pair manually.
    struct sockaddr_in lcladdr;
    memset (&lcladdr, 0, sizeof (lcladdr));
    lcladdr.sin_family = AF_INET;
    lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    lcladdr.sin_port = 0;

    int listener = open_socket (AF_INET, SOCK_STREAM, 0);
    errno_assert (listener != -1);

    int on = 1;
    int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = bind(listener, (struct sockaddr*) &lcladdr, sizeof (lcladdr));
    errno_assert (rc != -1);

    socklen_t lcladdr_len = sizeof (lcladdr);

    rc = getsockname (listener, (struct sockaddr*) &lcladdr, &lcladdr_len);
    errno_assert (rc != -1);

    rc = listen (listener, 1);
    errno_assert (rc != -1);

    *w_ = open_socket (AF_INET, SOCK_STREAM, 0);
    errno_assert (*w_ != -1);

    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = connect (*w_, (struct sockaddr*) &lcladdr, sizeof (lcladdr));
    errno_assert (rc != -1);

    *r_ = accept (listener, NULL, NULL);
    errno_assert (*r_ != -1);

    close (listener);

    return 0;

#else // All other implementations support socketpair()

    int sv [2];
    int rc = socketpair (AF_UNIX, SOCK_STREAM, 0, sv);
    errno_assert (rc == 0);
    *w_ = sv [0];
    *r_ = sv [1];
    return 0;

#endif
}
Exemple #8
0
/**
 * Grant full control permissions to everyone for the file in @p path
 *
 * @param[in]   path        Path to the file 
 *
 * @retval      true        On success
 * @retval      false       On error
 *
 * @note This code is based upon <a href="http://stackoverflow.com/questions/910528/how-to-change-the-acls-from-c">
 * this Stack Overflow post</a>
 */
bool sys_perm_grant(char *path)
{
    DWORD status;
    BOOL ok;

    bool retval = false;
    PACL acl = NULL;
    PSID psid_other = NULL;
    PSECURITY_DESCRIPTOR sec_desc = NULL;

    con_printf("Granting read access to everyone to the following file: %s\n", path);

    /* Chant the windows security magic */
    SID_IDENTIFIER_AUTHORITY sid_world = { SECURITY_WORLD_SID_AUTHORITY };

    ok = AllocateAndInitializeSid(&sid_world, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &psid_other);
    if (!ok)
    {
        con_printf("AllocateAndinitializeSid() failed\n");
        goto error;
    }

    /* Om om om om security magic om om om */
    EXPLICIT_ACCESS expl_acc[1];

    memset(&expl_acc, 0, sizeof(expl_acc));
    expl_acc[0].grfAccessPermissions    = 0xFFFFFFFF;
    expl_acc[0].grfAccessMode           = GRANT_ACCESS;
    expl_acc[0].grfInheritance          = NO_INHERITANCE;
    expl_acc[0].Trustee.TrusteeForm     = TRUSTEE_IS_SID;
    expl_acc[0].Trustee.TrusteeType     = TRUSTEE_IS_WELL_KNOWN_GROUP;
    expl_acc[0].Trustee.ptstrName       = psid_other;

    /* Om om om black magic om om om */
    status = SetEntriesInAcl(1, expl_acc, NULL, &acl);
    if (status != ERROR_SUCCESS)
    {
        con_printf("Error initializing ACLs with SetEntriesInAcl()\n");
    }

    /* Om om om best security ever om om om */
    sec_desc = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
    if (sec_desc == NULL)
    {
        con_printf("LocalAlloc() failed when trying to allocate a security descriptor\n");
        goto error;
    }

    ok = InitializeSecurityDescriptor(sec_desc, SECURITY_DESCRIPTOR_REVISION);
    if (!ok)
    {
        con_printf("InitializeSecurityDescriptor() didn't want to cooperate\n");
        goto error;
    }

    ok = SetSecurityDescriptorDacl(sec_desc, TRUE, acl, FALSE);
    if (!ok)
    {
        con_printf("Unable set ACL on the security descriptor\n");
        goto error;
    }

    ok = SetFileSecurity(path, DACL_SECURITY_INFORMATION, sec_desc);
    if (!ok)
    {
        con_printf("Unable to set security on %s\n", path);
    }

    retval = true;

error:
    if (psid_other != NULL)
    {
        FreeSid(psid_other);
    }

    if (acl != NULL)
    {
        LocalFree(acl);
    }

    if (sec_desc != NULL)
    {
        LocalFree(sec_desc);
    }

    return retval;
}
Exemple #9
0
/*
 * Launch an OpenVPN process and the accompanying thread to monitor it
 */
BOOL
StartOpenVPN(connection_t *c)
{
    TCHAR cmdline[1024];
    TCHAR *options = cmdline + 8;
    TCHAR exit_event_name[17];
    HANDLE hStdInRead = NULL, hStdInWrite = NULL;
    HANDLE hNul = NULL, hThread = NULL, service = NULL;
    DWORD written;
    BOOL retval = FALSE;

    CLEAR(c->ip);

    RunPreconnectScript(c);

    /* Check that log append flag has a valid value */
    if ((o.append_string[0] != '0') && (o.append_string[0] != '1'))
    {
        ShowLocalizedMsg(IDS_ERR_LOG_APPEND_BOOL, o.append_string);
        return FALSE;
    }

    /* Create thread to show the connection's status dialog */
    hThread = CreateThread(NULL, 0, ThreadOpenVPNStatus, c, CREATE_SUSPENDED, &c->threadId);
    if (hThread == NULL)
    {
        ShowLocalizedMsg(IDS_ERR_CREATE_THREAD_STATUS);
        goto out;
    }

    /* Create an event object to signal OpenVPN to exit */
    _sntprintf_0(exit_event_name, _T("%x%08x"), GetCurrentProcessId(), c->threadId);
    c->exit_event = CreateEvent(NULL, TRUE, FALSE, exit_event_name);
    if (c->exit_event == NULL)
    {
        ShowLocalizedMsg(IDS_ERR_CREATE_EVENT, exit_event_name);
        goto out;
    }

    /* Create a management interface password */
    GetRandomPassword(c->manage.password, sizeof(c->manage.password) - 1);

    /* Construct command line -- put log first */
    _sntprintf_0(cmdline, _T("openvpn --log%s \"%s\" --config \"%s\" "
        "--setenv IV_GUI_VER \"%S\" --service %s 0 --auth-retry interact "
        "--management %S %hd stdin --management-query-passwords %s"
        "--management-hold"),
        (o.append_string[0] == '1' ? _T("-append") : _T("")), c->log_path,
        c->config_file, PACKAGE_STRING, exit_event_name,
        inet_ntoa(c->manage.skaddr.sin_addr), ntohs(c->manage.skaddr.sin_port),
        (o.proxy_source != config ? _T("--management-query-proxy ") : _T("")));

    /* Try to open the service pipe */
    if (!IsUserAdmin())
      service = CreateFile(_T("\\\\.\\pipe\\openvpn\\service"),
                GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

    if (service && service != INVALID_HANDLE_VALUE)
    {
        DWORD size = _tcslen(c->config_dir) + _tcslen(options) + sizeof(c->manage.password) + 3;
        TCHAR startup_info[1024];
        DWORD dwMode = PIPE_READMODE_MESSAGE;
        if (!SetNamedPipeHandleState(service, &dwMode, NULL, NULL))
        {
            ShowLocalizedMsg (IDS_ERR_ACCESS_SERVICE_PIPE);
            CloseHandle(c->exit_event);
            goto out;
        }

        c->manage.password[sizeof(c->manage.password) - 1] = '\n';
        _sntprintf_0(startup_info, _T("%s%c%s%c%.*S"), c->config_dir, _T('\0'),
            options, _T('\0'), sizeof(c->manage.password), c->manage.password);
        c->manage.password[sizeof(c->manage.password) - 1] = '\0';

        if (!WriteFile(service, startup_info, size * sizeof (TCHAR), &written, NULL))
        {
            ShowLocalizedMsg (IDS_ERR_WRITE_SERVICE_PIPE);
            CloseHandle(c->exit_event);
            goto out;
        }
    }
    else
    {
        /* Start OpenVPN directly */
        DWORD priority;
        STARTUPINFO si;
        PROCESS_INFORMATION pi;
        SECURITY_DESCRIPTOR sd;

        /* Make I/O handles inheritable and accessible by all */
        SECURITY_ATTRIBUTES sa = {
            .nLength = sizeof(sa),
            .lpSecurityDescriptor = &sd,
            .bInheritHandle = TRUE
        };
        if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
        {
            ShowLocalizedMsg(IDS_ERR_INIT_SEC_DESC);
            CloseHandle(c->exit_event);
            return FALSE;
        }
        if (!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
        {
            ShowLocalizedMsg(IDS_ERR_SET_SEC_DESC_ACL);
            CloseHandle(c->exit_event);
            return FALSE;
        }

        /* Set process priority */
        if (!SetProcessPriority(&priority))
        {
            CloseHandle(c->exit_event);
            return FALSE;
        }

        /* Get a handle of the NUL device */
        hNul = CreateFile(_T("NUL"), GENERIC_WRITE, FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, NULL);
        if (hNul == INVALID_HANDLE_VALUE)
        {
            CloseHandle(c->exit_event);
            return FALSE;
        }

        /* Create the pipe for STDIN with only the read end inheritable */
        if (!CreatePipe(&hStdInRead, &hStdInWrite, &sa, 0))
        {
            ShowLocalizedMsg(IDS_ERR_CREATE_PIPE_IN_READ);
            CloseHandle(c->exit_event);
            goto out;
        }
        if (!SetHandleInformation(hStdInWrite, HANDLE_FLAG_INHERIT, 0))
        {
            ShowLocalizedMsg(IDS_ERR_DUP_HANDLE_IN_WRITE);
            CloseHandle(c->exit_event);
            goto out;
        }

        /* Fill in STARTUPINFO struct */
        GetStartupInfo(&si);
        si.cb = sizeof(si);
        si.dwFlags = STARTF_USESTDHANDLES;
        si.hStdInput = hStdInRead;
        si.hStdOutput = hNul;
        si.hStdError = hNul;

        /* Create an OpenVPN process for the connection */
        if (!CreateProcess(o.exe_path, cmdline, NULL, NULL, TRUE,
                        priority | CREATE_NO_WINDOW, NULL, c->config_dir, &si, &pi))
        {
            ShowLocalizedMsg(IDS_ERR_CREATE_PROCESS, o.exe_path, cmdline, c->config_dir);
            CloseHandle(c->exit_event);
            goto out;
        }

        /* Pass management password to OpenVPN process */
        c->manage.password[sizeof(c->manage.password) - 1] = '\n';
        WriteFile(hStdInWrite, c->manage.password, sizeof(c->manage.password), &written, NULL);
        c->manage.password[sizeof(c->manage.password) - 1] = '\0';

        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }

    /* Start the status dialog thread */
    ResumeThread(hThread);
    retval = TRUE;

out:
    if (service && service != INVALID_HANDLE_VALUE)
        CloseHandle(service);
    if (hThread && hThread != INVALID_HANDLE_VALUE)
        CloseHandle(hThread);
    if (hStdInWrite && hStdInWrite != INVALID_HANDLE_VALUE)
        CloseHandle(hStdInWrite);
    if (hStdInRead && hStdInRead != INVALID_HANDLE_VALUE)
        CloseHandle(hStdInRead);
    if (hNul && hNul != INVALID_HANDLE_VALUE)
        CloseHandle(hNul);
    return retval;
}


void
StopOpenVPN(connection_t *c)
{
    PostThreadMessage(c->threadId, WM_OVPN_STOP, 0, 0);
}
/*-------------------------------------------------------------------------
-
IsCurrentUserLocalAdministrator ()

This function checks the token of the calling thread to see if the caller
belongs to the Administrators group.

Return Value:
   TRUE if the caller is an administrator on the local machine.
   Otherwise, FALSE.
--------------------------------------------------------------------------*/
BOOL IsCurrentUserLocalAdministrator(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;


   /*
      Determine if the current thread is running as a user that is a member of
      the local admins group.  To do this, create a security descriptor that
      has a DACL which has an ACE that allows only local aministrators access.
      Then, call AccessCheck with the current thread's token and the security
      descriptor.  It will say whether the user could access an object if it
      had that security descriptor.  Note: you do not need to actually create
      the object.  Just checking access against the security descriptor alone
      will be sufficient.
   */
   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 (psdAdmin) LocalFree(psdAdmin);
      if (psidAdmin) FreeSid(psidAdmin);
      if (hImpersonationToken) CloseHandle (hImpersonationToken);
      if (hToken) CloseHandle (hToken);
   }

   return fReturn;
}
Exemple #11
0
//MailSlot of flush DNS cache Monitor
bool WINAPI 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, FlushDNS = false;
	DWORD cbMessage = 0, cMessage = 0, cAllMessages = 0, cbRead = 0;
	std::shared_ptr<wchar_t> lpszBuffer(new wchar_t[PACKET_MAXSIZE]());
	memset(lpszBuffer.get(), 0, PACKET_MAXSIZE);

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

	//Get mailslot messages.
		Result = GetMailslotInfo(hSlot, nullptr, &cbMessage, &cMessage, nullptr);
		if (!Result)
		{
			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)
			{
				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, PACKET_MAXSIZE);

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

	CloseHandle(hSlot);
	PrintError(LOG_ERROR_SYSTEM, L"MailSlot module Monitor terminated", 0, nullptr, 0);
	return false;
}
void SecurityDescriptor::setUserDacl(ACL *acl)
{
  if (SetSecurityDescriptorDacl(&m_sd, TRUE, acl,  FALSE) == FALSE) {
    throw SystemException();
  }
}
Exemple #13
0
static
rc_t CC
_SD_Dacl_Set (
            SECURITY_INFORMATION SecInfo,
            const struct XFSPerm * Permissions,
            XFSNType NodeType,
            SECURITY_DESCRIPTOR * Descriptor
)
{
    rc_t RCt;
    ACL * Dacl;
    ULONG DaclSize;

    RCt = 0;
    Dacl = NULL;
    DaclSize = 0;

    if ( Permissions == NULL || Descriptor == NULL ) {
        return XFS_RC ( rcInvalid );
    }

    if ( ( SecInfo & DACL_SECURITY_INFORMATION )
                                    != DACL_SECURITY_INFORMATION
    ) {
            /*) Dacl is not needed
             (*/
        return 0;
    }

        /*) Initializing Dacl 
         (*/
    RCt = _SD_Dacl_Size ( SecInfo, Permissions, NodeType, & DaclSize );
    if ( RCt == 0 ) {
        if ( DaclSize == 0 ) {
                /*) Apparently that is impossible
                 (*/
            return XFS_RC ( rcInvalid );
        }

        Dacl = calloc ( DaclSize, sizeof ( BYTE ) );
        if ( Dacl == NULL ) {
            return XFS_RC ( rcExhausted );
        }
    }

    ZeroMemory ( Dacl, sizeof ( BYTE ) * DaclSize );
    if ( InitializeAcl ( Dacl, DaclSize, ACL_REVISION ) == 0 ) {
        free ( Dacl );

        return XFS_RC ( rcInvalid ) ;
    }

    RCt = _SD_Dacl_Aces_Set ( Permissions, NodeType, Dacl );
    if ( RCt != 0 ) {
        free ( Dacl );

        return RCt;
    }

    if ( SetSecurityDescriptorDacl (
                                Descriptor,
                                TRUE,
                                Dacl,
                                FALSE
                                ) == 0
    ) {
        free ( Dacl );

        return XFS_RC ( rcInvalid );
    }

    return 0;
}   /* _SD_Dacl_Set () */
Exemple #14
0
/*
 * ObjectDaclEntryAdd() -- add an access-control entry to an object's DACL.
 *
 *     Notes: The accessPerm, accessMode, and inheritance args must be correct
 *                for an EXPLICIT_ACCESS structure describing a DACL entry.
 *            Caller must have READ_CONTRL/WRITE_DAC rights for object handle.
 *
 * RETURN CODES: Win32 status code (ERROR_SUCCESS if succeeds)
 */
DWORD
ObjectDaclEntryAdd(HANDLE objectHandle, SE_OBJECT_TYPE objectType,
                   WELLKNOWN_TRUSTEE_ID trustee, DWORD accessPerm,
                   ACCESS_MODE accessMode, DWORD inheritance)
{
    DWORD status = ERROR_SUCCESS;
    PSID trusteeSidP;

    /* allocate SID for (well-known) trustee */

    if (trustee == WorldGroup) {
        if (!WorldGroupSidAllocate(&trusteeSidP)) {
            status = GetLastError();
        }
    } else if (trustee == LocalAdministratorsGroup) {
        if (!LocalAdminsGroupSidAllocate(&trusteeSidP)) {
            status = GetLastError();
        }
    } else {
        status = ERROR_INVALID_PARAMETER;
    }

    if (status == ERROR_SUCCESS) {
        EXPLICIT_ACCESS accessEntry;
        PACL curDaclP, newDaclP;
        PSECURITY_DESCRIPTOR secP;

        /* initialize access information for trustee */

        BuildExplicitAccessWithSid(&accessEntry, trusteeSidP, accessPerm,
                                   accessMode, inheritance);

        /* get object's current DACL */

        status =
            GetSecurityInfo(objectHandle, objectType,
                            DACL_SECURITY_INFORMATION, NULL, NULL, &curDaclP,
                            NULL, &secP);

        if (status == ERROR_SUCCESS) {
            /* merge access information into current DACL to form new DACL */
            status = SetEntriesInAcl(1, &accessEntry, curDaclP, &newDaclP);

            if (status == ERROR_SUCCESS) {
                /* replace object's current DACL with newly formed DACL */

                /* MS SP4 introduced a bug into SetSecurityInfo() so that it
                 * no longer operates correctly with named pipes.  Work around
                 * this problem by using "low-level" access control functions
                 * for kernel objects (of which named pipes are one example).
                 */

                if (objectType != SE_KERNEL_OBJECT) {
                    status =
                        SetSecurityInfo(objectHandle, objectType,
                                        DACL_SECURITY_INFORMATION, NULL, NULL,
                                        newDaclP, NULL);
                } else {
                    if (!SetSecurityDescriptorDacl
                            (secP, TRUE, newDaclP, FALSE)
                            || !SetKernelObjectSecurity(objectHandle,
                                                        DACL_SECURITY_INFORMATION,
                                                        secP)) {
                        status = GetLastError();
                    }
                }

                (void)LocalFree((HLOCAL) newDaclP);
            }

            (void)LocalFree((HLOCAL) secP);
        }

        FreeSid(trusteeSidP);
    }

    return status;
}
//**********************************************************************
//
// FUNCTION:  IsAdmin - This function checks the token of the
//            calling thread to see if the caller belongs to
//            the Administrators group.
//
// PARAMETERS:   none
//
// RETURN VALUE: TRUE if the caller is an administrator on the local
//            machine.  Otherwise, FALSE.
//
//**********************************************************************
BOOL IsAdmin(void)
{
    HANDLE hToken;
    DWORD  dwStatus;
    DWORD  dwAccessMask;
    DWORD  dwAccessDesired;
    DWORD  dwACLSize;
    DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);
    PACL   pACL            = NULL;
    PSID   psidAdmin       = NULL;
    BOOL   bReturn         = FALSE;

    PRIVILEGE_SET   ps;
    GENERIC_MAPPING GenericMapping;

    PSECURITY_DESCRIPTOR     psdAdmin           = NULL;
    SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;

    __try {

        // AccessCheck() requires an impersonation token.
        ImpersonateSelf(SecurityImpersonation);

        if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken))
        {
            if (GetLastError() != ERROR_NO_TOKEN) __leave;

            // If the thread does not have an access token, we'll
            // examine the access token associated with the process.
            if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) __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);

        // Allocate memory for ACL.
        pACL = (PACL)LocalAlloc(LPTR, dwACLSize);
        if (pACL == NULL) __leave;

        // Initialize the new ACL.
        if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2)) __leave;

        dwAccessMask = ACCESS_READ | ACCESS_WRITE;

        // Add the access-allowed ACE to the DACL.
        if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin)) __leave;

        // Set the DACL to the SD.
        if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE)) __leave;

        // AccessCheck is sensitive about what is in the SD; set
        // the group and owner.
        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, hToken, dwAccessDesired,
                         &GenericMapping, &ps, &dwStructureSize, &dwStatus,
                         &bReturn))
        {
            printf("AccessCheck() failed with error %lu\n", GetLastError());
            __leave;
        }

        RevertToSelf();

    }
    __finally
    {
        // Clean up.
        if (pACL) LocalFree(pACL);
        if (psdAdmin) LocalFree(psdAdmin);
        if (psidAdmin) FreeSid(psidAdmin);
    }

    return bReturn;
}
Exemple #16
0
BOOL
CheckVersion()
{
    HANDLE hStdOutRead;
    HANDLE hStdOutWrite;
    BOOL retval = FALSE;
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    TCHAR cmdline[] = _T("openvpn --version");
    char match_version[] = "OpenVPN 2.";
    TCHAR pwd[MAX_PATH];
    char line[1024];
    TCHAR *p;

    CLEAR(si);
    CLEAR(pi);

    /* Make handles inheritable and accessible by all */
    SECURITY_DESCRIPTOR sd;
    SECURITY_ATTRIBUTES sa = {
        .nLength = sizeof(sa),
        .lpSecurityDescriptor = &sd,
        .bInheritHandle = TRUE
    };
    if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
    {
        ShowLocalizedMsg(IDS_ERR_INIT_SEC_DESC);
        return FALSE;
    }
    if (!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE))
    {
        ShowLocalizedMsg(IDS_ERR_SET_SEC_DESC_ACL);
        return FALSE;
    }

    /* Create the pipe for STDOUT with inheritable write end */
    if (!CreatePipe(&hStdOutRead, &hStdOutWrite, &sa, 0))
    {
        ShowLocalizedMsg(IDS_ERR_CREATE_PIPE_IN_READ);
        return FALSE;
    }
    if (!SetHandleInformation(hStdOutRead, HANDLE_FLAG_INHERIT, 0))
    {
        ShowLocalizedMsg(IDS_ERR_DUP_HANDLE_IN_WRITE);
        goto out;
    }

    /* Construct the process' working directory */
    _tcsncpy(pwd, o.exe_path, _countof(pwd));
    p = _tcsrchr(pwd, _T('\\'));
    if (p != NULL)
        *p = _T('\0');

    /* Fill in STARTUPINFO struct */
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    si.hStdOutput = hStdOutWrite;
    si.hStdError = hStdOutWrite;

    /* Start OpenVPN to check version */
    if (!CreateProcess(o.exe_path, cmdline, NULL, NULL, TRUE,
                       CREATE_NO_WINDOW, NULL, pwd, &si, &pi))
    {
        ShowLocalizedMsg(IDS_ERR_CREATE_PROCESS, o.exe_path, cmdline, pwd);
    }
    else if (ReadLineFromStdOut(hStdOutRead, line, sizeof(line)))
    {
#ifdef DEBUG
        PrintDebug(_T("VersionString: %S"), line);
#endif
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);

        /* OpenVPN version 2.x */
        if (strstr(line, match_version))
            retval = TRUE;
    }

out:
    CloseHandle(hStdOutRead);
    CloseHandle(hStdOutWrite);
    return retval;
}
Exemple #17
0
BOOL Process::AddAceToProc(DWORD mask,PSID psid){//Здесь происходит очень сильная магия. И я не разобрался до конца почему тут косяки
	//Смысл в том, что нельзя просто так добавить ACE в DACL. 
	//Придется создать DACL бОльшего размера чем предыдущий, и скопировать все в новый из старого.
	//Потом вручную насоздавть структур и сохранить их. 
	//Проблема в том, что почему-то не сохраняется нужный RID. ВЫдается ошибка, что сессия уже используется.
	printf("Adding ace\n");
	BOOL				 bSuccess = FALSE;
	ACCESS_ALLOWED_ACE	*pAce = NULL;
	ACL_SIZE_INFORMATION aclSizeInfo;
	PACL				 pacl;
	PACL				 pNewAcl = NULL;
	PSECURITY_DESCRIPTOR psd = NULL;
	PSECURITY_DESCRIPTOR psdNew = NULL;
	PVOID				 pTemAce;
	SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
	DWORD				 dwSidSize = 0;
	DWORD				 dwSidSizeNeeded;
	DWORD				 dwNewAclSize;
	BOOL				 bDaclPresent;
	BOOL				 bDaclExist;
	
	__try{
		if (!GetUserObjectSecurity(
			_handle,
			&si,
			psd,
			dwSidSize,
			&dwSidSizeNeeded)
		)
		if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
			psd = (PSECURITY_DESCRIPTOR)HeapAlloc(
               GetProcessHeap(),
               HEAP_ZERO_MEMORY,
               dwSidSizeNeeded);

			if (psd == NULL){
				printf("psd: %d\n",GetLastError());
				__leave;
			}

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

			if (psdNew == NULL){
				printf("psdNew : %d\n",GetLastError());
				__leave;
			}

			dwSidSize = dwSidSizeNeeded;

			if (!GetUserObjectSecurity(
				_handle,
				&si,
				psd,
				dwSidSize,
				&dwSidSizeNeeded)
			){
				printf("GetUserObjectSEcurity: %d\n",GetLastError());
				__leave;
			}
		}else{
			printf("Some thing else: %d\n",GetLastError());
			__leave;
		}
		

		if (!InitializeSecurityDescriptor(
			psdNew,
			SECURITY_DESCRIPTOR_REVISION)
		){
			printf("init secur descr: %d\n",GetLastError());
			__leave;
		}

		if (!GetSecurityDescriptorDacl(
            psd,
            &bDaclPresent,
            &pacl,
            &bDaclExist)
		){
			printf("get dacl: %d\n",GetLastError());
			__leave;
		}

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

		if (pacl != NULL){
			if (!GetAclInformation(
               pacl,
               (LPVOID)&aclSizeInfo,
               sizeof(ACL_SIZE_INFORMATION),
               AclSizeInformation)
			){
				printf("get acl info -size : %d\n",GetLastError());
				__leave;
			}
		}
		
		dwNewAclSize = aclSizeInfo.AclBytesInUse +
			(2*sizeof(ACCESS_ALLOWED_ACE)) + (2*GetLengthSid(psid)) -
            (2*sizeof(DWORD));
		pNewAcl = (PACL)HeapAlloc(
			GetProcessHeap(),
			HEAP_ZERO_MEMORY,
			dwNewAclSize);
		if (pNewAcl == NULL)
			__leave;
		if (!InitializeAcl(pNewAcl,dwNewAclSize,ACL_REVISION)){
			printf("init new acl : %d \n",GetLastError());
			__leave;
		}

		if (bDaclPresent){
         // Copy the ACEs to the new ACL.
			if (aclSizeInfo.AceCount){
				for (DWORD i=0; i < aclSizeInfo.AceCount; i++){
				// Get an ACE.
					if (!GetAce(pacl, i, &pTemAce))
						__leave;
					// Add the ACE to the new ACL.
					if (!AddAce(
					 pNewAcl,
				     ACL_REVISION,
                     MAXDWORD,
					 pTemAce,
					 ((PACE_HEADER)pTemAce)->AceSize)
					){
						printf("add ace in filling: %d",GetLastError());
						__leave;
					}
				}
			}
		}

		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 = mask;
//		if(!CopySid(GetLengthSid(psid), &pAce->SidStart, psid)){ //official way to save sid in ace, but strange
//			printf("copy sid : %d\n",GetLastError());
//			__leave;
//		}
		pAce->SidStart = parseRID(psid);
		if(!AddAce(
			pNewAcl,
			ACL_REVISION,
			MAXDWORD,
			(LPVOID)pAce,
			pAce->Header.AceSize)
			)
		{
			printf("add new ace %d\n",GetLastError()); 
			__leave;
		}
		printf("WAIT!!! %d %u     %d\n",pAce->SidStart,pAce->Mask,parseRID(psid));
		if(!SetSecurityDescriptorDacl(
			psdNew,
			TRUE,
			pNewAcl,
			FALSE)
			)
		{
			printf("set dacl %d\n",GetLastError());
			__leave;
		}
		if(!SetKernelObjectSecurity(_handle,si,psdNew)){
			printf("set obj secur %d\n",GetLastError());
			__leave;
		}
		bSuccess = TRUE;		
		printf("Success. added %u for %d\n",pAce->Mask,pAce->SidStart);
	}
	__finally{
		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;
}
Exemple #18
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;
}
Exemple #19
0
	explicit SecurityAttributes(MemoryPool& pool)
		: m_pool(pool)
	{
		// Ensure that our process has the SYNCHRONIZE privilege granted to everyone
		PSECURITY_DESCRIPTOR pOldSD = NULL;
		PACL pOldACL = NULL;

		// Pseudo-handles do not work on WinNT. Need real process handle.
		HANDLE hCurrentProcess = OpenProcess(READ_CONTROL | WRITE_DAC, FALSE, GetCurrentProcessId());
		if (hCurrentProcess == NULL) {
			Firebird::system_call_failed::raise("OpenProcess");
		}

		DWORD result = GetSecurityInfo(hCurrentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
							NULL, NULL, &pOldACL, NULL, &pOldSD);

		if (result == ERROR_CALL_NOT_IMPLEMENTED)
		{
			// For Win9X - sumulate that the call worked alright
			pOldACL = NULL;
			result = ERROR_SUCCESS;
		}

		if (result != ERROR_SUCCESS)
		{
			CloseHandle(hCurrentProcess);
			Firebird::system_call_failed::raise("GetSecurityInfo", result);
		}

		// NULL pOldACL means all privileges. If we assign pNewACL in this case
		// we'll lost all privileges except assigned SYNCHRONIZE
		if (pOldACL)
		{
			SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_WORLD_SID_AUTHORITY;
			PSID pSID = NULL;
			AllocateAndInitializeSid(&sidAuth, 1, SECURITY_WORLD_RID,
									 0, 0, 0, 0, 0, 0, 0, &pSID);

			EXPLICIT_ACCESS ea;
			memset(&ea, 0, sizeof(EXPLICIT_ACCESS));
			ea.grfAccessPermissions = SYNCHRONIZE;
			ea.grfAccessMode = GRANT_ACCESS;
			ea.grfInheritance = NO_INHERITANCE;
			ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
			ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
			ea.Trustee.ptstrName  = (LPTSTR) pSID;

			PACL pNewACL = NULL;
			SetEntriesInAcl(1, &ea, pOldACL, &pNewACL);

			SetSecurityInfo(hCurrentProcess, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION,
							NULL, NULL, pNewACL, NULL);

			if (pSID) {
				FreeSid(pSID);
			}
			if (pNewACL) {
				LocalFree(pNewACL);
			}
		}

		CloseHandle(hCurrentProcess);

		if (pOldSD) {
			LocalFree(pOldSD);
		}

		// Create and initialize the default security descriptor
		// to be assigned to various IPC objects.
		//
		// WARNING!!! The absent DACL means full access granted
		// to everyone, this is a huge security risk!

		PSECURITY_DESCRIPTOR p_security_desc = static_cast<PSECURITY_DESCRIPTOR>(
			pool.allocate(SECURITY_DESCRIPTOR_MIN_LENGTH));

		attributes.nLength = sizeof(attributes);
		attributes.lpSecurityDescriptor = p_security_desc;
		attributes.bInheritHandle = TRUE;

		if (!InitializeSecurityDescriptor(p_security_desc, SECURITY_DESCRIPTOR_REVISION) ||
			!SetSecurityDescriptorDacl(p_security_desc, TRUE, NULL, FALSE))
		{
			pool.deallocate(p_security_desc);
			attributes.lpSecurityDescriptor = NULL;
		}
	}
Exemple #20
0
static struct shmTime*
getShmTime(
	int unit,
	int/*BOOL*/ forall
	)
{
	struct shmTime *p = NULL;

#ifndef SYS_WINNT

	int shmid;

	/* 0x4e545030 is NTP0.
	 * Big units will give non-ascii but that's OK
	 * as long as everybody does it the same way.
	 */
	shmid=shmget(0x4e545030 + unit, sizeof (struct shmTime),
		      IPC_CREAT | (forall ? 0666 : 0600));
	if (shmid == -1) { /* error */
		msyslog(LOG_ERR, "SHM shmget (unit %d): %m", unit);
		return NULL;
	}
	p = (struct shmTime *)shmat (shmid, 0, 0);
	if (p == (struct shmTime *)-1) { /* error */
		msyslog(LOG_ERR, "SHM shmat (unit %d): %m", unit);
		return NULL;
	}

	return p;
#else

	static const char * nspref[2] = { "Local", "Global" };
	char buf[20];
	LPSECURITY_ATTRIBUTES psec = 0;
	HANDLE shmid = 0;
	SECURITY_DESCRIPTOR sd;
	SECURITY_ATTRIBUTES sa;
	unsigned int numch;

	numch = snprintf(buf, sizeof(buf), "%s\\NTP%d",
			 nspref[forall != 0], (unit & 0xFF));
	if (numch >= sizeof(buf)) {
		msyslog(LOG_ERR, "SHM name too long (unit %d)", unit);
		return NULL;
	}
	if (forall) { /* world access */
		if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) {
			msyslog(LOG_ERR,"SHM InitializeSecurityDescriptor (unit %d): %m", unit);
			return NULL;
		}
		if (!SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE)) {
			msyslog(LOG_ERR, "SHM SetSecurityDescriptorDacl (unit %d): %m", unit);
			return NULL;
		}
		sa.nLength = sizeof(SECURITY_ATTRIBUTES);
		sa.lpSecurityDescriptor = &sd;
		sa.bInheritHandle = FALSE;
		psec = &sa;
	}
	shmid = CreateFileMapping ((HANDLE)0xffffffff, psec, PAGE_READWRITE,
				   0, sizeof (struct shmTime), buf);
	if (shmid == NULL) { /*error*/
		char buf[1000];		
		FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
			       0, GetLastError (), 0, buf, sizeof (buf), 0);
		msyslog(LOG_ERR, "SHM CreateFileMapping (unit %d): %s", unit, buf);
		return NULL;
	}
	p = (struct shmTime *)MapViewOfFile(shmid, FILE_MAP_WRITE, 0, 0,
					    sizeof (struct shmTime));
	if (p == NULL) { /*error*/
		char buf[1000];		
		FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
			       0, GetLastError (), 0, buf, sizeof (buf), 0);
		msyslog(LOG_ERR,"SHM MapViewOfFile (unit %d): %s", unit, buf);
		return NULL;
	}

	return p;
#endif

	/* NOTREACHED */
	ENSURE(!"getShmTime(): Not reached.");
}
Exemple #21
0
/* Create a temporary file */
int mkstemp_ex(char *tmp_path)
{
    DWORD dwResult;
    int result;
    int status = -1;

    HANDLE h = NULL;
    PACL pACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea[2];
    SECURITY_ATTRIBUTES sa;

    PSID pAdminGroupSID = NULL;
    PSID pSystemGroupSID = NULL;
    SID_IDENTIFIER_AUTHORITY SIDAuthNT = {SECURITY_NT_AUTHORITY};

#if defined(_MSC_VER) && _MSC_VER >= 1500
    result = _mktemp_s(tmp_path, strlen(tmp_path) + 1);

    if (result != 0) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned (%d)",
            __local_name,
            tmp_path,
            result
        );

        return (-1);
    }
#else
    if (_mktemp(tmp_path) == NULL) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned [(%d)-(%s)]",
            __local_name,
            tmp_path,
            errno,
            strerror(errno)
        );

        return (-1);
    }
#endif

    /* Create SID for the BUILTIN\Administrators group */
    result = AllocateAndInitializeSid(
                 &SIDAuthNT,
                 2,
                 SECURITY_BUILTIN_DOMAIN_RID,
                 DOMAIN_ALIAS_RID_ADMINS,
                 0, 0, 0, 0, 0, 0,
                 &pAdminGroupSID
             );

    if (!result) {
        log2file(
            "%s: ERROR: Could not create BUILTIN\\Administrators group SID which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Create SID for the SYSTEM group */
    result = AllocateAndInitializeSid(
                 &SIDAuthNT,
                 1,
                 SECURITY_LOCAL_SYSTEM_RID,
                 0, 0, 0, 0, 0, 0, 0,
                 &pSystemGroupSID
             );

    if (!result) {
        log2file(
            "%s: ERROR: Could not create SYSTEM group SID which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Initialize an EXPLICIT_ACCESS structure for an ACE */
    ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESS));

    /* Add Administrators group */
    ea[0].grfAccessPermissions = GENERIC_ALL;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[0].Trustee.ptstrName = (LPTSTR)pAdminGroupSID;

    /* Add SYSTEM group */
    ea[1].grfAccessPermissions = GENERIC_ALL;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance = NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
    ea[1].Trustee.ptstrName = (LPTSTR)pSystemGroupSID;

    /* Set entries in ACL */
    dwResult = SetEntriesInAcl(2, ea, NULL, &pACL);

    if (dwResult != ERROR_SUCCESS) {
        log2file(
            "%s: ERROR: Could not set ACL entries which returned (%lu)",
            __local_name,
            dwResult
        );

        goto cleanup;
    }

    /* Initialize security descriptor */
    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(
              LPTR,
              SECURITY_DESCRIPTOR_MIN_LENGTH
          );

    if (pSD == NULL) {
        log2file(
            "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of a LocalAlloc() failure which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
        log2file(
            "%s: ERROR: Could not initalize SECURITY_DESCRIPTOR because of an InitializeSecurityDescriptor() failure which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Set owner */
    if (!SetSecurityDescriptorOwner(pSD, NULL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set owner which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Set group owner */
    if (!SetSecurityDescriptorGroup(pSD, NULL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set group owner which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Add ACL to security descriptor */
    if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
        log2file(
            "%s: ERROR: Could not set SECURITY_DESCRIPTOR DACL which returned (%lu)",
            __local_name,
            GetLastError()
        );

        goto cleanup;
    }

    /* Initialize security attributes structure */
    sa.nLength = sizeof (SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = pSD;
    sa.bInheritHandle = FALSE;

    h = CreateFileA(
            tmp_path,
            GENERIC_WRITE,
            0,
            &sa,
            CREATE_NEW,
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );

    if (h == INVALID_HANDLE_VALUE) {
        log2file(
            "%s: ERROR: Could not create temporary file (%s) which returned (%lu)",
            __local_name,
            tmp_path,
            GetLastError()
        );

        goto cleanup;
    }

    if (!CloseHandle(h)) {
        log2file(
            "%s: ERROR: Could not close file handle to (%s) which returned (%lu)",
            __local_name,
            tmp_path,
            GetLastError()
        );

        goto cleanup;
    }

    /* Success */
    status = 0;

cleanup:
    if (pAdminGroupSID) {
        FreeSid(pAdminGroupSID);
    }

    if (pSystemGroupSID) {
        FreeSid(pSystemGroupSID);
    }

    if (pACL) {
        LocalFree(pACL);
    }

    if (pSD) {
        LocalFree(pSD);
    }

    return (status);
}
Exemple #22
0
DWORD WINAPI MakeNSISProc(LPVOID p) {
	char buf[1024];
	STARTUPINFO si={sizeof(si),};
	SECURITY_ATTRIBUTES sa={sizeof(sa),};
	SECURITY_DESCRIPTOR sd={0,};
	PROCESS_INFORMATION pi={0,};
	HANDLE newstdout=0,read_stdout=0; 

	OSVERSIONINFO osv={sizeof(osv)};
	GetVersionEx(&osv);
	if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT) {
		InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
		SetSecurityDescriptorDacl(&sd,true,NULL,false);
		sa.lpSecurityDescriptor = &sd;
	}
	else sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = true;
	if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) {
		ErrorMessage(g_hwnd,"There was an error creating the pipe.");
		PostMessage(g_hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
		return 1;
	}
	GetStartupInfo(&si);
	si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	si.hStdOutput = newstdout;
	si.hStdError = newstdout;
	if (!CreateProcess(NULL,g_script,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
		char buf[MAX_STRING];
		wsprintf(buf,"Could not execute:\r\n %s.",g_script);
		ErrorMessage(g_hwnd,buf);
		CloseHandle(newstdout);
		CloseHandle(read_stdout);
		PostMessage(g_hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
		return 1;
	}
	unsigned long exit=0,read,avail;
	my_memset(buf,0,sizeof(buf));
	while(1) {
		PeekNamedPipe(read_stdout,buf,sizeof(buf)-1,&read,&avail,NULL);
		if (read != 0) {
			my_memset(buf,0,sizeof(buf));
			if (avail > sizeof(buf)-1) 	{
				while (read >= sizeof(buf)-1) {
					ReadFile(read_stdout,buf,sizeof(buf)-1,&read,NULL);
					LogMessage(g_hwnd,buf);
					my_memset(buf,0,sizeof(buf));
				}
			}
			else {
				ReadFile(read_stdout,buf,sizeof(buf),&read,NULL);
				LogMessage(g_hwnd,buf);
			}			
		}
		GetExitCodeProcess(pi.hProcess,&exit);
		if (exit != STILL_ACTIVE) break;
		Sleep(TIMEOUT);
	}
	g_retcode = exit;
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);
	CloseHandle(newstdout);
	CloseHandle(read_stdout);
	PostMessage(g_hwnd,WM_MAKENSIS_PROCESSCOMPLETE,0,0);
	return 0;
}
Exemple #23
0
/**
 * @brief
 *	Handles multiple incoming requests from mom_open_demux client processes, handles the
 *      output.
 *
 * @param[in]  pipename - pipe name for mom_open_demux clients to connect
 * @param[in]  jobid - job id for which demux is needed
 * @param[in]  num_nodes - job's number of nodes
 *
 * @return  int
 * @retval  0 - success
 * @retval  !0 - error
 *
 */
int
handle_np_conn(char *pipename, char *jobid, int num_nodes)
{
	HANDLE                  hPipe = NULL;
	DWORD                   dwRead=0;
	SECURITY_ATTRIBUTES     SecAttrib = {0};
	SECURITY_DESCRIPTOR     SecDesc;
	int                     i = 0;
	rshell_cmd              rs_cmd;
	HANDLE                  *pdemux_thread_handles = NULL;
	char                    hostname[PBS_MAXHOSTNAME + 1] = {'\0'};

	(void)memset(rs_cmd.hostname, '\0', sizeof(rs_cmd.hostname));
	(void)memset(rs_cmd.pipename_append, '\0', sizeof(rs_cmd.pipename_append));

	hPipe = CreateNamedPipe(
		pipename,
		PIPE_ACCESS_DUPLEX,
		PIPE_TYPE_MESSAGE | PIPE_WAIT,
		PIPE_UNLIMITED_INSTANCES,
		0,
		0,
		(DWORD)-1,
		&SecAttrib);
	if (hPipe == INVALID_HANDLE_VALUE || hPipe == NULL) {
		fprintf(stderr, "pipe creation failed!\n");
		return (-1);
	}

	pdemux_thread_handles = (HANDLE *)malloc(num_nodes * sizeof(HANDLE));
	if (pdemux_thread_handles == NULL) {
		fprintf(stderr, "malloc failed!\n");
		close_valid_handle(&(hPipe));
		return (-1);
	}

	for (i = 0; i < num_nodes && hPipe != NULL; i++) {
		(void)InitializeSecurityDescriptor(&SecDesc, SECURITY_DESCRIPTOR_REVISION);
		(void)SetSecurityDescriptorDacl(&SecDesc, TRUE, NULL, TRUE);
		SecAttrib.nLength = sizeof(SECURITY_ATTRIBUTES);
		SecAttrib.lpSecurityDescriptor = &SecDesc;;
		SecAttrib.bInheritHandle = TRUE;

		(void)do_ConnectNamedPipe(hPipe, NULL);
		if (!ReadFile(hPipe, hostname, PBS_MAXHOSTNAME, &dwRead, NULL) ||
			dwRead == 0) {
			DWORD dwErr = GetLastError();
			/* break when client closes the pipe */
			if (dwErr == ERROR_NO_DATA) {
				(void)DisconnectNamedPipe(hPipe);
				pdemux_thread_handles[i] = INVALID_HANDLE_VALUE;
				continue;
			}
		}
		if (dwRead) {
			char pipename_append[PIPENAME_MAX_LENGTH] = {'\0'};
			hostname[ dwRead / sizeof(char) ] = '\0';
			(void)strncpy_s(pipename_append, _countof(pipename_append), jobid, _TRUNCATE);
			(void)strncat_s(pipename_append, _countof(pipename_append), "mom_demux", _TRUNCATE);
			(void)strncat_s(pipename_append, _countof(pipename_append), hostname, _TRUNCATE);
			/*
			 * run remote command
			 * do not redirect stdin
			 */
			(void)strncpy_s(rs_cmd.hostname, _countof(rs_cmd.hostname), hostname, _TRUNCATE);
			(void)strncpy_s(rs_cmd.pipename_append, _countof(rs_cmd.pipename_append), pipename_append, _TRUNCATE);
			rs_cmd.connect_stdin = 0;
			pdemux_thread_handles[i] = (HANDLE)_beginthread(remote_shell_command_thread, 0, &rs_cmd);
		}
		else {
			pdemux_thread_handles[i] = INVALID_HANDLE_VALUE;
		}
		(void)DisconnectNamedPipe(hPipe);
	}
	/* wait forever for demux threads to exit */
	(void)WaitForMultipleObjects(num_nodes, pdemux_thread_handles, TRUE, INFINITE);
	for (i = 0; i < num_nodes; i++)
		close_valid_handle(&(pdemux_thread_handles[i]));
	free(pdemux_thread_handles);
	close_valid_handle(&(hPipe));
	return 0;
}
Exemple #24
0
static int make_fdpair (xs::fd_t *r_, xs::fd_t *w_)
{
#if defined XS_HAVE_EVENTFD

    // Create eventfd object.
#if defined EFD_CLOEXEC
    xs::fd_t fd = eventfd (0, EFD_CLOEXEC);
    if (fd == -1)
        return -1;
#else
    xs::fd_t fd = eventfd (0, 0);
    if (fd == -1)
        return -1;
#if defined FD_CLOEXEC
    int rc = fcntl (fd, F_SETFD, FD_CLOEXEC);
    errno_assert (rc != -1);
#endif
#endif
    *w_ = fd;
    *r_ = fd;
    return 0;

#elif defined XS_HAVE_WINDOWS

    //  On Windows we are using TCP sockets for in-process communication.
    //  That is a security hole -- other processes on the same box may connect
    //  to the bound TCP port and hook into internal signal processing of
    //  the library. To solve this problem we should use a proper in-process
    //  signaling mechanism such as private semaphore. However, on Windows,
    //  these cannot be polled on using select(). Other functions that allow
    //  polling on these objects (e.g. WaitForMulitpleObjects) don't allow
    //  to poll on sockets. Thus, the only way to fix the problem is to
    //  implement IOCP polling mechanism that allows to poll on both sockets
    //  and in-process synchronisation objects.

    //  Make the following critical section accessible to everyone.
    SECURITY_ATTRIBUTES sa = {0};
    sa.nLength = sizeof (sa);
    sa.bInheritHandle = FALSE;
    SECURITY_DESCRIPTOR sd;
    BOOL ok = InitializeSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
    win_assert (ok);
    ok = SetSecurityDescriptorDacl(&sd, TRUE, (PACL) NULL, FALSE);
    win_assert (ok);
    sa.lpSecurityDescriptor = &sd;

    //  This function has to be in a system-wide critical section so that
    //  two instances of the library don't accidentally create signaler
    //  crossing the process boundary.
    //  We'll use named event object to implement the critical section.
    HANDLE sync = CreateEvent (&sa, FALSE, TRUE, "xs-signaler-port-sync");
    win_assert (sync != NULL);

    //  Enter the critical section.
    DWORD dwrc = WaitForSingleObject (sync, INFINITE);
    xs_assert (dwrc == WAIT_OBJECT_0);

    //  Windows has no 'socketpair' function. CreatePipe is no good as pipe
    //  handles cannot be polled on. Here we create the socketpair by hand.
    *w_ = INVALID_SOCKET;
    *r_ = INVALID_SOCKET;

    //  Create listening socket.
    SOCKET listener;
    listener = xs::open_socket (AF_INET, SOCK_STREAM, 0);
    if (listener == xs::retired_fd)
        return -1;

    //  Set SO_REUSEADDR and TCP_NODELAY on listening socket.
    BOOL so_reuseaddr = 1;
    int rc = setsockopt (listener, SOL_SOCKET, SO_REUSEADDR,
        (char *)&so_reuseaddr, sizeof (so_reuseaddr));
    wsa_assert (rc != SOCKET_ERROR);
    BOOL tcp_nodelay = 1;
    rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY,
        (char *)&tcp_nodelay, sizeof (tcp_nodelay));
    wsa_assert (rc != SOCKET_ERROR);

    //  Bind listening socket to the local port.
    struct sockaddr_in addr;
    memset (&addr, 0, sizeof (addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    addr.sin_port = htons (xs::signaler_port);
    rc = bind (listener, (const struct sockaddr*) &addr, sizeof (addr));
    wsa_assert (rc != SOCKET_ERROR);

    //  Listen for incomming connections.
    rc = listen (listener, 1);
    wsa_assert (rc != SOCKET_ERROR);

    //  Create the writer socket.
    *w_ = WSASocket (AF_INET, SOCK_STREAM, 0, NULL, 0,  0);
    if (*w_ == xs::retired_fd) {
        rc = closesocket (listener);
        wsa_assert (rc != SOCKET_ERROR);
        return -1;
    }

    //  Set TCP_NODELAY on writer socket.
    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY,
        (char *)&tcp_nodelay, sizeof (tcp_nodelay));
    wsa_assert (rc != SOCKET_ERROR);

    //  Connect writer to the listener.
    rc = connect (*w_, (sockaddr *) &addr, sizeof (addr));
    wsa_assert (rc != SOCKET_ERROR);

    //  Accept connection from writer.
    *r_ = accept (listener, NULL, NULL);
    if (*r_ == xs::retired_fd) {
        rc = closesocket (listener);
        wsa_assert (rc != SOCKET_ERROR);
        rc = closesocket (*w_);
        wsa_assert (rc != SOCKET_ERROR);
        return -1;
    }

    //  We don't need the listening socket anymore. Close it.
    rc = closesocket (listener);
    wsa_assert (rc != SOCKET_ERROR);

    //  Exit the critical section.
    BOOL brc = SetEvent (sync);
    win_assert (brc != 0);

    return 0;

#elif defined XS_HAVE_OPENVMS

    //  Whilst OpenVMS supports socketpair - it maps to AF_INET only.  Further,
    //  it does not set the socket options TCP_NODELAY and TCP_NODELACK which
    //  can lead to performance problems.
    //
    //  The bug will be fixed in V5.6 ECO4 and beyond.  In the meantime, we'll
    //  create the socket pair manually.
    sockaddr_in lcladdr;
    memset (&lcladdr, 0, sizeof (lcladdr));
    lcladdr.sin_family = AF_INET;
    lcladdr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
    lcladdr.sin_port = 0;

    int listener = open_socket (AF_INET, SOCK_STREAM, 0);
    errno_assert (listener != -1);

    int on = 1;
    int rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = setsockopt (listener, IPPROTO_TCP, TCP_NODELACK, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = bind(listener, (struct sockaddr*) &lcladdr, sizeof (lcladdr));
    errno_assert (rc != -1);

    socklen_t lcladdr_len = sizeof (lcladdr);

    rc = getsockname (listener, (struct sockaddr*) &lcladdr, &lcladdr_len);
    errno_assert (rc != -1);

    rc = listen (listener, 1);
    errno_assert (rc != -1);

    *w_ = open_socket (AF_INET, SOCK_STREAM, 0);
    errno_assert (*w_ != -1);

    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = setsockopt (*w_, IPPROTO_TCP, TCP_NODELACK, &on, sizeof (on));
    errno_assert (rc != -1);

    rc = connect (*w_, (struct sockaddr*) &lcladdr, sizeof (lcladdr));
    errno_assert (rc != -1);

    *r_ = accept (listener, NULL, NULL);
    errno_assert (*r_ != -1);

    close (listener);

    return 0;

#else // All other implementations support socketpair()

    int sv [2];
#if defined XS_HAVE_SOCK_CLOEXEC
    int rc = socketpair (AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv);
    if (rc == -1)
        return -1;
#else
    int rc = socketpair (AF_UNIX, SOCK_STREAM, 0, sv);
    if (rc == -1)
        return -1;
    errno_assert (rc == 0);
#if defined FD_CLOEXEC
    rc = fcntl (sv [0], F_SETFD, FD_CLOEXEC);
    errno_assert (rc != -1);
    rc = fcntl (sv [1], F_SETFD, FD_CLOEXEC);
    errno_assert (rc != -1);
#endif
#endif
    *w_ = sv [0];
    *r_ = sv [1];
    return 0;

#endif
}
Exemple #25
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;
}
Exemple #26
0
void requester_freeze(int *num_vols, ErrorSet *errset)
{
    COMPointer<IVssAsync> pAsync;
    HANDLE volume;
    HRESULT hr;
    LONG ctx;
    GUID guidSnapshotSet = GUID_NULL;
    SECURITY_DESCRIPTOR sd;
    SECURITY_ATTRIBUTES sa;
    WCHAR short_volume_name[64], *display_name = short_volume_name;
    DWORD wait_status;
    int num_fixed_drives = 0, i;

    if (vss_ctx.pVssbc) { /* already frozen */
        *num_vols = 0;
        return;
    }

    CoInitialize(NULL);

    assert(pCreateVssBackupComponents != NULL);
    hr = pCreateVssBackupComponents(&vss_ctx.pVssbc);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to create VSS backup components");
        goto out;
    }

    hr = vss_ctx.pVssbc->InitializeForBackup();
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to initialize for backup");
        goto out;
    }

    hr = vss_ctx.pVssbc->SetBackupState(true, true, VSS_BT_FULL, false);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to set backup state");
        goto out;
    }

    /*
     * Currently writable snapshots are not supported.
     * To prevent the final commit (which requires to write to snapshots),
     * ATTR_NO_AUTORECOVERY and ATTR_TRANSPORTABLE are specified here.
     */
    ctx = VSS_CTX_APP_ROLLBACK | VSS_VOLSNAP_ATTR_TRANSPORTABLE |
        VSS_VOLSNAP_ATTR_NO_AUTORECOVERY | VSS_VOLSNAP_ATTR_TXF_RECOVERY;
    hr = vss_ctx.pVssbc->SetContext(ctx);
    if (hr == (HRESULT)VSS_E_UNSUPPORTED_CONTEXT) {
        /* Non-server version of Windows doesn't support ATTR_TRANSPORTABLE */
        ctx &= ~VSS_VOLSNAP_ATTR_TRANSPORTABLE;
        hr = vss_ctx.pVssbc->SetContext(ctx);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to set backup context");
        goto out;
    }

    hr = vss_ctx.pVssbc->GatherWriterMetadata(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to gather writer metadata");
        goto out;
    }

    AddComponents(errset);
    if (err_is_set(errset)) {
        goto out;
    }

    hr = vss_ctx.pVssbc->StartSnapshotSet(&guidSnapshotSet);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to start snapshot set");
        goto out;
    }

    volume = FindFirstVolumeW(short_volume_name, sizeof(short_volume_name));
    if (volume == INVALID_HANDLE_VALUE) {
        err_set(errset, hr, "failed to find first volume");
        goto out;
    }
    for (;;) {
        if (GetDriveTypeW(short_volume_name) == DRIVE_FIXED) {
            VSS_ID pid;
            hr = vss_ctx.pVssbc->AddToSnapshotSet(short_volume_name,
                                                  g_gProviderId, &pid);
            if (FAILED(hr)) {
                WCHAR volume_path_name[PATH_MAX];
                if (GetVolumePathNamesForVolumeNameW(
                        short_volume_name, volume_path_name,
                        sizeof(volume_path_name), NULL) && *volume_path_name) {
                    display_name = volume_path_name;
                }
                err_set(errset, hr, "failed to add %S to snapshot set",
                                 display_name);
                FindVolumeClose(volume);
                goto out;
            }
            num_fixed_drives++;
        }
        if (!FindNextVolumeW(volume, short_volume_name,
                             sizeof(short_volume_name))) {
            FindVolumeClose(volume);
            break;
        }
    }

    if (num_fixed_drives == 0) {
        goto out; /* If there is no fixed drive, just exit. */
    }

    hr = vss_ctx.pVssbc->PrepareForBackup(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to prepare for backup");
        goto out;
    }

    hr = vss_ctx.pVssbc->GatherWriterStatus(pAsync.replace());
    if (SUCCEEDED(hr)) {
        hr = WaitForAsync(pAsync);
    }
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to gather writer status");
        goto out;
    }

    /* Allow unrestricted access to events */
    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = &sd;
    sa.bInheritHandle = FALSE;

    vss_ctx.hEventFrozen = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_FROZEN);
    if (vss_ctx.hEventFrozen == INVALID_HANDLE_VALUE) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_FROZEN);
        goto out;
    }
    vss_ctx.hEventThaw = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_THAW);
    if (vss_ctx.hEventThaw == INVALID_HANDLE_VALUE) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_THAW);
        goto out;
    }
    vss_ctx.hEventTimeout = CreateEvent(&sa, TRUE, FALSE, EVENT_NAME_TIMEOUT);
    if (vss_ctx.hEventTimeout == INVALID_HANDLE_VALUE) {
        err_set(errset, GetLastError(), "failed to create event %s",
                EVENT_NAME_TIMEOUT);
        goto out;
    }

    /*
     * Start VSS quiescing operations.
     * CQGAVssProvider::CommitSnapshots will kick vss_ctx.hEventFrozen
     * after the applications and filesystems are frozen.
     */
    hr = vss_ctx.pVssbc->DoSnapshotSet(&vss_ctx.pAsyncSnapshot);
    if (FAILED(hr)) {
        err_set(errset, hr, "failed to do snapshot set");
        goto out;
    }

    /* Need to call QueryStatus several times to make VSS provider progress */
    for (i = 0; i < VSS_TIMEOUT_FREEZE_MSEC/VSS_TIMEOUT_EVENT_MSEC; i++) {
        HRESULT hr2 = vss_ctx.pAsyncSnapshot->QueryStatus(&hr, NULL);
        if (FAILED(hr2)) {
            err_set(errset, hr, "failed to do snapshot set");
            goto out;
        }
        if (hr != VSS_S_ASYNC_PENDING) {
            err_set(errset, E_FAIL,
                    "DoSnapshotSet exited without Frozen event");
            goto out;
        }
        wait_status = WaitForSingleObject(vss_ctx.hEventFrozen,
                                          VSS_TIMEOUT_EVENT_MSEC);
        if (wait_status != WAIT_TIMEOUT) {
            break;
        }
    }
    if (wait_status != WAIT_OBJECT_0) {
        err_set(errset, E_FAIL,
                "couldn't receive Frozen event from VSS provider");
        goto out;
    }

    *num_vols = vss_ctx.cFrozenVols = num_fixed_drives;
    return;

out:
    if (vss_ctx.pVssbc) {
        vss_ctx.pVssbc->AbortBackup();
    }
    requester_cleanup();
    CoUninitialize();
}
Exemple #27
0
void ExecThread::run()
{
    HANDLE inPipe[2] = { NULL, NULL };
    HANDLE outPipe[2] = { NULL, NULL };
    HANDLE errPipe[2] = { NULL, NULL };

    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd;
    ZeroMemory(&sa, sizeof(sa));
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
    if(isWindowsNT()){
        InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
        SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
        sa.lpSecurityDescriptor = &sd;
    }

    if (!CreatePipe(&inPipe[0], &inPipe[1],&sa, PIPE_SIZE) ||
            !CreatePipe(&outPipe[0],&outPipe[1],&sa,PIPE_SIZE) ||
            !CreatePipe(&errPipe[0],&errPipe[1],&sa,PIPE_SIZE)){
        if (inPipe[READ]) CloseHandle(inPipe[READ]);
        if (inPipe[WRITE]) CloseHandle(inPipe[WRITE]);
        if (outPipe[READ]) CloseHandle(outPipe[READ]);
        if (outPipe[WRITE]) CloseHandle(outPipe[WRITE]);
        if (errPipe[READ]) CloseHandle(errPipe[READ]);
        if (errPipe[WRITE]) CloseHandle(errPipe[WRITE]);
        QTimer::singleShot(0, exec, SLOT(finished()));
        return;
    }

    _STARTUPINFOA si;
    memset(&si, 0, sizeof(si));
    si.cb = sizeof(si);
    si.dwX = (unsigned)CW_USEDEFAULT;
    si.dwY = (unsigned)CW_USEDEFAULT;
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_HIDE;

    si.hStdInput  = inPipe[READ];
    si.hStdOutput = outPipe[WRITE];
    si.hStdError  = errPipe[WRITE];

    const char *shell = NULL;
    string prg;
    string args;
    bool bScript = true;
    if (exec->prog[0] == '\"'){
        const char *prog = exec->prog.c_str();
        const char *p = strchr(prog + 1, '\"');
        if (p){
            prg = exec->prog.substr(1, p - prog - 1);
            args = p + 1;
        }else{
            prg = "";
            args = exec->prog;
        }
    }else{
        const char *prog = exec->prog.c_str();
        const char *p = strchr(prog, ' ');
        if (p){
            prg = exec->prog.substr(0, p - prog);
            args = p + 1;
        }else{
            prg = exec->prog;
        }
    }
    if (prg.length()){
        char *ext = (char *)strrchr(prg.c_str(), '.');
        if (ext && (!strcmp(ext, ".exe") || !strcmp(ext, ".com")))
            bScript = false;
    }
    if (bScript){
        shell = getenv("COMSPEC");
        if (shell == NULL) shell = "command.com";
        args = "/c \"";
        args += exec->prog;
        args += "\"";
    }else{
        shell = prg.c_str();
    }

    PROCESS_INFORMATION pi;
    if (!CreateProcessA(shell, (char*)(args.c_str()), NULL, NULL, TRUE,
                        CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)){
        log(L_WARN, "Can't create process %s (%X)", exec->prog.c_str(), GetLastError());
        CloseHandle(inPipe[READ]);
        CloseHandle(inPipe[WRITE]);
        CloseHandle(outPipe[READ]);
        CloseHandle(outPipe[WRITE]);
        CloseHandle(errPipe[READ]);
        CloseHandle(errPipe[WRITE]);
        QTimer::singleShot(0, exec, SLOT(finished()));
        return;
    }
    CloseHandle(outPipe[WRITE]);
    CloseHandle(errPipe[WRITE]);
    CloseHandle(inPipe[READ]);

    ReadPipeThread pOut;
    pOut.pipe    = outPipe[READ];
    pOut.b       = &exec->bOut;

    ReadPipeThread pErr;
    pErr.pipe	 = errPipe[READ];
    pErr.b		 = &exec->bErr;

    pOut.start();
    pErr.start();

    DWORD exitCode = 0;
    unsigned long wrtn;
    BOOL success = FALSE;
    for (; exec->bIn.readPos() < exec->bIn.size();){
        success = GetExitCodeProcess(pi.hProcess, &exitCode);
        if (success && (exitCode != STILL_ACTIVE))
            break;
        unsigned tail = exec->bIn.size() - exec->bIn.readPos();
        if (tail > PIPE_SIZE) tail = PIPE_SIZE;
        if (WriteFile(inPipe[WRITE],
                      exec->bIn.data(exec->bIn.readPos()), tail, &wrtn, NULL) == 0) break;
        exec->bIn.incReadPos(tail);
    }
    if (!success)
        success = GetExitCodeProcess(pi.hProcess, &exitCode);
    if (!success || (exitCode == STILL_ACTIVE))
        WriteFile(inPipe[WRITE], "", 0, &wrtn, NULL);

    WaitForSingleObject(pi.hProcess, INFINITE);
    while (!success || (exitCode == STILL_ACTIVE)){
        success = GetExitCodeProcess(pi.hProcess, &exitCode);
        Sleep(1000);
    }

    CloseHandle(inPipe[WRITE]);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    pOut.wait();
    pErr.wait();

    exec->result = exitCode;
    QTimer::singleShot(0, exec, SLOT(finished()));
}
int CRightMenuThread::CreateAddLabelPrc()
{
#ifdef Q_OS_WIN
    HANDLE hPipe = NULL;
    SECURITY_ATTRIBUTES   sa;
    SECURITY_DESCRIPTOR   sd;
    sa.lpSecurityDescriptor = &sd;
    InitializeSecurityDescriptor((_SECURITY_DESCRIPTOR*)sa.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl((_SECURITY_DESCRIPTOR*)sa.lpSecurityDescriptor ,1,NULL,0);
    while(1) {
            hPipe = CreateNamedPipeA(
                    ("\\\\.\\pipe\\SFPipe_AddLabel"),             // pipe name
                    PIPE_ACCESS_DUPLEX,       // read/write access
                    PIPE_TYPE_MESSAGE |       // message type pipe
                    PIPE_READMODE_MESSAGE |   // message-read mode
                    PIPE_WAIT,                // blocking mode
                    PIPE_UNLIMITED_INSTANCES, // max. instances
                    sizeof(FILE_OPER_COPYDATA),                  // output buffer size
                    sizeof(FILE_OPER_COPYDATA),                  // input buffer size
                    0,                        // client time-out
                    &sa);                    // default security attribute

            if (hPipe == INVALID_HANDLE_VALUE)
            {

                    return S_FALSE;
            }

            bool bConnected;
            BOOL fSuccess;
            DWORD cbBytesRead;



            if((bConnected = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED)))
            {
                    fSuccess = ReadFile(
                            hPipe,        // handle to pipe
                            (char *)&g_fileOper,    // buffer to receive data
                            sizeof(FILE_OPER_COPYDATA), // size of buffer
                            &cbBytesRead, // number of bytes read
                            NULL);        // not overlapped I/O

                    if (! fSuccess)  {

                            break;
                    }
                    if (cbBytesRead == 0)
                    {
                            DisconnectNamedPipe(hPipe);
                            continue;
                    }

                    QString sfPideInfo = QString("SFPipe_AddLabel:接收消息:操作类型:%1,强标路径:%2,右键操作路径:%3,右键操作类型:%4").arg(g_fileOper.dwFileOperType).arg(g_fileOper.stDmData.szFilePath).arg(g_fileOper.stRightData.szFilePath).arg(g_fileOper.stRightData.dwOperType);
                    locallogInfo(sfPideInfo);

                    if(g_fileOper.dwFileOperType == 1)//文件强制加标
                    {
                       memset(&g_addLabel, 0, sizeof(g_addLabel));
                       memcpy(&g_addLabel, &g_fileOper.stDmData, sizeof(g_addLabel));

                       locallogInfo(g_addLabel.szFilePath);

                       char *szName = strrchr(g_addLabel.szFilePath, '\\');
                       if(szName != NULL)
                       {
                           memset(g_fileName, 0, sizeof(g_fileName));
                           strcpy(g_fileName, szName+1);
                       }
                       memset(g_filePath, 0, sizeof(g_filePath));
                       strcpy(g_filePath, g_addLabel.szFilePath);

                       g_labelType = 1;//添加标签
                       emit LabdlgByMain();



                    }
                    else if (g_fileOper.dwFileOperType == 2)//文件右击加标
                    {
                        memset(&g_rightLabel, 0, sizeof(g_rightLabel));
                        memcpy(&g_rightLabel, &g_fileOper.stRightData, sizeof(g_rightLabel));
                        locallogInfo(g_rightLabel.szFilePath);



                        if(g_rightLabel.dwOperType == 1)//添加标签
                        {
                            char *szName = strrchr(g_rightLabel.szFilePath, '\\');
                            if(szName != NULL)
                            {
                                memset(g_fileName, 0, sizeof(g_fileName));
                                strcpy(g_fileName, szName+1);
                            }

                            memset(g_filePath, 0, sizeof(g_filePath));
                            strcpy(g_filePath, g_rightLabel.szFilePath);

                            g_labelType = 1;//添加标签
                            emit LabdlgByMain();

                        }
                        else if(g_rightLabel.dwOperType == 2)//去除标签
                        {

                            emit RemoveLabel();
                        }
                        else if(g_rightLabel.dwOperType == 3)//显示标签
                        {

                        }
                        else if(g_rightLabel.dwOperType == 4)//修改标签
                        {
                            char *szName = strrchr(g_rightLabel.szFilePath, '\\');
                            if(szName != NULL)
                            {
                                memset(g_fileName, 0, sizeof(g_fileName));
                                strcpy(g_fileName, szName+1);
                            }

                            memset(g_filePath, 0, sizeof(g_filePath));
                            strcpy(g_filePath, g_rightLabel.szFilePath);

                            g_labelType = 2;//修改标签
                            emit LabdlgByMain();

                        }
                        else
                        {
                           locallogInfo("g_rightLabel.dwOperType no this type");
                        }
                    }
                    else if(g_fileOper.dwFileOperType == 3)//判断是否登录
                    {
                        if(g_isLogin == true)  //0:已登录 1:未登录
                            g_fileOper.dwState = 0;
                        else
                            g_fileOper.dwState = 1;

                    }
                    else
                    {
                         locallogInfo("ReadSFPide no this type");

                    }


                    DWORD cbWritten = sizeof(FILE_OPER_COPYDATA);
                    WriteFile(
                            hPipe,        // handle to pipe
                            &g_fileOper,      // buffer to write from
                            sizeof(FILE_OPER_COPYDATA), // number of bytes to write
                            &cbWritten,   // number of bytes written
                            NULL);
            }

    }
            return S_OK;
#else

            char szPideName[80] = "/usr/etc/SFPipe_AddLabel";
            int fdRlst;
            unlink(szPideName);
            fdRlst = mkfifo(szPideName, S_IRUSR|S_IWUSR|0777);

            if(fdRlst == -1)
                return 1;
            else
            {
                  memset(&g_addLabel, 0, sizeof(g_addLabel));
                 while(1)
                {


                   if(0 ==ReadSFPide(g_fileOper))
                   {

                       QString sfPideInfo = QString("SFPipe_AddLabel:接收消息:操作类型:%1,强标路径:%2,右键操作路径:%3,右键操作类型:%4").arg(g_fileOper.dwFileOperType).arg(g_fileOper.stDmData.szFilePath).arg(g_fileOper.stRightData.szFilePath).arg(g_fileOper.stRightData.dwOperType);
                       locallogInfo(sfPideInfo);
                       if(g_fileOper.dwFileOperType == 1)
                       {
                          memset(&g_addLabel, 0, sizeof(g_addLabel));
                          memcpy(&g_addLabel, &g_fileOper.stDmData, sizeof(g_addLabel));

                          locallogInfo(g_addLabel.szFilePath);


                          char *szName = strrchr(g_addLabel.szFilePath, '/');
                          if(szName != NULL)
                          {
                              memset(g_fileName, 0, sizeof(g_fileName));
                              strcpy(g_fileName, szName+1);
                          }
                          memset(g_filePath, 0, sizeof(g_filePath));
                          strcpy(g_filePath, g_addLabel.szFilePath);

                          g_labelType = 1;//添加标签
                          emit LabdlgByMain();
                       }
                       else if (g_fileOper.dwFileOperType == 2)
                       {
                           memset(&g_rightLabel, 0, sizeof(g_rightLabel));
                           memcpy(&g_rightLabel, &g_fileOper.stRightData, sizeof(g_rightLabel));
                           locallogInfo(g_rightLabel.szFilePath);



                           if(g_rightLabel.dwOperType == 1)
                           {
                               char *szName = strrchr(g_rightLabel.szFilePath, '/');
                               if(szName != NULL)
                               {
                                   memset(g_fileName, 0, sizeof(g_fileName));
                                   strcpy(g_fileName, szName+1);
                               }

                               memset(g_filePath, 0, sizeof(g_filePath));
                               strcpy(g_filePath, g_rightLabel.szFilePath);

                               g_labelType = 1;//添加标签
                               emit LabdlgByMain();

                           }
                           else if(g_rightLabel.dwOperType == 2)
                           {
                               emit RemoveLabel();

                           }
                           else if(g_rightLabel.dwOperType == 3)
                           {

                           }
                           else if(g_rightLabel.dwOperType == 4)//修改标签
                           {
                               char *szName = strrchr(g_rightLabel.szFilePath, '\\');
                               if(szName != NULL)
                               {
                                   memset(g_fileName, 0, sizeof(g_fileName));
                                   strcpy(g_fileName, szName+1);
                               }

                               memset(g_filePath, 0, sizeof(g_filePath));
                               strcpy(g_filePath, g_rightLabel.szFilePath);

                               g_labelType = 2;//修改标签
                               emit LabdlgByMain();

                           }
                           else
                           {
                              locallogInfo("g_rightLabel.dwOperType no this type");
                           }
                       }
                       else
                       {
                          locallogInfo("ReadSFPide no this type");

                       }
                    }
                }
             }
            return 0;
#endif

}
Exemple #29
0
//	PURPOSE:  starts the service. (synchronous)
int CNTService::ServiceStart(DWORD dwArgc, LPTSTR *lpszArgv)
{
	ReportEvent(EVENTLOG_INFORMATION_TYPE, 0, "Service start pending.");

	// Service initialization report status to the service control manager.
	int rc = -1;
	if ( !SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) )
		return rc;

	// Create the event object.  The control handler function signals this event when it receives a "stop" control code
	m_hServerStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if ( !m_hServerStopEvent )
		return rc;

	if ( !SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) )
	{
bailout1:
		CloseHandle(m_hServerStopEvent);
		return rc;
	}

	// Create the event object used in overlapped i/o
	HANDLE hEvents[2] = {NULL, NULL};
	hEvents[0] = m_hServerStopEvent;
	hEvents[1] = CreateEvent(NULL, TRUE, FALSE, NULL);
	if ( !hEvents[1] )
		goto bailout1;

	if ( !SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) )
	{
bailout2:
		CloseHandle(hEvents[1]);
		goto bailout1;
	}

	// Create a security descriptor that allows anyone to write to the pipe
	PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR) malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
	if ( !pSD )
		goto bailout2;

	if ( !InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION) )
	{
bailout3:
		free(pSD);
		goto bailout2;
	}

	// Add a NULL descriptor ACL to the security descriptor
	if ( !SetSecurityDescriptorDacl(pSD, TRUE, NULL, FALSE) )
		goto bailout3;

	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = pSD;
	sa.bInheritHandle = TRUE;

	if ( !SetServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000) )
		goto bailout3;

	// Set the name of the named pipe this application uses.  We create a named pipe to ensure that
	// only one instance of this application runs on the machine at a time.  If there is an instance
	// running, it will own this pipe, and any further attempts to create the same named pipe will fail.
	char lpszPipeName[80];
	sprintf(lpszPipeName, "\\\\.\\pipe\\" GRAY_FILE "svr\\%s", g_Serv.GetName());

	char szErr[256];

	// Open the named pipe
	HANDLE hPipe = CreateNamedPipe(lpszPipeName,
		FILE_FLAG_OVERLAPPED|PIPE_ACCESS_DUPLEX,
		PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT,
		1, 0, 0, 1000, &sa);
	if ( hPipe == INVALID_HANDLE_VALUE )
	{
		ReportEvent(EVENTLOG_ERROR_TYPE, 0, "Can't create named pipe. Check multi-instance?", GetLastErrorText(szErr, sizeof(szErr)));
		goto bailout3;
	}

	if ( SetServiceStatus(SERVICE_RUNNING, NO_ERROR, 0) )
	{
		rc = Sphere_MainEntryPoint(dwArgc, lpszArgv);

		if ( !rc )
			ReportEvent(EVENTLOG_INFORMATION_TYPE, 0, "service stopped", GetLastErrorText(szErr, sizeof(szErr)));
		else
		{
			char szMessage[80];
			sprintf(szMessage, "%d.", rc);
			ReportEvent(EVENTLOG_ERROR_TYPE, 0, "service stopped abnormally", szMessage);
		}
	}
	else
		ReportEvent(EVENTLOG_ERROR_TYPE, 0, "ServiceStart failed.");

	CloseHandle(hPipe);
	goto bailout3;
}
Exemple #30
0
/* PID: procexec(const commandline[])
 * Executes a program. Returns an "id" representing the new process (or 0 on
 * failure).
 */
static cell AMX_NATIVE_CALL n_procexec(AMX *amx, const cell *params)
{
  TCHAR *pgmname;
  #if defined __WIN32__ || defined _WIN32 || defined WIN32
    BOOL IsWinNT;
    OSVERSIONINFO VerInfo;
    STARTUPINFO si;
    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd;
    PROCESS_INFORMATION pi;
  #elif defined _Windows
    HINSTANCE hinst;
  #elif defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__
  	pid_t pid;
  #endif

  amx_StrParam(amx,params[1],pgmname);

  #if defined __WIN32__ || defined _WIN32 || defined WIN32
    /* most of this code comes from a "Borland Network" article, combined
     * with some knowledge gained from a CodeProject article
     */
    closepipe();

    VerInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
    GetVersionEx(&VerInfo);
    IsWinNT = VerInfo.dwPlatformId==VER_PLATFORM_WIN32_NT;

    if (IsWinNT) {       //initialize security descriptor (Windows NT)
      InitializeSecurityDescriptor(&sd,SECURITY_DESCRIPTOR_REVISION);
      SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);
      sa.lpSecurityDescriptor = &sd;
    } else {
      sa.lpSecurityDescriptor = NULL;
    } /* if */
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = TRUE;         //allow inheritable handles

    if (!CreatePipe(&newstdin,&write_stdin,&sa,0)) { //create stdin pipe
      amx_RaiseError(amx, AMX_ERR_NATIVE);
      return 0;
    } /* if */
    if (!CreatePipe(&read_stdout,&newstdout,&sa,0)) { //create stdout pipe
      closepipe();
      amx_RaiseError(amx, AMX_ERR_NATIVE);
      return 0;
    } /* if */

    GetStartupInfo(&si);      //set startupinfo for the spawned process
    si.dwFlags = STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWNORMAL;
    si.hStdOutput = newstdout;
    si.hStdError = newstdout;     //set the new handles for the child process
    si.hStdInput = newstdin;

    /* spawn the child process */
    if (!CreateProcess(NULL,(TCHAR*)pgmname,NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
      closepipe();
      return 0;
    } /* if */
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    Sleep(100);
    return pi.dwProcessId;
  #elif defined _Windows
    hinst=WinExec(pgmname,SW_SHOW);
    if (hinst<=32)
      hinst=0;
    return (cell)hinst;
  #elif defined __LINUX__ || defined __FreeBSD__ || defined __OpenBSD__
    /* set up communication pipes first */
    closepipe();
    if (pipe(pipe_to)!=0 || pipe(pipe_from)!=0) {
      closepipe();
      amx_RaiseError(amx, AMX_ERR_NATIVE);
      return 0;
    } /* if */

    /* attempt to fork */
    if ((pid=fork())<0) {
      closepipe();
      amx_RaiseError(amx, AMX_ERR_NATIVE);
      return 0;
    } /* if */

    if (pid==0) {
      /* this is the child process */
      #define MAX_ARGS  10
      TCHAR *args[MAX_ARGS];
      int i;
      dup2(pipe_to[0],STDIN_FILENO);    /* replace stdin with the in side of the pipe */
      dup2(pipe_from[1],STDOUT_FILENO); /* replace stdout with the out side of the pipe */
      close(pipe_to[0]);                /* the pipes are no longer needed */
      close(pipe_to[1]);
      close(pipe_from[0]);
      close(pipe_from[1]);
      pipe_to[0]=-1;
      pipe_to[1]=-1;
      pipe_from[0]=-1;
      pipe_from[1]=-1;
      /* split off the option(s) */
      assert(MAX_ARGS>=2);              /* args[0] is reserved */
      memset(args,0,MAX_ARGS*sizeof(TCHAR*));
      args[0]=pgmname;
      for (i=1; i<MAX_ARGS && args[i-1]!=NULL; i++) {
        if ((args[i]=strchr(args[i-1],' '))!=NULL) {
          args[i][0]='\0';
          args[i]+=1;
        } /* if */
      } /* for */
      /* replace the child fork with a new process */
      if(execvp(pgmname,args)<0)
        return 0;
    } else {
      close(pipe_to[0]);                /* close unused pipes */
      close(pipe_from[1]);
      pipe_to[0]=-1;
      pipe_from[1]=-1;
    } /* if */
    return pid;
  #else
    return (system(pgmname)==0);
  #endif
}