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); } } }
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; }
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 }
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 }
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; }
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; }
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 }
/** * 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; }
/* * 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; }
//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(); } }
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 () */
/* * 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; }
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; }
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; }
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; }
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; } }
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."); }
/* 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); }
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; }
/** * @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; }
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 }
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; }
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(); }
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 }
// 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; }
/* 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 }