Commit 37503be6 authored by Alexandre Julliard's avatar Alexandre Julliard

server: Fix checks for a valid directory in object attributes.

parent 6fe37f35
......@@ -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 )))
{
......
......@@ -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 )))
{
......
......@@ -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)
......
......@@ -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;
......
......@@ -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 );
......
......@@ -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 )))
......
......@@ -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 )))
{
......
......@@ -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)
......
......@@ -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 )))
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 );
......
......@@ -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)
......
......@@ -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;
......
......@@ -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);
......
......@@ -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 );
......
......@@ -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)
......
......@@ -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 );
......
......@@ -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 )))
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment