From 36cd6f5dbbcae12f91cab0a8af5e0ff880d44394 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Thu, 24 Jul 2003 00:07:00 +0000 Subject: [PATCH] Added a security token object in wineserver. --- dlls/ntdll/nt.c | 38 ++++++++++++--- include/wine/server_protocol.h | 21 +++++++- server/Makefile.in | 1 + server/object.h | 5 ++ server/process.c | 2 + server/process.h | 1 + server/protocol.def | 11 +++++ server/request.h | 2 + server/thread.c | 3 ++ server/thread.h | 1 + server/token.c | 89 ++++++++++++++++++++++++++++++++++ server/trace.c | 14 ++++++ 12 files changed, 179 insertions(+), 9 deletions(-) create mode 100644 server/token.c diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index ba2a6f88550..2686ad4f5ad 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -210,10 +210,20 @@ NTSTATUS WINAPI NtOpenProcessToken( DWORD DesiredAccess, HANDLE *TokenHandle) { - FIXME("(%p,0x%08lx,%p): stub\n", - ProcessHandle,DesiredAccess, TokenHandle); - *TokenHandle = (HANDLE)0xcafe; - return 0; + NTSTATUS ret; + + TRACE("(%p,0x%08lx,%p)\n", ProcessHandle,DesiredAccess, TokenHandle); + + SERVER_START_REQ( open_token ) + { + req->handle = ProcessHandle; + req->flags = 0; + ret = wine_server_call( req ); + if (!ret) *TokenHandle = reply->token; + } + SERVER_END_REQ; + + return ret; } /****************************************************************************** @@ -226,10 +236,22 @@ NTSTATUS WINAPI NtOpenThreadToken( BOOLEAN OpenAsSelf, HANDLE *TokenHandle) { - FIXME("(%p,0x%08lx,0x%08x,%p): stub\n", - ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle); - *TokenHandle = (HANDLE)0xcafe; - return 0; + NTSTATUS ret; + + TRACE("(%p,0x%08lx,0x%08x,%p)\n", + ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle); + + SERVER_START_REQ( open_token ) + { + req->handle = ThreadHandle; + req->flags = OPEN_TOKEN_THREAD; + if (OpenAsSelf) req->flags |= OPEN_TOKEN_AS_SELF; + ret = wine_server_call( req ); + if (!ret) *TokenHandle = reply->token; + } + SERVER_END_REQ; + + return ret; } /****************************************************************************** diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index f87ce73eddc..fe451abf117 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3082,6 +3082,22 @@ struct set_clipboard_info_reply #define CB_OWNER 0x080 + +struct open_token_request +{ + struct request_header __header; + obj_handle_t handle; + unsigned int flags; +}; +struct open_token_reply +{ + struct reply_header __header; + obj_handle_t token; +}; +#define OPEN_TOKEN_THREAD 1 +#define OPEN_TOKEN_AS_SELF 2 + + enum request { REQ_new_process, @@ -3260,6 +3276,7 @@ enum request REQ_finish_hook_chain, REQ_get_next_hook, REQ_set_clipboard_info, + REQ_open_token, REQ_NB_REQUESTS }; @@ -3443,6 +3460,7 @@ union generic_request struct finish_hook_chain_request finish_hook_chain_request; struct get_next_hook_request get_next_hook_request; struct set_clipboard_info_request set_clipboard_info_request; + struct open_token_request open_token_request; }; union generic_reply { @@ -3624,8 +3642,9 @@ union generic_reply struct finish_hook_chain_reply finish_hook_chain_reply; struct get_next_hook_reply get_next_hook_reply; struct set_clipboard_info_reply set_clipboard_info_reply; + struct open_token_reply open_token_reply; }; -#define SERVER_PROTOCOL_VERSION 116 +#define SERVER_PROTOCOL_VERSION 117 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/Makefile.in b/server/Makefile.in index 828b37f674c..1955d670d28 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -39,6 +39,7 @@ C_SRCS = \ sock.c \ thread.c \ timer.c \ + token.c \ trace.c \ unicode.c \ user.c \ diff --git a/server/object.h b/server/object.h index 1815e2495c1..0116b1fb477 100644 --- a/server/object.h +++ b/server/object.h @@ -38,6 +38,7 @@ struct object; struct object_name; struct thread; struct process; +struct token; struct file; struct wait_queue_entry; struct async; @@ -150,6 +151,10 @@ extern void registry_close_handle( struct object *obj, obj_handle_t hkey ); extern void init_signals(void); extern void close_signals(void); +/* token functions */ + +extern struct token *create_token(void); + /* atom functions */ extern void close_atom_table(void); diff --git a/server/process.c b/server/process.c index 3e6e9473fd0..333e11c2dd8 100644 --- a/server/process.c +++ b/server/process.c @@ -267,6 +267,7 @@ struct thread *create_process( int fd ) process->exe.namelen = 0; process->exe.filename = NULL; process->group_id = 0; + process->token = create_token(); list_init( &process->locks ); gettimeofday( &process->start_time, NULL ); @@ -405,6 +406,7 @@ static void process_destroy( struct object *obj ) if (process->exe.file) release_object( process->exe.file ); if (process->exe.filename) free( process->exe.filename ); if (process->id) free_ptid( process->id ); + if (process->token) release_object( process->token ); } /* dump a process on stdout for debugging purposes */ diff --git a/server/process.h b/server/process.h index b79982a7153..33ece35ccad 100644 --- a/server/process.h +++ b/server/process.h @@ -74,6 +74,7 @@ struct process struct event *idle_event; /* event for input idle */ struct msg_queue *queue; /* main message queue */ struct atom_table *atom_table; /* pointer to local atom table */ + struct token *token; /* security token associated with this process */ struct process_dll exe; /* main exe file */ void *ldt_copy; /* pointer to LDT copy in client addr space */ void *ldt_flags; /* pointer to LDT flags in client addr space */ diff --git a/server/protocol.def b/server/protocol.def index 7020c9cf83b..c3e37ccd819 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2160,3 +2160,14 @@ enum message_type #define SET_CB_CLOSE 0x020 #define CB_OPEN 0x040 #define CB_OWNER 0x080 + + +/* Open a security token */ +@REQ(open_token) + obj_handle_t handle; /* handle to the thread or process */ + unsigned int flags; /* flags (see below) */ +@REPLY + obj_handle_t token; /* handle to the token */ +@END +#define OPEN_TOKEN_THREAD 1 +#define OPEN_TOKEN_AS_SELF 2 diff --git a/server/request.h b/server/request.h index e28594effca..a25dc507272 100644 --- a/server/request.h +++ b/server/request.h @@ -279,6 +279,7 @@ DECL_HANDLER(start_hook_chain); DECL_HANDLER(finish_hook_chain); DECL_HANDLER(get_next_hook); DECL_HANDLER(set_clipboard_info); +DECL_HANDLER(open_token); #ifdef WANT_REQUEST_HANDLERS @@ -461,6 +462,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_finish_hook_chain, (req_handler)req_get_next_hook, (req_handler)req_set_clipboard_info, + (req_handler)req_open_token, }; #endif /* WANT_REQUEST_HANDLERS */ diff --git a/server/thread.c b/server/thread.c index 9a261da5681..6b451feec3f 100644 --- a/server/thread.c +++ b/server/thread.c @@ -178,6 +178,8 @@ struct thread *create_thread( int fd, struct process *process ) return NULL; } + thread->token = (struct token *) grab_object( process->token ); + set_fd_events( thread->request_fd, POLLIN ); /* start listening to events */ add_process_thread( thread->process, thread ); return thread; @@ -246,6 +248,7 @@ static void destroy_thread( struct object *obj ) cleanup_thread( thread ); release_object( thread->process ); if (thread->id) free_ptid( thread->id ); + if (thread->token) release_object( thread->token ); } /* dump a thread on stdout for debugging purposes */ diff --git a/server/thread.h b/server/thread.h index 2100518af49..9403ddfd3eb 100644 --- a/server/thread.h +++ b/server/thread.h @@ -92,6 +92,7 @@ struct thread int suspend; /* suspend count */ time_t creation_time; /* Thread creation time */ time_t exit_time; /* Thread exit time */ + struct token *token; /* security token associated with this thread */ }; struct thread_snapshot diff --git a/server/token.c b/server/token.c new file mode 100644 index 00000000000..67d42b436a9 --- /dev/null +++ b/server/token.c @@ -0,0 +1,89 @@ +/* + * Tokens + * + * Copyright (C) 1998 Alexandre Julliard + * Copyright (C) 2003 Mike McCormack + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include +#include +#include + +#include "windef.h" + +#include "handle.h" +#include "thread.h" +#include "process.h" +#include "request.h" + +struct token +{ + struct object obj; /* object header */ +}; + +static void token_dump( struct object *obj, int verbose ); + +static const struct object_ops token_ops = +{ + sizeof(struct token), /* size */ + token_dump, /* dump */ + no_add_queue, /* add_queue */ + NULL, /* remove_queue */ + NULL, /* signaled */ + NULL, /* satified */ + no_get_fd, /* get_fd */ + no_destroy /* destroy */ +}; + + +static void token_dump( struct object *obj, int verbose ) +{ + fprintf( stderr, "Security token\n" ); +} + +struct token *create_token( void ) +{ + struct token *token = alloc_object( &token_ops ); + return token; +} + +/* open a security token */ +DECL_HANDLER(open_token) +{ + if( req->flags & OPEN_TOKEN_THREAD ) + { + struct thread *thread = get_thread_from_handle( req->handle, 0 ); + if (thread) + { + if (thread->token) + reply->token = alloc_handle( current->process, thread->token, TOKEN_ALL_ACCESS, 0); + release_object( thread ); + } + } + else + { + struct process *process = get_process_from_handle( req->handle, 0 ); + if (process) + { + if (process->token) + reply->token = alloc_handle( current->process, process->token, TOKEN_ALL_ACCESS, 0); + release_object( process ); + } + } +} diff --git a/server/trace.c b/server/trace.c index bfab0824b94..d9f683353d7 100644 --- a/server/trace.c +++ b/server/trace.c @@ -2486,6 +2486,17 @@ static void dump_set_clipboard_info_reply( const struct set_clipboard_info_reply fprintf( stderr, " seqno=%08x", req->seqno ); } +static void dump_open_token_request( const struct open_token_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " flags=%08x", req->flags ); +} + +static void dump_open_token_reply( const struct open_token_reply *req ) +{ + fprintf( stderr, " token=%p", req->token ); +} + static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_new_process_request, (dump_func)dump_get_new_process_info_request, @@ -2663,6 +2674,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_finish_hook_chain_request, (dump_func)dump_get_next_hook_request, (dump_func)dump_set_clipboard_info_request, + (dump_func)dump_open_token_request, }; static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { @@ -2842,6 +2854,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)0, (dump_func)dump_get_next_hook_reply, (dump_func)dump_set_clipboard_info_reply, + (dump_func)dump_open_token_reply, }; static const char * const req_names[REQ_NB_REQUESTS] = { @@ -3021,6 +3034,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "finish_hook_chain", "get_next_hook", "set_clipboard_info", + "open_token", }; /* ### make_requests end ### */