CreateNamedPipe causes ERROR_ACCESS_DENIED? - c++

i need to create a named pipe for communication between client and server (in same host), here is the code:
WCHAR wszPipeName[MAX_FILE_LENGTH];
swprintf_s(wszPipeName, MAX_FILE_LENGTH, L"\\\\.\\pipe\\TEST%d", uniqueID);
pipe = CreateNamedPipe(
wszPipeName, // name of the pipe
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT,
1,
MAX_MSG_SIZE,
MAX_MSG_SIZE , //inbound buffer
MAX_READ_DATA_TIMEOUT,
NULL // use default security attributes
);
It the handler get back is always INVALID_HANDLE_VAULE, and the error is ERROR_ACCESS_DENIED.
Is there anything wrong here? It is running on Windows 7/8.
Thanks

This is Python code, but this sets up a security descriptor for the local user and denies remote:
dacl = ACL()
# Deny NT AUTHORITY\NETWORK SID
sid = CreateWellKnownSid(WinNetworkSid)
dacl.AddAccessDeniedAce(ACL_REVISION, GENERIC_ALL, sid)
# Allow current user SID
token = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY)
sid = GetTokenInformation(token, TokenUser)[0]
dacl.AddAccessAllowedAce(ACL_REVISION, GENERIC_READ | GENERIC_WRITE, sid)
security_descriptor = SECURITY_DESCRIPTOR()
security_descriptor.SetSecurityDescriptorDacl(True, dacl, False)
security_attributes = SECURITY_ATTRIBUTES()
security_attributes.SECURITY_DESCRIPTOR = security_descriptor
pipe = CreateNamedPipe(
<your other params here>
security_attributes
)

Found the reason, it is because the security limitation. After providing a suitable security descriptor, it just works!

Related

Create Scheduled Task for a specific user

I'm trying to make a little application that I can use at my work for setting up PC and Laptop demos. This application will run a series of operations. One of these operations is to create a Scheduled Task for the Customer account. The Customer account is created simply via NET USER Customer /ADD /PASSWORDREQ:NO (I have tried using the Windows API to achieve this, but I ran into a lot of problems. But that is for another question).
The Scheduled Task that is created for the Customer account would be issued like so: SCHTASKS /CREATE /TN DemoReboot /SC DAILY /ST 12:00 /ET 18:00 /MO 2 /TR "SHUTDOWN /R /F /T 30".
I'm aware of the /U and /P parameters, but unfortunately they do not work as credentials aren't allowed to be saved on the machine, and if there is no password provided, you are prompted to enter a password.
My current approach of executing the command above is like so:
bool AccountManager::run(const QString &rUserName, const QString &rPass, const QString &rCommand)
{
HANDLE hToken;
LPVOID lpvEnv;
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
std::wstring wUser = rUserName.toStdWString();
WCHAR *pUser = const_cast<WCHAR*>(wUser.c_str());
std::wstring wPass = rPass.toStdWString();
WCHAR *pPass = const_cast<WCHAR*>(wPass.c_str());
std::wstring wCommand = rCommand.toStdWString();
WCHAR *pCommand = const_cast<WCHAR*>(wCommand.c_str());
/*
if (!CreateProcessWithLogonW(test, L".", pass,
0, NULL, cmd,
CREATE_UNICODE_ENVIRONMENT, NULL, NULL,
&si, &pi))
DisplayError(str);
*/
if (!LogonUser(pUser, L".", pPass, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken)) {
setLastError("LogonUser");
return false;
}
/*
if (!ImpersonateLoggedOnUser(&hToken))
{
setLastError("ImpersonateLoggedOnUser");
return false;
}
*/
if (!CreateEnvironmentBlock(&lpvEnv, hToken, TRUE)) {
setLastError("CreateEnvironmentBlock");
return false;
}
// I've tried specifying NULL for the second paramater (lpDomain)
if (!CreateProcessWithLogonW(pUser, L".", pPass,
LOGON_WITH_PROFILE, NULL, pCommand,
// I've tried using the created environmentBlock
//CREATE_UNICODE_ENVIRONMENT, lpvEnv, NULL,
CREATE_UNICODE_ENVIRONMENT, NULL, NULL,
&si, &pi)) {
setLastError("CreateProcessWithLogonW");
return false;
}
if (!DestroyEnvironmentBlock(lpvEnv)) {
setLastError("DestroyEnvironmentBlock");
return false;
}
CloseHandle(hToken);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
qDebug() << "finished";
return true;
}
The way this function is called:
void MainWindow::onCreateRebootTaskClicked()
{
// Memory Leak
QProcess *pProc = new QProcess();
pProc->setProgram("cmd.exe");
// Blank password is not allowed, so add temp one
pProc->setArguments({QString("/C net user %1 %2").arg(ui->cxNameLineEdit->text(), "cccx") });
pProc->start();
pProc->waitForFinished();
// Tried without using cmd /C
const QString command = QString("cmd /C SCHTASKS /CREATE /TN \"%1\" /SC DAILY /ST %2 /ET %3 /MO %4 /TR \"%5\"").arg(
ui->taskRebootNameLineEdit->text(),
ui->taskStartTimeEdit->text(),
ui->taskEndTimeEdit->text(),
ui->taskModifierSpinBox->text(),
QString("shutdown /r /f /t %1").arg(ui->taskRebootTimeOutSpinBox->value()));
if (!AccountManager::run(ui->cxNameLineEdit->text(), "cccx", command))
{
const auto &rError = AccountManager::getLastError();
QMessageBox::warning(this, rError.errorCodeName, rError.msg);
}
// Remove temp password
pProc->setArguments({QString("/C net user %1 %2").arg(ui->cxNameLineEdit->text(), "") });
pProc->start();
}
I have left some comments in the code stating some tweaks I have tried.
After the command is executed, I log onto the Customer account and run SCHTASKS /DELETE /TN DemoReboot to see if the Task was successfully created, but the task name isn't found.
Next I tried using the Run function listed above, specifying just cmd as the command so I can get the command line for the Customer account. With the command line that pops up, I manually enter SCHTASKS /CREATE /TN DemoReboot /SC DAILY /ST 12:00 /ET 18:00 /MO 2 /TR "SHUTDOWN /R /F /T 30", then sign into the Customer account and try to delete the Task again, which does work; the task is there to be deleted!
There are other ways I have thought about doing this, such as using the Registry for the Customer account, adding keys under RunOnce, but I have not been able to successfully access the Registry of the Customer account from a different local account.
Hopefully I didn't leave anything out.
Update:
I have managed to figure out what the issue is. The first issue is that for the /MO Option, the taskModifierSpinBox has "hr" suffixed to the text. To fix that, I just split the QString like so: ui->taskModifierSpinBox.text().split(' ').first() What I should have done which I didn't think of just until now is use ui->taskModiferSpinBox->value().toString();
The other issue is the escaped double quotes... I don't really need them around the argument for /TN, but for /TR I do. I have tried using single quotes which did not work. I have tried doubling up on the double quotes, and that didn't work either. I also tried \\\" but that didn't work either.
What I have resulted to is to create a batch file, and pass the batch file as the command to run. Now that isn't really ideal, but I haven't figured out a way to successfully pass an argument that has spaces to /TR

gss_accept_sec_context() failed: An unsupported mechanism was requested

I have a client on windows which is sending a kerberos token obtained from windows using sspi. When I pass in client's token to gss_accept_sec_context on server (Linux Redhat 8) , I get "An unsupported mechanism was requested"
I am calling the gss_accept_sec_context as below:
j_stat = gss_accept_sec_context(&min_stat, context,
*server_creds, &recv_tok,
GSS_C_NO_CHANNEL_BINDINGS,
&client, &doid, &send_tok,
NULL,
NULL, /* time_rec */
NULL); /* del_cred_handle */
I acquire the credentials as :
OM_uint32 maj_stat, min_stat;
maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME,
GSS_C_INDEFINITE ,
GSS_C_NO_OID_SET,
GSS_C_ACCEPT,
server_creds,
NULL, NULL);
What could be the problem?
I hightly doubt that. It is likely an NTLM or SPNEGO token.

how to open partition with CreateFile API?

I want to get handle from drive C:/.I can get handle from disk by:
HANDLE hd = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, NULL);
how to access partition of disk?
when use this code:
HANDLE hd = CreateFile("\\.\C", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, NULL);
and use GetLastError() error code is 123.
ERROR_INVALID_NAME
123 (0x7B)
The filename, directory name, or volume label syntax is incorrect.
from Microsoft doc:
image
but not work!
thanks in advance.
The name you should be using to open a volume is C: and make sure the back slashes are escaped appropriately.
HANDLE hd = CreateFile("\\\\.\\C:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 0, OPEN_EXISTING, 0, NULL);
Note that you will probably get error 5 (Access denied), unless the exe is being run with administrator privileges.

CertOpenStore access denied

I have a pice of code in c++ that gets certificate from store:
// Open CA system store
m_hCertStore = ::CertOpenStore(
CERT_STORE_PROV_SYSTEM,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER,
//CERT_SYSTEM_STORE_LOCAL_MACHINE,
Store
);
if( !m_hCertStore )
throw MY_WIN32_TO_HRESULT(GetLastError());
// Locate "iScala License Key Generator" certificate
m_pCCertContext = ::CertFindCertificateInStore(
m_hCertStore,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
0,
CERT_FIND_SUBJECT_STR,
CertSubject,
NULL
);
When it tries to open the Cert Store I get an access denied error.
The certificate is in the Certificates/Current User, Intermediate Certification Authorities.

Cannot upload a file to a ftp server using C++

I have this simple code to upload a file to a server, but it seems that it doesnt work, doesn't upload any file(FtpPutFile returns 0). I am using FileZilla Server and this is my code and what FileZilla says:
void upload()
{
hInternet = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
hFtpSession = InternetConnect(hInternet,"127.0.0.1",INTERNET_DEFAULT_FTP_PORT,"vbx","pass",INTERNET_SERVICE_FTP, 0,0 );
FtpPutFile(hFtpSession, "c:\\stories.txt", "e:\\text.txt", FTP_TRANSFER_TYPE_BINARY, 0);
InternetCloseHandle(hFtpSession);
InternetCloseHandle(hInternet);
}
(000011)3/27/2011 0:01:53 AM - (not logged in) (127.0.0.1)> USER vbx
(000011)3/27/2011 0:01:53 AM - (not logged in) (127.0.0.1)> 331 Password required for vbx
(000011)3/27/2011 0:01:53 AM - (not logged in) (127.0.0.1)> PASS *******
(000011)3/27/2011 0:01:53 AM - vbx (127.0.0.1)> 230 Logged on
(000011)3/27/2011 0:01:53 AM - vbx (127.0.0.1)> disconnected.
Thank you.
edit: GetLastError() returns: The process cannot access the file because it is being used by another process.
With GetLastError() returning ERROR_SHARING_VIOLATION (32) for FtpPutFile, it likely means that that there is an open handle to "c:\stories.txt" that prevents read sharing. If you have this file open in your program, you will need to either allow read sharing in the CreateFile call or close all open handles that prevent sharing so that FtpPutFile can open the file.