Commit 9504e2ad authored by Alexandre Julliard's avatar Alexandre Julliard

server: Add a helper function to validate and return object attributes.

parent 7350682a
...@@ -287,16 +287,10 @@ DECL_HANDLER(create_event) ...@@ -287,16 +287,10 @@ DECL_HANDLER(create_event)
struct event *event; struct event *event;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
reply->handle = 0; if (!objattr) return;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return; return;
...@@ -378,13 +372,10 @@ DECL_HANDLER(create_keyed_event) ...@@ -378,13 +372,10 @@ DECL_HANDLER(create_keyed_event)
struct keyed_event *event; struct keyed_event *event;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
if (!objattr_is_valid( objattr, get_req_data_size() )) return; if (!objattr) return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
......
...@@ -686,17 +686,16 @@ DECL_HANDLER(create_file) ...@@ -686,17 +686,16 @@ DECL_HANDLER(create_file)
{ {
struct object *file; struct object *file;
struct fd *root_fd = NULL; struct fd *root_fd = NULL;
const struct object_attributes *objattr = get_req_data(); struct unicode_str unicode_name;
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &unicode_name );
const char *name; const char *name;
data_size_t name_len; data_size_t name_len;
reply->handle = 0; if (!objattr) return;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
/* name is transferred in the unix codepage outside of the objattr structure */ /* name is transferred in the unix codepage outside of the objattr structure */
if (objattr->name_len) if (unicode_name.len)
{ {
set_error( STATUS_INVALID_PARAMETER ); set_error( STATUS_INVALID_PARAMETER );
return; return;
...@@ -712,8 +711,6 @@ DECL_HANDLER(create_file) ...@@ -712,8 +711,6 @@ DECL_HANDLER(create_file)
if (!root_fd) return; if (!root_fd) return;
} }
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
name = (const char *)get_req_data() + sizeof(*objattr) + objattr->sd_len; name = (const char *)get_req_data() + sizeof(*objattr) + objattr->sd_len;
name_len = get_req_data_size() - sizeof(*objattr) - objattr->sd_len; name_len = get_req_data_size() - sizeof(*objattr) - objattr->sd_len;
......
...@@ -664,16 +664,10 @@ DECL_HANDLER(create_mapping) ...@@ -664,16 +664,10 @@ DECL_HANDLER(create_mapping)
struct object *obj; struct object *obj;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
reply->handle = 0; if (!objattr) return;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return; return;
......
...@@ -211,16 +211,10 @@ DECL_HANDLER(create_mutex) ...@@ -211,16 +211,10 @@ DECL_HANDLER(create_mutex)
struct mutex *mutex; struct mutex *mutex;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
reply->handle = 0; if (!objattr) return;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return; return;
......
...@@ -923,8 +923,10 @@ DECL_HANDLER(create_named_pipe) ...@@ -923,8 +923,10 @@ DECL_HANDLER(create_named_pipe)
struct pipe_server *server; struct pipe_server *server;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
if (!objattr) return;
if (!req->sharing || (req->sharing & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) || if (!req->sharing || (req->sharing & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
(!(req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && (req->flags & NAMED_PIPE_MESSAGE_STREAM_READ))) (!(req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && (req->flags & NAMED_PIPE_MESSAGE_STREAM_READ)))
...@@ -933,14 +935,6 @@ DECL_HANDLER(create_named_pipe) ...@@ -933,14 +935,6 @@ DECL_HANDLER(create_named_pipe)
return; return;
} }
reply->handle = 0;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return; return;
......
...@@ -1539,13 +1539,10 @@ DECL_HANDLER(create_job) ...@@ -1539,13 +1539,10 @@ DECL_HANDLER(create_job)
struct job *job; struct job *job;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
if (!objattr_is_valid( objattr, get_req_data_size() )) return; if (!objattr) return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return; if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
......
...@@ -65,6 +65,8 @@ ...@@ -65,6 +65,8 @@
#include "file.h" #include "file.h"
#include "process.h" #include "process.h"
#include "thread.h"
#include "security.h"
#define WANT_REQUEST_HANDLERS #define WANT_REQUEST_HANDLERS
#include "request.h" #include "request.h"
...@@ -163,6 +165,31 @@ void *set_reply_data_size( data_size_t size ) ...@@ -163,6 +165,31 @@ void *set_reply_data_size( data_size_t size )
return current->reply_data; return current->reply_data;
} }
/* return object attributes from the current request */
const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd,
struct unicode_str *name )
{
const struct object_attributes *attr = get_req_data();
data_size_t size = get_req_data_size();
if ((size < sizeof(*attr)) || (size - sizeof(*attr) < attr->sd_len) ||
(size - sizeof(*attr) - attr->sd_len < attr->name_len))
{
set_error( STATUS_ACCESS_VIOLATION );
return NULL;
}
if (attr->sd_len && !sd_is_valid( (const struct security_descriptor *)(attr + 1), attr->sd_len ))
{
set_error( STATUS_INVALID_SECURITY_DESCR );
return NULL;
}
*sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL;
name->len = (attr->name_len / sizeof(WCHAR)) * sizeof(WCHAR);
name->str = (const WCHAR *)(attr + 1) + attr->sd_len / sizeof(WCHAR);
return attr;
}
/* write the remaining part of the reply */ /* write the remaining part of the reply */
void write_reply( struct thread *thread ) void write_reply( struct thread *thread )
{ {
......
...@@ -46,6 +46,8 @@ extern void fatal_error( const char *err, ... ); ...@@ -46,6 +46,8 @@ extern void fatal_error( const char *err, ... );
extern const char *get_config_dir(void); extern const char *get_config_dir(void);
extern void *set_reply_data_size( data_size_t size ); 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 );
extern int receive_fd( struct process *process ); extern int receive_fd( struct process *process );
extern int send_client_fd( struct process *process, int fd, obj_handle_t handle ); extern int send_client_fd( struct process *process, int fd, obj_handle_t handle );
extern void read_request( struct thread *thread ); extern void read_request( struct thread *thread );
......
...@@ -139,13 +139,4 @@ static inline const SID *sd_get_group( const struct security_descriptor *sd ) ...@@ -139,13 +139,4 @@ static inline const SID *sd_get_group( const struct security_descriptor *sd )
return NULL; return NULL;
} }
/* determines whether an object_attributes struct is valid in a buffer
* and calls set_error appropriately */
extern int objattr_is_valid( const struct object_attributes *objattr, data_size_t size );
static inline void objattr_get_name( const struct object_attributes *objattr, struct unicode_str *name )
{
name->len = ((objattr->name_len) / sizeof(WCHAR)) * sizeof(WCHAR);
name->str = (const WCHAR *)objattr + (sizeof(*objattr) + objattr->sd_len) / sizeof(WCHAR);
}
#endif /* __WINE_SERVER_SECURITY_H */ #endif /* __WINE_SERVER_SECURITY_H */
...@@ -179,16 +179,10 @@ DECL_HANDLER(create_semaphore) ...@@ -179,16 +179,10 @@ DECL_HANDLER(create_semaphore)
struct semaphore *sem; struct semaphore *sem;
struct unicode_str name; struct unicode_str name;
struct directory *root = NULL; struct directory *root = NULL;
const struct object_attributes *objattr = get_req_data();
const struct security_descriptor *sd; const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
reply->handle = 0; if (!objattr) return;
if (!objattr_is_valid( objattr, get_req_data_size() ))
return;
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
objattr_get_name( objattr, &name );
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
return; return;
......
...@@ -334,30 +334,6 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size ) ...@@ -334,30 +334,6 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
return TRUE; return TRUE;
} }
/* determines whether an object_attributes struct is valid in a buffer
* and calls set_error appropriately */
int objattr_is_valid( const struct object_attributes *objattr, data_size_t size )
{
if ((size < sizeof(*objattr)) || (size - sizeof(*objattr) < objattr->sd_len) ||
(size - sizeof(*objattr) - objattr->sd_len < objattr->name_len))
{
set_error( STATUS_ACCESS_VIOLATION );
return FALSE;
}
if (objattr->sd_len)
{
const struct security_descriptor *sd = (const struct security_descriptor *)(objattr + 1);
if (!sd_is_valid( sd, objattr->sd_len ))
{
set_error( STATUS_INVALID_SECURITY_DESCR );
return FALSE;
}
}
return TRUE;
}
/* maps from generic rights to specific rights as given by a mapping */ /* maps from generic rights to specific rights as given by a mapping */
static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping) static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping)
{ {
......
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