From 37503be65497b97fe5197c2c5c28486e3ff73e59 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 1 Feb 2016 14:57:37 +0900 Subject: [PATCH] server: Fix checks for a valid directory in object attributes. Signed-off-by: Alexandre Julliard --- dlls/ntdll/tests/om.c | 84 ++++--------------------------------------- server/completion.c | 5 ++- server/directory.c | 5 ++- server/event.c | 13 +++---- server/file.c | 2 +- server/handle.c | 10 ++++-- server/mailslot.c | 15 ++++++-- server/mapping.c | 7 ++-- server/mutex.c | 7 ++-- server/named_pipe.c | 15 +++++--- server/process.c | 6 ++-- server/registry.c | 4 +-- server/request.c | 9 ++++- server/request.h | 3 +- server/semaphore.c | 7 ++-- server/symlink.c | 6 ++-- server/timer.c | 5 ++- 17 files changed, 70 insertions(+), 133 deletions(-) diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c index c6794cca733..1884e3fa415 100644 --- a/dlls/ntdll/tests/om.c +++ b/dlls/ntdll/tests/om.c @@ -472,84 +472,69 @@ static void test_name_limits(void) str.Length = 0; status = pNtCreateMutant( &ret, GENERIC_ALL, &attr2, FALSE ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateMutant failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenMutant failed %x\n", str.Length, status ); status = pNtOpenMutant( &ret2, GENERIC_ALL, &attr3 ); - todo_wine ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "%u: NtOpenMutant failed %x\n", str.Length, status ); pNtClose( ret ); status = pNtCreateSemaphore( &ret, GENERIC_ALL, &attr2, 1, 2 ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateSemaphore failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSemaphore failed %x\n", str.Length, status ); status = pNtOpenSemaphore( &ret2, GENERIC_ALL, &attr3 ); - todo_wine ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "%u: NtOpenSemaphore failed %x\n", str.Length, status ); pNtClose( ret ); status = pNtCreateEvent( &ret, GENERIC_ALL, &attr2, 1, 0 ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateEvent failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenEvent failed %x\n", str.Length, status ); status = pNtOpenEvent( &ret2, GENERIC_ALL, &attr3 ); - todo_wine ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "%u: NtOpenEvent failed %x\n", str.Length, status ); pNtClose( ret ); status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, &attr2, 0 ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateKeyedEvent failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenKeyedEvent failed %x\n", str.Length, status ); status = pNtOpenKeyedEvent( &ret2, GENERIC_ALL, &attr3 ); - todo_wine ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "%u: NtOpenKeyedEvent failed %x\n", str.Length, status ); pNtClose( ret ); status = pNtCreateTimer( &ret, GENERIC_ALL, &attr2, NotificationTimer ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateTimer failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenTimer failed %x\n", str.Length, status ); status = pNtOpenTimer( &ret2, GENERIC_ALL, &attr3 ); - todo_wine ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "%u: NtOpenTimer failed %x\n", str.Length, status ); pNtClose( ret ); status = pNtCreateIoCompletion( &ret, GENERIC_ALL, &attr2, 0 ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateCompletion failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenCompletion failed %x\n", str.Length, status ); status = pNtOpenIoCompletion( &ret2, GENERIC_ALL, &attr3 ); - todo_wine ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "%u: NtOpenCompletion failed %x\n", str.Length, status ); pNtClose( ret ); status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr2 ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateJobObject failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenJobObject failed %x\n", str.Length, status ); status = pNtOpenJobObject( &ret2, GENERIC_ALL, &attr3 ); - todo_wine ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "%u: NtOpenJobObject failed %x\n", str.Length, status ); pNtClose( ret ); status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr2 ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateDirectoryObject failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr ); @@ -557,12 +542,10 @@ static void test_name_limits(void) "%u: NtOpenDirectoryObject failed %x\n", str.Length, status ); if (!status) pNtClose( ret2 ); status = pNtOpenDirectoryObject( &ret2, GENERIC_ALL, &attr3 ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtOpenDirectoryObject failed %x\n", str.Length, status ); pNtClose( ret2 ); pNtClose( ret ); status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, &attr2, &target ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateSymbolicLinkObject failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenSymbolicLinkObject( &ret2, GENERIC_ALL, &attr ); @@ -573,13 +556,11 @@ static void test_name_limits(void) pNtClose( ret2 ); pNtClose( ret ); status = pNtCreateSection( &ret, SECTION_MAP_WRITE, &attr2, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); - todo_wine ok( status == STATUS_SUCCESS, "%u: NtCreateSection failed %x\n", str.Length, status ); attr3.RootDirectory = ret; status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr ); ok( status == STATUS_OBJECT_TYPE_MISMATCH, "%u: NtOpenSection failed %x\n", str.Length, status ); status = pNtOpenSection( &ret2, SECTION_MAP_WRITE, &attr3 ); - todo_wine ok( status == STATUS_OBJECT_TYPE_MISMATCH || status == STATUS_INVALID_HANDLE, "%u: NtOpenSection failed %x\n", str.Length, status ); pNtClose( ret ); @@ -587,6 +568,12 @@ static void test_name_limits(void) str.Length = 67; test_all_kernel_objects( __LINE__, &attr2, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID ); + str.Length = 65532; + test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS ); + + str.Length = 65534; + test_all_kernel_objects( __LINE__, &attr, STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_NAME_INVALID ); + str.Length = 128; for (attr.Length = 0; attr.Length <= 2 * sizeof(attr); attr.Length++) { @@ -597,61 +584,6 @@ static void test_name_limits(void) } attr.Length = sizeof(attr); - str.Length = 65532; - test_all_kernel_objects( __LINE__, &attr, STATUS_SUCCESS, STATUS_SUCCESS ); - - str.Length = 65534; - status = pNtCreateMutant( &ret, GENERIC_ALL, &attr, FALSE ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateMutant failed %x\n", str.Length, status ); - status = pNtOpenMutant( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenMutant failed %x\n", str.Length, status ); - status = pNtCreateSemaphore( &ret, GENERIC_ALL, &attr, 1, 2 ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateSemaphore failed %x\n", str.Length, status ); - status = pNtOpenSemaphore( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenSemaphore failed %x\n", str.Length, status ); - status = pNtCreateEvent( &ret, GENERIC_ALL, &attr, 1, 0 ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateEvent failed %x\n", str.Length, status ); - status = pNtOpenEvent( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenEvent failed %x\n", str.Length, status ); - status = pNtCreateKeyedEvent( &ret, GENERIC_ALL, &attr, 0 ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateKeyedEvent failed %x\n", str.Length, status ); - status = pNtOpenKeyedEvent( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenKeyedEvent failed %x\n", str.Length, status ); - status = pNtCreateTimer( &ret, GENERIC_ALL, &attr, NotificationTimer ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateTimer failed %x\n", str.Length, status ); - status = pNtOpenTimer( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenTimer failed %x\n", str.Length, status ); - status = pNtCreateIoCompletion( &ret, GENERIC_ALL, &attr, 0 ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateCompletion failed %x\n", str.Length, status ); - status = pNtOpenIoCompletion( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenCompletion failed %x\n", str.Length, status ); - status = pNtCreateJobObject( &ret, GENERIC_ALL, &attr ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateJobObject failed %x\n", str.Length, status ); - status = pNtOpenJobObject( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenJobObject failed %x\n", str.Length, status ); - status = pNtCreateDirectoryObject( &ret, GENERIC_ALL, &attr ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateDirectoryObject failed %x\n", str.Length, status ); - status = pNtOpenDirectoryObject( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenDirectoryObject failed %x\n", str.Length, status ); - status = pNtCreateSymbolicLinkObject( &ret, GENERIC_ALL, &attr, &target ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateSymbolicLinkObject failed %x\n", str.Length, status ); - status = pNtOpenSymbolicLinkObject( &ret, GENERIC_ALL, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenSymbolicLinkObject failed %x\n", str.Length, status ); - status = pNtCreateSection( &ret, SECTION_MAP_WRITE, &attr, &size, PAGE_READWRITE, SEC_COMMIT, 0 ); - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtCreateSection failed %x\n", str.Length, status ); - status = pNtOpenSection( &ret, SECTION_MAP_WRITE, &attr ); - todo_wine - ok( status == STATUS_OBJECT_NAME_INVALID, "%u: NtOpenSection failed %x\n", str.Length, status ); - /* null attributes or ObjectName, with or without RootDirectory */ attr3.RootDirectory = 0; attr2.ObjectName = attr3.ObjectName = NULL; @@ -720,7 +652,6 @@ static void test_name_limits(void) timeout.QuadPart = -10000; status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); - todo_wine ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateNamedPipeFile failed %x\n", str.Length, status ); status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr2, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); @@ -759,7 +690,6 @@ static void test_name_limits(void) ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateNamedPipeFile failed %x\n", status ); status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, &attr3, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); - todo_wine ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateNamedPipeFile failed %x\n", status ); status = pNtCreateNamedPipeFile( &ret, GENERIC_ALL, NULL, &iosb, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_CREATE, FILE_PIPE_FULL_DUPLEX, 0, 0, 0, 1, 256, 256, &timeout ); @@ -771,7 +701,6 @@ static void test_name_limits(void) for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(mailslotW)/sizeof(WCHAR)] = 'a'; str.Length = 0; status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL ); - todo_wine ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL ); ok( status == STATUS_INVALID_HANDLE, "%u: NtCreateMailslotFile failed %x\n", str.Length, status ); @@ -803,7 +732,6 @@ static void test_name_limits(void) status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr2, &iosb, 0, 0, 0, NULL ); ok( status == STATUS_OBJECT_NAME_INVALID, "NULL: NtCreateMailslotFile failed %x\n", status ); status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr3, &iosb, 0, 0, 0, NULL ); - todo_wine ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "NULL: NtCreateMailslotFile failed %x\n", status ); status = pNtCreateMailslotFile( &ret, GENERIC_ALL, NULL, &iosb, 0, 0, 0, NULL ); ok( status == STATUS_INVALID_PARAMETER, "NULL: NtCreateMailslotFile failed %x\n", status ); diff --git a/server/completion.c b/server/completion.c index ceebce10d8d..9cf196fdcdd 100644 --- a/server/completion.c +++ b/server/completion.c @@ -177,12 +177,11 @@ DECL_HANDLER(create_completion) { struct completion *completion; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; if ((completion = create_completion( root, &name, objattr->attributes, req->concurrent, sd ))) { diff --git a/server/directory.c b/server/directory.c index 93fdc74def1..6af489e247e 100644 --- a/server/directory.c +++ b/server/directory.c @@ -503,12 +503,11 @@ void init_directories(void) DECL_HANDLER(create_directory) { struct unicode_str name; - struct directory *dir, *root = NULL; + struct directory *dir, *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; if ((dir = create_directory( root, &name, objattr->attributes, HASH_SIZE, sd ))) { diff --git a/server/event.c b/server/event.c index 943bd5b8876..782abee9292 100644 --- a/server/event.c +++ b/server/event.c @@ -280,15 +280,12 @@ DECL_HANDLER(create_event) { struct event *event; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; - if ((event = create_event( root, &name, objattr->attributes, req->manual_reset, req->initial_state, sd ))) { @@ -354,14 +351,12 @@ DECL_HANDLER(create_keyed_event) { struct keyed_event *event; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; - if ((event = create_keyed_event( root, &name, objattr->attributes, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) diff --git a/server/file.c b/server/file.c index 39f6ff0bb6a..bf883f3cf76 100644 --- a/server/file.c +++ b/server/file.c @@ -688,7 +688,7 @@ DECL_HANDLER(create_file) struct fd *root_fd = NULL; struct unicode_str unicode_name; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &unicode_name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &unicode_name, NULL ); const char *name; data_size_t name_len; diff --git a/server/handle.c b/server/handle.c index ce58894ffea..8d6637ea3a0 100644 --- a/server/handle.c +++ b/server/handle.c @@ -579,11 +579,17 @@ obj_handle_t open_object( struct process *process, obj_handle_t parent, unsigned struct directory *root = NULL; struct object *obj; - if (parent && !(root = get_directory_obj( current->process, parent, 0 ))) return 0; + if (name->len >= 65534) + { + set_error( STATUS_OBJECT_NAME_INVALID ); + return 0; + } + + if (parent && !(root = get_directory_obj( process, parent, 0 ))) return 0; if ((obj = open_object_dir( root, name, attributes, ops ))) { - handle = alloc_handle( current->process, obj, access, attributes ); + handle = alloc_handle( process, obj, access, attributes ); release_object( obj ); } if (root) release_object( root ); diff --git a/server/mailslot.c b/server/mailslot.c index b135fb2f73f..e388f8e5153 100644 --- a/server/mailslot.c +++ b/server/mailslot.c @@ -514,12 +514,21 @@ DECL_HANDLER(create_mailslot) { struct mailslot *mailslot; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; + + if (!name.len) /* mailslots need a root directory even without a name */ + { + if (!objattr->rootdir) + { + set_error( STATUS_OBJECT_PATH_SYNTAX_BAD ); + return; + } + else if (!(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; + } if ((mailslot = create_mailslot( root, &name, objattr->attributes, req->max_msgsize, req->read_timeout, sd ))) diff --git a/server/mapping.c b/server/mapping.c index 3c7293d0e30..aef174c935f 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -661,15 +661,12 @@ DECL_HANDLER(create_mapping) { struct object *obj; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; - if ((obj = create_mapping( root, &name, objattr->attributes, req->size, req->protect, req->file_handle, sd ))) { diff --git a/server/mutex.c b/server/mutex.c index 0d7ae031d19..0482fe0b691 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -208,15 +208,12 @@ DECL_HANDLER(create_mutex) { struct mutex *mutex; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; - if ((mutex = create_mutex( root, &name, objattr->attributes, req->owned, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) diff --git a/server/named_pipe.c b/server/named_pipe.c index aa527aa0581..cbacb9363d1 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -917,9 +917,9 @@ DECL_HANDLER(create_named_pipe) struct named_pipe *pipe; struct pipe_server *server; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; @@ -930,8 +930,15 @@ DECL_HANDLER(create_named_pipe) return; } - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; + if (!name.len) /* pipes need a root directory even without a name */ + { + if (!objattr->rootdir) + { + set_error( STATUS_OBJECT_PATH_SYNTAX_BAD ); + return; + } + else if (!(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; + } pipe = create_named_pipe( root, &name, objattr->attributes | OBJ_OPENIF, sd ); diff --git a/server/process.c b/server/process.c index 40cbf938208..6611de1cec1 100644 --- a/server/process.c +++ b/server/process.c @@ -1538,14 +1538,12 @@ DECL_HANDLER(create_job) { struct job *job; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; - if ((job = create_job_object( root, &name, objattr->attributes, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) diff --git a/server/registry.c b/server/registry.c index a41f0addbfc..bdfdb2b621c 100644 --- a/server/registry.c +++ b/server/registry.c @@ -2026,7 +2026,7 @@ DECL_HANDLER(create_key) struct unicode_str name, class; unsigned int access = req->access; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL ); if (!objattr) return; @@ -2183,7 +2183,7 @@ DECL_HANDLER(load_registry) struct key *key, *parent; struct unicode_str name; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL ); if (!objattr) return; diff --git a/server/request.c b/server/request.c index 62e2b0304ff..021878a9231 100644 --- a/server/request.c +++ b/server/request.c @@ -167,12 +167,15 @@ void *set_reply_data_size( data_size_t size ) /* return object attributes from the current request */ const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd, - struct unicode_str *name ) + struct unicode_str *name, + struct directory **root ) { static const struct object_attributes empty_attributes; const struct object_attributes *attr = get_req_data(); data_size_t size = get_req_data_size(); + if (root) *root = NULL; + if (!size) { *sd = NULL; @@ -196,6 +199,10 @@ const struct object_attributes *get_req_object_attributes( const struct security set_error( STATUS_OBJECT_NAME_INVALID ); return NULL; } + if (root && attr->rootdir && attr->name_len) + { + if (!(*root = get_directory_obj( current->process, attr->rootdir, 0 ))) return NULL; + } *sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL; name->len = attr->name_len; name->str = (const WCHAR *)(attr + 1) + attr->sd_len / sizeof(WCHAR); diff --git a/server/request.h b/server/request.h index e4d20e81408..7ec00cdd86b 100644 --- a/server/request.h +++ b/server/request.h @@ -47,7 +47,8 @@ extern void fatal_error( const char *err, ... ); extern const char *get_config_dir(void); extern void *set_reply_data_size( data_size_t size ); extern const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd, - struct unicode_str *name ); + struct unicode_str *name, + struct directory **root ); extern const void *get_req_data_after_objattr( const struct object_attributes *attr, data_size_t *len ); extern int receive_fd( struct process *process ); extern int send_client_fd( struct process *process, int fd, obj_handle_t handle ); diff --git a/server/semaphore.c b/server/semaphore.c index 7213effe403..73d4fe239c3 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -176,15 +176,12 @@ DECL_HANDLER(create_semaphore) { struct semaphore *sem; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) - return; - if ((sem = create_semaphore( root, &name, objattr->attributes, req->initial, req->max, sd ))) { if (get_error() == STATUS_OBJECT_NAME_EXISTS) diff --git a/server/symlink.c b/server/symlink.c index 2611dc30b88..4254c71ddae 100644 --- a/server/symlink.c +++ b/server/symlink.c @@ -166,17 +166,15 @@ DECL_HANDLER(create_symlink) { struct symlink *symlink; struct unicode_str name, target; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; target.str = get_req_data_after_objattr( objattr, &target.len ); target.len = (target.len / sizeof(WCHAR)) * sizeof(WCHAR); - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; - if ((symlink = create_symlink( root, &name, objattr->attributes, &target, sd ))) { reply->handle = alloc_handle( current->process, symlink, req->access, objattr->attributes ); diff --git a/server/timer.c b/server/timer.c index 2b9cb79b202..69d0bef8bc6 100644 --- a/server/timer.c +++ b/server/timer.c @@ -232,12 +232,11 @@ DECL_HANDLER(create_timer) { struct timer *timer; struct unicode_str name; - struct directory *root = NULL; + struct directory *root; const struct security_descriptor *sd; - const struct object_attributes *objattr = get_req_object_attributes( &sd, &name ); + const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, &root ); if (!objattr) return; - if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; if ((timer = create_timer( root, &name, objattr->attributes, req->manual, sd ))) {