diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index fe4c96226d6..6b12d94e5eb 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -238,9 +238,18 @@ AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges, LPVOID NewState, DWORD BufferLength, LPVOID PreviousState, LPDWORD ReturnLength ) { - return set_ntstatus( NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges, + NTSTATUS status; + + TRACE("\n"); + + status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, - ReturnLength)); + ReturnLength); + SetLastError( RtlNtStatusToDosError( status )); + if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED)) + return TRUE; + else + return FALSE; } /****************************************************************************** @@ -2996,10 +3005,24 @@ BOOL WINAPI DuplicateTokenEx( TOKEN_TYPE TokenType, PHANDLE DuplicateTokenHandle ) { - FIXME("%p 0x%08lx 0x%08x 0x%08x %p - stub\n", ExistingTokenHandle, dwDesiredAccess, + OBJECT_ATTRIBUTES ObjectAttributes; + + TRACE("%p 0x%08lx 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess, ImpersonationLevel, TokenType, DuplicateTokenHandle); - return FALSE; + InitializeObjectAttributes( + &ObjectAttributes, + NULL, + (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0, + NULL, + lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL ); + + return set_ntstatus( NtDuplicateToken( ExistingTokenHandle, + dwDesiredAccess, + &ObjectAttributes, + ImpersonationLevel, + TokenType, + DuplicateTokenHandle ) ); } BOOL WINAPI DuplicateToken( diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index c359707ccdd..e70bf270a59 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -88,11 +88,26 @@ NTSTATUS WINAPI NtDuplicateToken( IN TOKEN_TYPE TokenType, OUT PHANDLE NewToken) { - FIXME("(%p,0x%08lx,%p,0x%08x,0x%08x,%p),stub!\n", - ExistingToken, DesiredAccess, ObjectAttributes, - ImpersonationLevel, TokenType, NewToken); - dump_ObjectAttributes(ObjectAttributes); - return 0; + NTSTATUS status; + + TRACE("(%p,0x%08lx,%p,0x%08x,0x%08x,%p)\n", + ExistingToken, DesiredAccess, ObjectAttributes, + ImpersonationLevel, TokenType, NewToken); + dump_ObjectAttributes(ObjectAttributes); + + SERVER_START_REQ( duplicate_token ) + { + req->handle = ExistingToken; + req->access = DesiredAccess; + req->inherit = ObjectAttributes && (ObjectAttributes->Attributes & OBJ_INHERIT); + req->primary = (TokenType == TokenPrimary); + req->impersonation_level = ImpersonationLevel; + status = wine_server_call( req ); + if (!status) *NewToken = reply->new_handle; + } + SERVER_END_REQ; + + return status; } /****************************************************************************** @@ -162,9 +177,34 @@ NTSTATUS WINAPI NtAdjustPrivilegesToken( OUT PTOKEN_PRIVILEGES PreviousState, OUT PDWORD ReturnLength) { - FIXME("(%p,0x%08x,%p,0x%08lx,%p,%p),stub!\n", - TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength); - return 0; + NTSTATUS ret; + + TRACE("(%p,0x%08x,%p,0x%08lx,%p,%p)\n", + TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength); + + SERVER_START_REQ( adjust_token_privileges ) + { + req->handle = TokenHandle; + req->disable_all = DisableAllPrivileges; + req->get_modified_state = (PreviousState != NULL); + if (!DisableAllPrivileges) + { + wine_server_add_data( req, &NewState->Privileges, + NewState->PrivilegeCount * sizeof(NewState->Privileges[0]) ); + } + if (PreviousState && BufferLength >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges )) + wine_server_set_reply( req, &PreviousState->Privileges, + BufferLength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) ); + ret = wine_server_call( req ); + if (PreviousState) + { + *ReturnLength = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ); + PreviousState->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES); + } + } + SERVER_END_REQ; + + return ret; } /****************************************************************************** @@ -185,6 +225,7 @@ NTSTATUS WINAPI NtQueryInformationToken( LPDWORD retlen ) { unsigned int len = 0; + NTSTATUS status = STATUS_SUCCESS; TRACE("(%p,%ld,%p,%ld,%p)\n", token,tokeninfoclass,tokeninfo,tokeninfolength,retlen); @@ -197,9 +238,6 @@ NTSTATUS WINAPI NtQueryInformationToken( case TokenGroups: len = sizeof(TOKEN_GROUPS); break; - case TokenPrivileges: - len = sizeof(TOKEN_PRIVILEGES); - break; case TokenOwner: len = sizeof(TOKEN_OWNER) + sizeof(SID); break; @@ -271,11 +309,17 @@ NTSTATUS WINAPI NtQueryInformationToken( } break; case TokenPrivileges: - if (tokeninfo) + SERVER_START_REQ( get_token_privileges ) { TOKEN_PRIVILEGES *tpriv = tokeninfo; - tpriv->PrivilegeCount = 1; + req->handle = token; + if (tpriv && tokeninfolength > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges )) + wine_server_set_reply( req, &tpriv->Privileges, tokeninfolength - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) ); + status = wine_server_call( req ); + *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len; + if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES); } + SERVER_END_REQ; break; case TokenOwner: if (tokeninfo) @@ -294,7 +338,7 @@ NTSTATUS WINAPI NtQueryInformationToken( return STATUS_NOT_IMPLEMENTED; } } - return 0; + return status; } /****************************************************************************** diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index b375e0b43a1..445ee70bc41 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -3171,6 +3171,50 @@ struct set_global_windows_reply #define SET_GLOBAL_TASKMAN_WINDOW 0x04 +struct adjust_token_privileges_request +{ + struct request_header __header; + obj_handle_t handle; + int disable_all; + int get_modified_state; + /* VARARG(privileges,LUID_AND_ATTRIBUTES); */ +}; +struct adjust_token_privileges_reply +{ + struct reply_header __header; + unsigned int len; + /* VARARG(privileges,LUID_AND_ATTRIBUTES); */ +}; + + +struct get_token_privileges_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct get_token_privileges_reply +{ + struct reply_header __header; + unsigned int len; + /* VARARG(privileges,LUID_AND_ATTRIBUTES); */ +}; + +struct duplicate_token_request +{ + struct request_header __header; + obj_handle_t handle; + unsigned int access; + int inherit; + int primary; + int impersonation_level; +}; +struct duplicate_token_reply +{ + struct reply_header __header; + obj_handle_t new_handle; +}; + + enum request { REQ_new_process, @@ -3353,6 +3397,9 @@ enum request REQ_set_clipboard_info, REQ_open_token, REQ_set_global_windows, + REQ_adjust_token_privileges, + REQ_get_token_privileges, + REQ_duplicate_token, REQ_NB_REQUESTS }; @@ -3540,6 +3587,9 @@ union generic_request struct set_clipboard_info_request set_clipboard_info_request; struct open_token_request open_token_request; struct set_global_windows_request set_global_windows_request; + struct adjust_token_privileges_request adjust_token_privileges_request; + struct get_token_privileges_request get_token_privileges_request; + struct duplicate_token_request duplicate_token_request; }; union generic_reply { @@ -3725,8 +3775,11 @@ union generic_reply struct set_clipboard_info_reply set_clipboard_info_reply; struct open_token_reply open_token_reply; struct set_global_windows_reply set_global_windows_reply; + struct adjust_token_privileges_reply adjust_token_privileges_reply; + struct get_token_privileges_reply get_token_privileges_reply; + struct duplicate_token_reply duplicate_token_reply; }; -#define SERVER_PROTOCOL_VERSION 156 +#define SERVER_PROTOCOL_VERSION 157 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/include/winnt.h b/include/winnt.h index 1dbe3affc06..4abae5c41be 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -2808,6 +2808,7 @@ typedef struct _ACL_SIZE_INFORMATION #define SE_PRIVILEGE_ENABLED_BY_DEFAULT 0x00000001 #define SE_PRIVILEGE_ENABLED 0x00000002 +#define SE_PRIVILEGE_REMOVE 0x00000004 #define SE_PRIVILEGE_USED_FOR_ACCESS 0x80000000 #define SE_OWNER_DEFAULTED 0x00000001 diff --git a/include/winternl.h b/include/winternl.h index cd202ea4e3e..23c4b27e038 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1396,6 +1396,7 @@ NTSTATUS WINAPI NtDeleteKey(HKEY); NTSTATUS WINAPI NtDeleteValueKey(HKEY,const UNICODE_STRING *); NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,PVOID,ULONG,PVOID,ULONG); NTSTATUS WINAPI NtDuplicateObject(HANDLE,HANDLE,HANDLE,PHANDLE,ACCESS_MASK,ULONG,ULONG); +NTSTATUS WINAPI NtDuplicateToken(HANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE); NTSTATUS WINAPI NtEnumerateKey(HKEY,ULONG,KEY_INFORMATION_CLASS,void *,DWORD,DWORD *); NTSTATUS WINAPI NtEnumerateValueKey(HKEY,ULONG,KEY_VALUE_INFORMATION_CLASS,PVOID,ULONG,PULONG); NTSTATUS WINAPI NtFlushBuffersFile(HANDLE,IO_STATUS_BLOCK*); diff --git a/server/object.h b/server/object.h index e3c2a5db922..c42b49c8408 100644 --- a/server/object.h +++ b/server/object.h @@ -153,7 +153,7 @@ extern void close_signals(void); /* token functions */ -extern struct token *create_token(void); +extern struct token *create_admin_token(void); /* atom functions */ diff --git a/server/process.c b/server/process.c index fc69e507232..36cf4c1e1fc 100644 --- a/server/process.c +++ b/server/process.c @@ -278,7 +278,7 @@ struct thread *create_process( int fd ) process->exe.namelen = 0; process->exe.filename = NULL; process->group_id = 0; - process->token = create_token(); + process->token = create_admin_token(); list_init( &process->locks ); list_init( &process->classes ); diff --git a/server/protocol.def b/server/protocol.def index 94af8adb911..1de26074241 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2229,3 +2229,32 @@ enum message_type #define SET_GLOBAL_SHELL_WINDOWS 0x01 /* set both main shell and listview windows */ #define SET_GLOBAL_PROGMAN_WINDOW 0x02 #define SET_GLOBAL_TASKMAN_WINDOW 0x04 + +/* Adjust the privileges held by a token */ +@REQ(adjust_token_privileges) + obj_handle_t handle; /* handle to the token */ + int disable_all; /* disable all privileges? */ + int get_modified_state; /* get modified privileges? */ + VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges to enable/disable/remove */ +@REPLY + unsigned int len; /* total length in bytes required to store token privileges */ + VARARG(privileges,LUID_AND_ATTRIBUTES); /* modified privileges */ +@END + +/* Retrieves the set of privileges held by or available to a token */ +@REQ(get_token_privileges) + obj_handle_t handle; /* handle to the token */ +@REPLY + unsigned int len; /* total length in bytes required to store token privileges */ + VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges held by or available to a token */ +@END + +@REQ(duplicate_token) + obj_handle_t handle; /* handle to the token to duplicate */ + unsigned int access; /* access rights to the new token */ + int inherit; /* inherit flag */ + int primary; /* is the new token to be a primary one? */ + int impersonation_level; /* impersonation level of the new token */ +@REPLY + obj_handle_t new_handle; /* duplicated handle */ +@END diff --git a/server/request.h b/server/request.h index 2b779196966..3902c7b2555 100644 --- a/server/request.h +++ b/server/request.h @@ -283,6 +283,9 @@ DECL_HANDLER(set_class_info); DECL_HANDLER(set_clipboard_info); DECL_HANDLER(open_token); DECL_HANDLER(set_global_windows); +DECL_HANDLER(adjust_token_privileges); +DECL_HANDLER(get_token_privileges); +DECL_HANDLER(duplicate_token); #ifdef WANT_REQUEST_HANDLERS @@ -469,6 +472,9 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_set_clipboard_info, (req_handler)req_open_token, (req_handler)req_set_global_windows, + (req_handler)req_adjust_token_privileges, + (req_handler)req_get_token_privileges, + (req_handler)req_duplicate_token, }; #endif /* WANT_REQUEST_HANDLERS */ diff --git a/server/token.c b/server/token.c index 67d42b436a9..94a2167622b 100644 --- a/server/token.c +++ b/server/token.c @@ -35,9 +35,19 @@ struct token { struct object obj; /* object header */ + struct list privileges; /* privileges available to the token */ +}; + +struct privilege +{ + struct list entry; + LUID luid; + int enabled : 1; /* is the privilege currently enabled? */ + int def : 1; /* is the privilege enabled by default? */ }; static void token_dump( struct object *obj, int verbose ); +static void token_destroy( struct object *obj ); static const struct object_ops token_ops = { @@ -48,7 +58,7 @@ static const struct object_ops token_ops = NULL, /* signaled */ NULL, /* satified */ no_get_fd, /* get_fd */ - no_destroy /* destroy */ + token_destroy /* destroy */ }; @@ -57,12 +67,163 @@ static void token_dump( struct object *obj, int verbose ) fprintf( stderr, "Security token\n" ); } -struct token *create_token( void ) +static inline int is_equal_luid( const LUID *luid1, const LUID *luid2 ) +{ + return (luid1->LowPart == luid2->LowPart && luid1->HighPart == luid2->HighPart); +} + +static inline void luid_and_attr_from_privilege( LUID_AND_ATTRIBUTES *out, const struct privilege *in) +{ + out->Luid = in->luid; + out->Attributes = + (in->enabled ? SE_PRIVILEGE_ENABLED : 0) | + (in->def ? SE_PRIVILEGE_ENABLED_BY_DEFAULT : 0); +} + +static struct privilege *privilege_add( struct token *token, const LUID *luid, int enabled ) +{ + struct privilege *privilege = mem_alloc( sizeof(*privilege) ); + if (privilege) + { + privilege->luid = *luid; + privilege->def = privilege->enabled = (enabled != 0); + list_add_tail( &token->privileges, &privilege->entry ); + } + return privilege; +} + +static void privilege_remove( struct privilege *privilege ) +{ + list_remove( &privilege->entry ); + free( privilege ); +} + +static void token_destroy( struct object *obj ) +{ + struct token* token; + struct list *cursor, *cursor_next; + + assert( obj->ops == &token_ops ); + token = (struct token *)obj; + + LIST_FOR_EACH_SAFE( cursor, cursor_next, &token->privileges ) + { + struct privilege *privilege = LIST_ENTRY( cursor, struct privilege, entry ); + privilege_remove( privilege ); + } +} + +static struct token *create_token( const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count ) { struct token *token = alloc_object( &token_ops ); + if (token) + { + int i; + list_init( &token->privileges ); + for (i = 0; i < priv_count; i++) + { + /* note: we don't check uniqueness: the caller must make sure + * privs doesn't contain any duplicate luids */ + if (!privilege_add( token, &privs[i].Luid, + privs[i].Attributes & SE_PRIVILEGE_ENABLED )) + { + release_object( token ); + return NULL; + } + } + } return token; } +struct token *create_admin_token( void ) +{ + static const LUID_AND_ATTRIBUTES admin_privs[] = + { + { { 23, 0 }, SE_PRIVILEGE_ENABLED }, /* SeChangeNotifyPrivilege */ + { { 8, 0 }, 0 }, /* SeSecurityPrivilege */ + { { 17, 0 }, 0 }, /* SeBackupPrivilege */ + { { 18, 0 }, 0 }, /* SeRestorePrivilege */ + { { 12, 0 }, 0 }, /* SeSystemtimePrivilege */ + { { 19, 0 }, 0 }, /* SeShutdownPrivilege */ + { { 24, 0 }, 0 }, /* SeRemoteShutdownPrivilege */ + { { 9, 0 }, 0 }, /* SeTakeOwnershipPrivilege */ + { { 20, 0 }, 0 }, /* SeDebugPrivilege */ + { { 22, 0 }, 0 }, /* SeSystemEnvironmentPrivilege */ + { { 11, 0 }, 0 }, /* SeSystemProfilePrivilege */ + { { 13, 0 }, 0 }, /* SeProfileSingleProcessPrivilege */ + { { 14, 0 }, 0 }, /* SeIncreaseBasePriorityPrivilege */ + { { 10, 0 }, 0 }, /* SeLoadDriverPrivilege */ + { { 15, 0 }, 0 }, /* SeCreatePagefilePrivilege */ + { { 5, 0 }, 0 }, /* SeIncreaseQuotaPrivilege */ + { { 25, 0 }, 0 }, /* SeUndockPrivilege */ + { { 28, 0 }, 0 }, /* SeManageVolumePrivilege */ + { { 29, 0 }, SE_PRIVILEGE_ENABLED }, /* SeImpersonatePrivilege */ + { { 30, 0 }, SE_PRIVILEGE_ENABLED }, /* SeCreateGlobalPrivilege */ + }; + return create_token( admin_privs, sizeof(admin_privs)/sizeof(admin_privs[0]) ); +} + +static struct privilege *token_find_privilege( struct token *token, const LUID *luid, int enabled_only) +{ + struct privilege *privilege; + LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry ) + { + if (is_equal_luid( luid, &privilege->luid )) + { + if (enabled_only && !privilege->enabled) + return NULL; + return privilege; + } + } + return NULL; +} + +static unsigned int token_adjust_privileges( struct token *token, const LUID_AND_ATTRIBUTES *privs, + unsigned int count, LUID_AND_ATTRIBUTES *mod_privs, + unsigned int mod_privs_count) +{ + int i; + unsigned int modified_count = 0; + + for (i = 0; i < count; i++) + { + struct privilege *privilege = + token_find_privilege( token, &privs[i].Luid, FALSE ); + if (!privilege) + { + set_error( STATUS_NOT_ALL_ASSIGNED ); + continue; + } + + if (privs[i].Attributes & SE_PRIVILEGE_REMOVE) + privilege_remove( privilege ); + else + { + /* save previous state for caller */ + if (mod_privs_count) + { + luid_and_attr_from_privilege(mod_privs, privilege); + mod_privs++; + mod_privs_count--; + modified_count++; + } + + if (privs[i].Attributes & SE_PRIVILEGE_ENABLED) + privilege->enabled = TRUE; + else + privilege->enabled = FALSE; + } + } + return modified_count; +} + +static void token_disable_privileges( struct token *token ) +{ + struct privilege *privilege; + LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry ) + privilege->enabled = FALSE; +} + /* open a security token */ DECL_HANDLER(open_token) { @@ -73,6 +234,8 @@ DECL_HANDLER(open_token) { if (thread->token) reply->token = alloc_handle( current->process, thread->token, TOKEN_ALL_ACCESS, 0); + else + set_error(STATUS_NO_TOKEN); release_object( thread ); } } @@ -83,7 +246,117 @@ DECL_HANDLER(open_token) { if (process->token) reply->token = alloc_handle( current->process, process->token, TOKEN_ALL_ACCESS, 0); + else + set_error(STATUS_NO_TOKEN); release_object( process ); } } } + +/* adjust the privileges held by a token */ +DECL_HANDLER(adjust_token_privileges) +{ + struct token *token; + unsigned int access = TOKEN_ADJUST_PRIVILEGES; + + if (req->get_modified_state) access |= TOKEN_QUERY; + + if ((token = (struct token *)get_handle_obj( current->process, req->handle, + access, &token_ops ))) + { + const LUID_AND_ATTRIBUTES *privs = get_req_data(); + LUID_AND_ATTRIBUTES *modified_privs = NULL; + unsigned int priv_count = get_req_data_size() / sizeof(LUID_AND_ATTRIBUTES); + unsigned int modified_priv_count = 0; + + if (req->get_modified_state && !req->disable_all) + { + int i; + /* count modified privs */ + for (i = 0; i < priv_count; i++) + { + struct privilege *privilege = + token_find_privilege( token, &privs[i].Luid, FALSE ); + if (privilege && req->get_modified_state) + modified_priv_count++; + } + reply->len = modified_priv_count; + modified_priv_count = min( modified_priv_count, get_reply_max_size() / sizeof(*modified_privs) ); + if (modified_priv_count) + modified_privs = set_reply_data_size( modified_priv_count * sizeof(*modified_privs) ); + } + reply->len = modified_priv_count * sizeof(*modified_privs); + + if (req->disable_all) + token_disable_privileges( token ); + else + modified_priv_count = token_adjust_privileges( token, privs, + priv_count, modified_privs, modified_priv_count ); + + release_object( token ); + } +} + +/* retrieves the list of privileges that may be held be the token */ +DECL_HANDLER(get_token_privileges) +{ + struct token *token; + + if ((token = (struct token *)get_handle_obj( current->process, req->handle, + TOKEN_QUERY, + &token_ops ))) + { + int priv_count = 0; + LUID_AND_ATTRIBUTES *privs; + struct privilege *privilege; + + LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry ) + priv_count++; + + reply->len = priv_count * sizeof(*privs); + if (reply->len <= get_reply_max_size()) + { + privs = set_reply_data_size( priv_count * sizeof(*privs) ); + if (privs) + { + int i = 0; + LIST_FOR_EACH_ENTRY( privilege, &token->privileges, struct privilege, entry ) + { + luid_and_attr_from_privilege( &privs[i], privilege ); + i++; + } + } + } + else + set_error(STATUS_BUFFER_TOO_SMALL); + + release_object( token ); + } +} + +/* creates a duplicate of the token */ +DECL_HANDLER(duplicate_token) +{ + struct token *src_token; + if ((src_token = (struct token *)get_handle_obj( current->process, req->handle, + TOKEN_DUPLICATE, + &token_ops ))) + { + /* FIXME: use req->primary and req->impersonation_level */ + struct token *token = create_token( NULL, 0 ); + if (token) + { + struct privilege *privilege; + unsigned int access; + + LIST_FOR_EACH_ENTRY( privilege, &src_token->privileges, struct privilege, entry ) + privilege_add( token, &privilege->luid, privilege->enabled ); + + access = req->access; + if (access & MAXIMUM_ALLOWED) access = TOKEN_ALL_ACCESS; /* FIXME: needs general solution */ + reply->new_handle = alloc_handle( current->process, token, access, req->inherit); + release_object( token ); + } + release_object( src_token ); + } +} diff --git a/server/trace.c b/server/trace.c index b4990130385..bfd69191b04 100644 --- a/server/trace.c +++ b/server/trace.c @@ -407,6 +407,23 @@ static void dump_varargs_properties( size_t size ) remove_data( size ); } +static void dump_varargs_LUID_AND_ATTRIBUTES( size_t size ) +{ + const LUID_AND_ATTRIBUTES *lat = cur_data; + size_t len = size / sizeof(*lat); + + fputc( '{', stderr ); + while (len > 0) + { + fprintf( stderr, "{luid=%08lx%08lx,attr=%lx}", + lat->Luid.HighPart, lat->Luid.LowPart, lat->Attributes ); + lat++; + if (--len) fputc( ',', stderr ); + } + fputc( '}', stderr ); + remove_data( size ); +} + typedef void (*dump_func)( const void *req ); /* Everything below this line is generated automatically by tools/make_requests */ @@ -2623,6 +2640,48 @@ static void dump_set_global_windows_reply( const struct set_global_windows_reply fprintf( stderr, " old_taskman_window=%p", req->old_taskman_window ); } +static void dump_adjust_token_privileges_request( const struct adjust_token_privileges_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " disable_all=%d,", req->disable_all ); + fprintf( stderr, " get_modified_state=%d,", req->get_modified_state ); + fprintf( stderr, " privileges=" ); + dump_varargs_LUID_AND_ATTRIBUTES( cur_size ); +} + +static void dump_adjust_token_privileges_reply( const struct adjust_token_privileges_reply *req ) +{ + fprintf( stderr, " len=%08x,", req->len ); + fprintf( stderr, " privileges=" ); + dump_varargs_LUID_AND_ATTRIBUTES( cur_size ); +} + +static void dump_get_token_privileges_request( const struct get_token_privileges_request *req ) +{ + fprintf( stderr, " handle=%p", req->handle ); +} + +static void dump_get_token_privileges_reply( const struct get_token_privileges_reply *req ) +{ + fprintf( stderr, " len=%08x,", req->len ); + fprintf( stderr, " privileges=" ); + dump_varargs_LUID_AND_ATTRIBUTES( cur_size ); +} + +static void dump_duplicate_token_request( const struct duplicate_token_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " access=%08x,", req->access ); + fprintf( stderr, " inherit=%d,", req->inherit ); + fprintf( stderr, " primary=%d,", req->primary ); + fprintf( stderr, " impersonation_level=%d", req->impersonation_level ); +} + +static void dump_duplicate_token_reply( const struct duplicate_token_reply *req ) +{ + fprintf( stderr, " new_handle=%p", req->new_handle ); +} + static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_new_process_request, (dump_func)dump_get_new_process_info_request, @@ -2804,6 +2863,9 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_set_clipboard_info_request, (dump_func)dump_open_token_request, (dump_func)dump_set_global_windows_request, + (dump_func)dump_adjust_token_privileges_request, + (dump_func)dump_get_token_privileges_request, + (dump_func)dump_duplicate_token_request, }; static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { @@ -2987,6 +3049,9 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_set_clipboard_info_reply, (dump_func)dump_open_token_reply, (dump_func)dump_set_global_windows_reply, + (dump_func)dump_adjust_token_privileges_reply, + (dump_func)dump_get_token_privileges_reply, + (dump_func)dump_duplicate_token_reply, }; static const char * const req_names[REQ_NB_REQUESTS] = { @@ -3170,6 +3235,9 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "set_clipboard_info", "open_token", "set_global_windows", + "adjust_token_privileges", + "get_token_privileges", + "duplicate_token", }; /* ### make_requests end ### */