server: Correctly implement permission checking for named pipes.
This commit is contained in:
parent
e4c2a6d1cd
commit
9034e694a3
|
@ -172,6 +172,55 @@ static void test_create_invalid(void)
|
|||
CloseHandle(handle);
|
||||
}
|
||||
|
||||
static void test_create(void)
|
||||
{
|
||||
HANDLE hserver;
|
||||
NTSTATUS res;
|
||||
int j, k;
|
||||
FILE_PIPE_LOCAL_INFORMATION info;
|
||||
IO_STATUS_BLOCK iosb;
|
||||
|
||||
static const DWORD access[] = { 0, GENERIC_READ, GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE};
|
||||
static const DWORD sharing[] = { FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE };
|
||||
|
||||
for (j = 0; j < sizeof(sharing) / sizeof(DWORD); j++) {
|
||||
for (k = 0; k < sizeof(access) / sizeof(DWORD); k++) {
|
||||
HANDLE hclient;
|
||||
BOOL should_succeed = TRUE;
|
||||
|
||||
res = create_pipe(&hserver, sharing[j], FILE_SYNCHRONOUS_IO_NONALERT);
|
||||
if (res) {
|
||||
ok(0, "NtCreateNamedPipeFile returned %x, sharing: %x\n", res, sharing[j]);
|
||||
continue;
|
||||
}
|
||||
|
||||
res = pNtQueryInformationFile(hserver, &iosb, &info, sizeof(info), (FILE_INFORMATION_CLASS)24);
|
||||
ok(!res, "NtQueryInformationFile for server returned %x, sharing: %x\n", res, sharing[j]);
|
||||
|
||||
hclient = CreateFileW(testpipe, access[k], 0, 0, OPEN_EXISTING, 0, 0);
|
||||
if (hclient != INVALID_HANDLE_VALUE) {
|
||||
res = pNtQueryInformationFile(hclient, &iosb, &info, sizeof(info), (FILE_INFORMATION_CLASS)24);
|
||||
ok(!res, "NtQueryInformationFile for client returned %x, access: %x, sharing: %x\n",
|
||||
res, access[k], sharing[j]);
|
||||
CloseHandle(hclient);
|
||||
}
|
||||
|
||||
if (access[k] & GENERIC_WRITE)
|
||||
should_succeed &= !!(sharing[j] & FILE_SHARE_WRITE);
|
||||
if (access[k] & GENERIC_READ)
|
||||
should_succeed &= !!(sharing[j] & FILE_SHARE_READ);
|
||||
|
||||
if (should_succeed)
|
||||
ok(hclient != INVALID_HANDLE_VALUE, "CreateFile failed for sharing %x, access: %x, GetLastError: %d\n",
|
||||
sharing[j], access[k], GetLastError());
|
||||
else
|
||||
ok(hclient == INVALID_HANDLE_VALUE, "CreateFile succeded for sharing %x, access: %x\n", sharing[j], access[k]);
|
||||
|
||||
CloseHandle(hserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL ioapc_called;
|
||||
static void CALLBACK ioapc(void *arg, PIO_STATUS_BLOCK io, ULONG reserved)
|
||||
{
|
||||
|
@ -419,6 +468,9 @@ START_TEST(pipe)
|
|||
trace("starting invalid create tests\n");
|
||||
test_create_invalid();
|
||||
|
||||
trace("starting create tests\n");
|
||||
test_create();
|
||||
|
||||
trace("starting overlapped tests\n");
|
||||
test_overlapped();
|
||||
|
||||
|
|
|
@ -804,6 +804,7 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
|
|||
struct named_pipe *pipe = (struct named_pipe *)obj;
|
||||
struct pipe_server *server;
|
||||
struct pipe_client *client;
|
||||
unsigned int pipe_sharing;
|
||||
int fds[2];
|
||||
|
||||
if (!(server = find_available_server( pipe )))
|
||||
|
@ -812,6 +813,15 @@ static struct object *named_pipe_open_file( struct object *obj, unsigned int acc
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pipe_sharing = server->pipe->sharing;
|
||||
if (((access & GENERIC_READ) && !(pipe_sharing & FILE_SHARE_READ)) ||
|
||||
((access & GENERIC_WRITE) && !(pipe_sharing & FILE_SHARE_WRITE)))
|
||||
{
|
||||
set_error( STATUS_ACCESS_DENIED );
|
||||
release_object( server );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((client = create_pipe_client( options )))
|
||||
{
|
||||
if (!socketpair( PF_UNIX, SOCK_STREAM, 0, fds ))
|
||||
|
|
Loading…
Reference in New Issue