server: Add a helper function to validate and return object attributes.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7350682aa6
commit
9504e2addf
|
@ -287,16 +287,10 @@ DECL_HANDLER(create_event)
|
|||
struct event *event;
|
||||
struct unicode_str name;
|
||||
struct directory *root = NULL;
|
||||
const struct object_attributes *objattr = get_req_data();
|
||||
const struct security_descriptor *sd;
|
||||
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
|
||||
|
||||
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) return;
|
||||
|
||||
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
|
||||
return;
|
||||
|
@ -378,13 +372,10 @@ DECL_HANDLER(create_keyed_event)
|
|||
struct keyed_event *event;
|
||||
struct unicode_str name;
|
||||
struct directory *root = NULL;
|
||||
const struct object_attributes *objattr = get_req_data();
|
||||
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;
|
||||
|
||||
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
|
||||
objattr_get_name( objattr, &name );
|
||||
if (!objattr) return;
|
||||
|
||||
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
|
||||
|
||||
|
|
|
@ -686,17 +686,16 @@ DECL_HANDLER(create_file)
|
|||
{
|
||||
struct object *file;
|
||||
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 object_attributes *objattr = get_req_object_attributes( &sd, &unicode_name );
|
||||
const char *name;
|
||||
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 */
|
||||
if (objattr->name_len)
|
||||
if (unicode_name.len)
|
||||
{
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
|
@ -712,8 +711,6 @@ DECL_HANDLER(create_file)
|
|||
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_len = get_req_data_size() - sizeof(*objattr) - objattr->sd_len;
|
||||
|
||||
|
|
|
@ -664,16 +664,10 @@ DECL_HANDLER(create_mapping)
|
|||
struct object *obj;
|
||||
struct unicode_str name;
|
||||
struct directory *root = NULL;
|
||||
const struct object_attributes *objattr = get_req_data();
|
||||
const struct security_descriptor *sd;
|
||||
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
|
||||
|
||||
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) return;
|
||||
|
||||
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
|
||||
return;
|
||||
|
|
|
@ -211,16 +211,10 @@ DECL_HANDLER(create_mutex)
|
|||
struct mutex *mutex;
|
||||
struct unicode_str name;
|
||||
struct directory *root = NULL;
|
||||
const struct object_attributes *objattr = get_req_data();
|
||||
const struct security_descriptor *sd;
|
||||
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
|
||||
|
||||
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) return;
|
||||
|
||||
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
|
||||
return;
|
||||
|
|
|
@ -923,8 +923,10 @@ DECL_HANDLER(create_named_pipe)
|
|||
struct pipe_server *server;
|
||||
struct unicode_str name;
|
||||
struct directory *root = NULL;
|
||||
const struct object_attributes *objattr = get_req_data();
|
||||
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)) ||
|
||||
(!(req->flags & NAMED_PIPE_MESSAGE_STREAM_WRITE) && (req->flags & NAMED_PIPE_MESSAGE_STREAM_READ)))
|
||||
|
@ -933,14 +935,6 @@ DECL_HANDLER(create_named_pipe)
|
|||
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 )))
|
||||
return;
|
||||
|
||||
|
|
|
@ -1539,13 +1539,10 @@ DECL_HANDLER(create_job)
|
|||
struct job *job;
|
||||
struct unicode_str name;
|
||||
struct directory *root = NULL;
|
||||
const struct object_attributes *objattr = get_req_data();
|
||||
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;
|
||||
|
||||
sd = objattr->sd_len ? (const struct security_descriptor *)(objattr + 1) : NULL;
|
||||
objattr_get_name( objattr, &name );
|
||||
if (!objattr) return;
|
||||
|
||||
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 ))) return;
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@
|
|||
|
||||
#include "file.h"
|
||||
#include "process.h"
|
||||
#include "thread.h"
|
||||
#include "security.h"
|
||||
#define WANT_REQUEST_HANDLERS
|
||||
#include "request.h"
|
||||
|
||||
|
@ -163,6 +165,31 @@ void *set_reply_data_size( data_size_t size )
|
|||
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 */
|
||||
void write_reply( struct thread *thread )
|
||||
{
|
||||
|
|
|
@ -46,6 +46,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 );
|
||||
extern int receive_fd( struct process *process );
|
||||
extern int send_client_fd( struct process *process, int fd, obj_handle_t handle );
|
||||
extern void read_request( struct thread *thread );
|
||||
|
|
|
@ -139,13 +139,4 @@ static inline const SID *sd_get_group( const struct security_descriptor *sd )
|
|||
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 */
|
||||
|
|
|
@ -179,16 +179,10 @@ DECL_HANDLER(create_semaphore)
|
|||
struct semaphore *sem;
|
||||
struct unicode_str name;
|
||||
struct directory *root = NULL;
|
||||
const struct object_attributes *objattr = get_req_data();
|
||||
const struct security_descriptor *sd;
|
||||
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name );
|
||||
|
||||
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) return;
|
||||
|
||||
if (objattr->rootdir && !(root = get_directory_obj( current->process, objattr->rootdir, 0 )))
|
||||
return;
|
||||
|
|
|
@ -334,30 +334,6 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
|
|||
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 */
|
||||
static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue