wined3d: Correctly destroy the adapter on format initialization failure in no3d mode.
[wine/zf.git] / dlls / ntdll / unix / security.c
blobdaecc5e0591b1de80a377b5e7d71c0eec8961616
1 /*
2 * Security functions
4 * Copyright 1996-1998 Marcus Meissner
5 * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #if 0
23 #pragma makedep unix
24 #endif
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include "ntstatus.h"
31 #define WIN32_NO_STATUS
32 #include "windef.h"
33 #include "unix_private.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
39 /***********************************************************************
40 * NtOpenProcessToken (NTDLL.@)
42 NTSTATUS WINAPI NtOpenProcessToken( HANDLE process, DWORD access, HANDLE *handle )
44 return NtOpenProcessTokenEx( process, access, 0, handle );
48 /***********************************************************************
49 * NtOpenProcessTokenEx (NTDLL.@)
51 NTSTATUS WINAPI NtOpenProcessTokenEx( HANDLE process, DWORD access, DWORD attributes, HANDLE *handle )
53 NTSTATUS ret;
55 TRACE( "(%p,0x%08x,0x%08x,%p)\n", process, access, attributes, handle );
57 SERVER_START_REQ( open_token )
59 req->handle = wine_server_obj_handle( process );
60 req->access = access;
61 req->attributes = attributes;
62 req->flags = 0;
63 ret = wine_server_call( req );
64 if (!ret) *handle = wine_server_ptr_handle( reply->token );
66 SERVER_END_REQ;
67 return ret;
71 /***********************************************************************
72 * NtOpenThreadToken (NTDLL.@)
74 NTSTATUS WINAPI NtOpenThreadToken( HANDLE thread, DWORD access, BOOLEAN self, HANDLE *handle )
76 return NtOpenThreadTokenEx( thread, access, self, 0, handle );
80 /***********************************************************************
81 * NtOpenThreadTokenEx (NTDLL.@)
83 NTSTATUS WINAPI NtOpenThreadTokenEx( HANDLE thread, DWORD access, BOOLEAN self, DWORD attributes,
84 HANDLE *handle )
86 NTSTATUS ret;
88 TRACE( "(%p,0x%08x,%u,0x%08x,%p)\n", thread, access, self, attributes, handle );
90 SERVER_START_REQ( open_token )
92 req->handle = wine_server_obj_handle( thread );
93 req->access = access;
94 req->attributes = attributes;
95 req->flags = OPEN_TOKEN_THREAD;
96 if (self) req->flags |= OPEN_TOKEN_AS_SELF;
97 ret = wine_server_call( req );
98 if (!ret) *handle = wine_server_ptr_handle( reply->token );
100 SERVER_END_REQ;
101 return ret;
105 /***********************************************************************
106 * NtDuplicateToken (NTDLL.@)
108 NTSTATUS WINAPI NtDuplicateToken( HANDLE token, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
109 SECURITY_IMPERSONATION_LEVEL level, TOKEN_TYPE type, HANDLE *handle )
111 NTSTATUS status;
112 data_size_t len;
113 struct object_attributes *objattr;
115 if ((status = alloc_object_attributes( attr, &objattr, &len ))) return status;
117 if (attr && attr->SecurityQualityOfService)
119 SECURITY_QUALITY_OF_SERVICE *qos = attr->SecurityQualityOfService;
120 TRACE( "ObjectAttributes->SecurityQualityOfService = {%d, %d, %d, %s}\n",
121 qos->Length, qos->ImpersonationLevel, qos->ContextTrackingMode,
122 qos->EffectiveOnly ? "TRUE" : "FALSE");
123 level = qos->ImpersonationLevel;
126 SERVER_START_REQ( duplicate_token )
128 req->handle = wine_server_obj_handle( token );
129 req->access = access;
130 req->primary = (type == TokenPrimary);
131 req->impersonation_level = level;
132 wine_server_add_data( req, objattr, len );
133 status = wine_server_call( req );
134 if (!status) *handle = wine_server_ptr_handle( reply->new_handle );
136 SERVER_END_REQ;
137 free( objattr );
138 return status;
142 /***********************************************************************
143 * NtQueryInformationToken (NTDLL.@)
145 NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS class,
146 void *info, ULONG length, ULONG *retlen )
148 static const ULONG info_len [] =
151 0, /* TokenUser */
152 0, /* TokenGroups */
153 0, /* TokenPrivileges */
154 0, /* TokenOwner */
155 0, /* TokenPrimaryGroup */
156 0, /* TokenDefaultDacl */
157 sizeof(TOKEN_SOURCE), /* TokenSource */
158 sizeof(TOKEN_TYPE), /* TokenType */
159 sizeof(SECURITY_IMPERSONATION_LEVEL), /* TokenImpersonationLevel */
160 sizeof(TOKEN_STATISTICS), /* TokenStatistics */
161 0, /* TokenRestrictedSids */
162 sizeof(DWORD), /* TokenSessionId */
163 0, /* TokenGroupsAndPrivileges */
164 0, /* TokenSessionReference */
165 0, /* TokenSandBoxInert */
166 0, /* TokenAuditPolicy */
167 0, /* TokenOrigin */
168 sizeof(TOKEN_ELEVATION_TYPE), /* TokenElevationType */
169 0, /* TokenLinkedToken */
170 sizeof(TOKEN_ELEVATION), /* TokenElevation */
171 0, /* TokenHasRestrictions */
172 0, /* TokenAccessInformation */
173 0, /* TokenVirtualizationAllowed */
174 sizeof(DWORD), /* TokenVirtualizationEnabled */
175 sizeof(TOKEN_MANDATORY_LABEL) + sizeof(SID), /* TokenIntegrityLevel [sizeof(SID) includes one SubAuthority] */
176 0, /* TokenUIAccess */
177 0, /* TokenMandatoryPolicy */
178 0, /* TokenLogonSid */
179 sizeof(DWORD), /* TokenIsAppContainer */
180 0, /* TokenCapabilities */
181 sizeof(TOKEN_APPCONTAINER_INFORMATION) + sizeof(SID), /* TokenAppContainerSid */
182 0, /* TokenAppContainerNumber */
183 0, /* TokenUserClaimAttributes*/
184 0, /* TokenDeviceClaimAttributes */
185 0, /* TokenRestrictedUserClaimAttributes */
186 0, /* TokenRestrictedDeviceClaimAttributes */
187 0, /* TokenDeviceGroups */
188 0, /* TokenRestrictedDeviceGroups */
189 0, /* TokenSecurityAttributes */
190 0, /* TokenIsRestricted */
191 0 /* TokenProcessTrustLevel */
194 ULONG len = 0;
195 NTSTATUS status = STATUS_SUCCESS;
197 TRACE( "(%p,%d,%p,%d,%p)\n", token, class, info, length, retlen );
199 if (class < MaxTokenInfoClass) len = info_len[class];
200 if (retlen) *retlen = len;
201 if (length < len) return STATUS_BUFFER_TOO_SMALL;
203 switch (class)
205 case TokenUser:
206 SERVER_START_REQ( get_token_sid )
208 TOKEN_USER *tuser = info;
209 PSID sid = tuser + 1;
210 DWORD sid_len = length < sizeof(TOKEN_USER) ? 0 : length - sizeof(TOKEN_USER);
212 req->handle = wine_server_obj_handle( token );
213 req->which_sid = class;
214 wine_server_set_reply( req, sid, sid_len );
215 status = wine_server_call( req );
216 if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_USER);
217 if (status == STATUS_SUCCESS)
219 tuser->User.Sid = sid;
220 tuser->User.Attributes = 0;
223 SERVER_END_REQ;
224 break;
226 case TokenGroups:
228 /* reply buffer is always shorter than output one */
229 void *buffer = malloc( length );
231 SERVER_START_REQ( get_token_groups )
233 TOKEN_GROUPS *groups = info;
235 req->handle = wine_server_obj_handle( token );
236 wine_server_set_reply( req, buffer, length );
237 status = wine_server_call( req );
238 if (status == STATUS_BUFFER_TOO_SMALL)
240 if (retlen) *retlen = reply->user_len;
242 else if (status == STATUS_SUCCESS)
244 struct token_groups *tg = buffer;
245 unsigned int *attr = (unsigned int *)(tg + 1);
246 ULONG i;
247 const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned int));
248 SID *sids = (SID *)((char *)info + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
250 if (retlen) *retlen = reply->user_len;
252 groups->GroupCount = tg->count;
253 memcpy( sids, (char *)buffer + non_sid_portion,
254 reply->user_len - offsetof( TOKEN_GROUPS, Groups[tg->count] ));
256 for (i = 0; i < tg->count; i++)
258 groups->Groups[i].Attributes = attr[i];
259 groups->Groups[i].Sid = sids;
260 sids = (SID *)((char *)sids + offsetof( SID, SubAuthority[sids->SubAuthorityCount] ));
263 else if (retlen) *retlen = 0;
265 SERVER_END_REQ;
266 free( buffer );
267 break;
270 case TokenPrimaryGroup:
271 SERVER_START_REQ( get_token_sid )
273 TOKEN_PRIMARY_GROUP *tgroup = info;
274 PSID sid = tgroup + 1;
275 DWORD sid_len = length < sizeof(TOKEN_PRIMARY_GROUP) ? 0 : length - sizeof(TOKEN_PRIMARY_GROUP);
277 req->handle = wine_server_obj_handle( token );
278 req->which_sid = class;
279 wine_server_set_reply( req, sid, sid_len );
280 status = wine_server_call( req );
281 if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_PRIMARY_GROUP);
282 if (status == STATUS_SUCCESS) tgroup->PrimaryGroup = sid;
284 SERVER_END_REQ;
285 break;
287 case TokenPrivileges:
288 SERVER_START_REQ( get_token_privileges )
290 TOKEN_PRIVILEGES *tpriv = info;
291 req->handle = wine_server_obj_handle( token );
292 if (tpriv && length > FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
293 wine_server_set_reply( req, tpriv->Privileges, length - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
294 status = wine_server_call( req );
295 if (retlen) *retlen = FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) + reply->len;
296 if (tpriv) tpriv->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
298 SERVER_END_REQ;
299 break;
301 case TokenOwner:
302 SERVER_START_REQ( get_token_sid )
304 TOKEN_OWNER *towner = info;
305 PSID sid = towner + 1;
306 DWORD sid_len = length < sizeof(TOKEN_OWNER) ? 0 : length - sizeof(TOKEN_OWNER);
308 req->handle = wine_server_obj_handle( token );
309 req->which_sid = class;
310 wine_server_set_reply( req, sid, sid_len );
311 status = wine_server_call( req );
312 if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_OWNER);
313 if (status == STATUS_SUCCESS) towner->Owner = sid;
315 SERVER_END_REQ;
316 break;
318 case TokenImpersonationLevel:
319 SERVER_START_REQ( get_token_impersonation_level )
321 SECURITY_IMPERSONATION_LEVEL *level = info;
322 req->handle = wine_server_obj_handle( token );
323 status = wine_server_call( req );
324 if (status == STATUS_SUCCESS) *level = reply->impersonation_level;
326 SERVER_END_REQ;
327 break;
329 case TokenStatistics:
330 SERVER_START_REQ( get_token_statistics )
332 TOKEN_STATISTICS *statistics = info;
333 req->handle = wine_server_obj_handle( token );
334 status = wine_server_call( req );
335 if (status == STATUS_SUCCESS)
337 statistics->TokenId.LowPart = reply->token_id.low_part;
338 statistics->TokenId.HighPart = reply->token_id.high_part;
339 statistics->AuthenticationId.LowPart = 0; /* FIXME */
340 statistics->AuthenticationId.HighPart = 0; /* FIXME */
341 statistics->ExpirationTime.u.HighPart = 0x7fffffff;
342 statistics->ExpirationTime.u.LowPart = 0xffffffff;
343 statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation;
344 statistics->ImpersonationLevel = reply->impersonation_level;
346 /* kernel information not relevant to us */
347 statistics->DynamicCharged = 0;
348 statistics->DynamicAvailable = 0;
350 statistics->GroupCount = reply->group_count;
351 statistics->PrivilegeCount = reply->privilege_count;
352 statistics->ModifiedId.LowPart = reply->modified_id.low_part;
353 statistics->ModifiedId.HighPart = reply->modified_id.high_part;
356 SERVER_END_REQ;
357 break;
359 case TokenType:
360 SERVER_START_REQ( get_token_statistics )
362 TOKEN_TYPE *type = info;
363 req->handle = wine_server_obj_handle( token );
364 status = wine_server_call( req );
365 if (status == STATUS_SUCCESS) *type = reply->primary ? TokenPrimary : TokenImpersonation;
367 SERVER_END_REQ;
368 break;
370 case TokenDefaultDacl:
371 SERVER_START_REQ( get_token_default_dacl )
373 TOKEN_DEFAULT_DACL *default_dacl = info;
374 ACL *acl = (ACL *)(default_dacl + 1);
375 DWORD acl_len = length < sizeof(TOKEN_DEFAULT_DACL) ? 0 : length - sizeof(TOKEN_DEFAULT_DACL);
377 req->handle = wine_server_obj_handle( token );
378 wine_server_set_reply( req, acl, acl_len );
379 status = wine_server_call( req );
380 if (retlen) *retlen = reply->acl_len + sizeof(TOKEN_DEFAULT_DACL);
381 if (status == STATUS_SUCCESS)
383 if (reply->acl_len)
384 default_dacl->DefaultDacl = acl;
385 else
386 default_dacl->DefaultDacl = NULL;
389 SERVER_END_REQ;
390 break;
392 case TokenElevationType:
394 TOKEN_ELEVATION_TYPE *type = info;
395 FIXME("QueryInformationToken( ..., TokenElevationType, ...) semi-stub\n");
396 *type = TokenElevationTypeFull;
398 break;
400 case TokenElevation:
402 TOKEN_ELEVATION *elevation = info;
403 FIXME("QueryInformationToken( ..., TokenElevation, ...) semi-stub\n");
404 elevation->TokenIsElevated = TRUE;
406 break;
408 case TokenSessionId:
410 *(DWORD *)info = 0;
411 FIXME("QueryInformationToken( ..., TokenSessionId, ...) semi-stub\n");
413 break;
415 case TokenVirtualizationEnabled:
417 *(DWORD *)info = 0;
418 TRACE("QueryInformationToken( ..., TokenVirtualizationEnabled, ...) semi-stub\n");
420 break;
422 case TokenIntegrityLevel:
424 /* report always "S-1-16-12288" (high mandatory level) for now */
425 static const SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
426 {SECURITY_MANDATORY_HIGH_RID}};
428 TOKEN_MANDATORY_LABEL *tml = info;
429 PSID psid = tml + 1;
431 tml->Label.Sid = psid;
432 tml->Label.Attributes = SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED;
433 memcpy( psid, &high_level, sizeof(SID) );
435 break;
437 case TokenAppContainerSid:
439 TOKEN_APPCONTAINER_INFORMATION *container = info;
440 FIXME("QueryInformationToken( ..., TokenAppContainerSid, ...) semi-stub\n");
441 container->TokenAppContainer = NULL;
443 break;
445 case TokenIsAppContainer:
447 TRACE("TokenIsAppContainer semi-stub\n");
448 *(DWORD *)info = 0;
449 break;
452 case TokenLogonSid:
453 SERVER_START_REQ( get_token_sid )
455 TOKEN_GROUPS * groups = info;
456 PSID sid = groups + 1;
457 DWORD sid_len = length < sizeof(TOKEN_GROUPS) ? 0 : length - sizeof(TOKEN_GROUPS);
459 req->handle = wine_server_obj_handle( token );
460 req->which_sid = class;
461 wine_server_set_reply( req, sid, sid_len );
462 status = wine_server_call( req );
463 if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_GROUPS);
464 if (status == STATUS_SUCCESS)
466 groups->GroupCount = 1;
467 groups->Groups[0].Sid = sid;
468 groups->Groups[0].Attributes = 0;
471 SERVER_END_REQ;
472 break;
474 default:
475 ERR( "Unhandled token information class %u\n", class );
476 return STATUS_NOT_IMPLEMENTED;
478 return status;
482 /***********************************************************************
483 * NtSetInformationToken (NTDLL.@)
485 NTSTATUS WINAPI NtSetInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS class,
486 void *info, ULONG length )
488 NTSTATUS ret = STATUS_NOT_IMPLEMENTED;
490 TRACE( "%p %d %p %u\n", token, class, info, length );
492 switch (class)
494 case TokenDefaultDacl:
495 if (length < sizeof(TOKEN_DEFAULT_DACL))
497 ret = STATUS_INFO_LENGTH_MISMATCH;
498 break;
500 if (!info)
502 ret = STATUS_ACCESS_VIOLATION;
503 break;
505 SERVER_START_REQ( set_token_default_dacl )
507 ACL *acl = ((TOKEN_DEFAULT_DACL *)info)->DefaultDacl;
508 WORD size;
510 if (acl) size = acl->AclSize;
511 else size = 0;
512 req->handle = wine_server_obj_handle( token );
513 wine_server_add_data( req, acl, size );
514 ret = wine_server_call( req );
516 SERVER_END_REQ;
517 break;
519 case TokenSessionId:
520 if (length < sizeof(DWORD))
522 ret = STATUS_INFO_LENGTH_MISMATCH;
523 break;
525 if (!info)
527 ret = STATUS_ACCESS_VIOLATION;
528 break;
530 FIXME("TokenSessionId stub!\n");
531 ret = STATUS_SUCCESS;
532 break;
534 case TokenIntegrityLevel:
535 FIXME( "TokenIntegrityLevel stub!\n" );
536 ret = STATUS_SUCCESS;
537 break;
539 default:
540 FIXME( "unimplemented class %u\n", class );
541 break;
543 return ret;
547 /***********************************************************************
548 * NtCreateLowBoxToken (NTDLL.@)
550 NTSTATUS WINAPI NtCreateLowBoxToken( HANDLE *token_handle, HANDLE token, ACCESS_MASK access,
551 OBJECT_ATTRIBUTES *attr, SID *sid, ULONG count,
552 SID_AND_ATTRIBUTES *capabilities, ULONG handle_count, HANDLE *handle )
554 FIXME("(%p, %p, %x, %p, %p, %u, %p, %u, %p): stub\n",
555 token_handle, token, access, attr, sid, count, capabilities, handle_count, handle );
557 /* we need to return a NULL handle since later it will be passed to NtClose and that must not fail */
558 *token_handle = NULL;
559 return STATUS_SUCCESS;
563 /***********************************************************************
564 * NtAdjustGroupsToken (NTDLL.@)
566 NTSTATUS WINAPI NtAdjustGroupsToken( HANDLE token, BOOLEAN reset, TOKEN_GROUPS *groups,
567 ULONG length, TOKEN_GROUPS *prev, ULONG *retlen )
569 FIXME( "%p %d %p %u %p %p\n", token, reset, groups, length, prev, retlen );
570 return STATUS_NOT_IMPLEMENTED;
574 /***********************************************************************
575 * NtAdjustPrivilegesToken (NTDLL.@)
577 NTSTATUS WINAPI NtAdjustPrivilegesToken( HANDLE token, BOOLEAN disable, TOKEN_PRIVILEGES *privs,
578 DWORD length, TOKEN_PRIVILEGES *prev, DWORD *retlen )
580 NTSTATUS ret;
582 TRACE( "(%p,0x%08x,%p,0x%08x,%p,%p)\n", token, disable, privs, length, prev, retlen );
584 SERVER_START_REQ( adjust_token_privileges )
586 req->handle = wine_server_obj_handle( token );
587 req->disable_all = disable;
588 req->get_modified_state = (prev != NULL);
589 if (!disable)
590 wine_server_add_data( req, privs->Privileges,
591 privs->PrivilegeCount * sizeof(privs->Privileges[0]) );
592 if (prev && length >= FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ))
593 wine_server_set_reply( req, prev->Privileges,
594 length - FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges ) );
595 ret = wine_server_call( req );
596 if (prev)
598 if (retlen) *retlen = reply->len + FIELD_OFFSET( TOKEN_PRIVILEGES, Privileges );
599 prev->PrivilegeCount = reply->len / sizeof(LUID_AND_ATTRIBUTES);
602 SERVER_END_REQ;
603 return ret;
607 /***********************************************************************
608 * NtPrivilegeCheck (NTDLL.@)
610 NTSTATUS WINAPI NtPrivilegeCheck( HANDLE token, PRIVILEGE_SET *privs, BOOLEAN *res )
612 NTSTATUS status;
614 SERVER_START_REQ( check_token_privileges )
616 req->handle = wine_server_obj_handle( token );
617 req->all_required = (privs->Control & PRIVILEGE_SET_ALL_NECESSARY) != 0;
618 wine_server_add_data( req, privs->Privilege, privs->PrivilegeCount * sizeof(privs->Privilege[0]) );
619 wine_server_set_reply( req, privs->Privilege, privs->PrivilegeCount * sizeof(privs->Privilege[0]) );
620 status = wine_server_call( req );
621 if (status == STATUS_SUCCESS) *res = reply->has_privileges != 0;
623 SERVER_END_REQ;
624 return status;
628 /***********************************************************************
629 * NtImpersonateAnonymousToken (NTDLL.@)
631 NTSTATUS WINAPI NtImpersonateAnonymousToken( HANDLE thread )
633 FIXME( "(%p): stub\n", thread );
634 return STATUS_NOT_IMPLEMENTED;
638 /***********************************************************************
639 * NtAccessCheck (NTDLL.@)
641 NTSTATUS WINAPI NtAccessCheck( PSECURITY_DESCRIPTOR descr, HANDLE token, ACCESS_MASK access,
642 GENERIC_MAPPING *mapping, PRIVILEGE_SET *privs, ULONG *retlen,
643 ULONG *access_granted, NTSTATUS *access_status)
645 struct object_attributes *objattr;
646 data_size_t len;
647 OBJECT_ATTRIBUTES attr;
648 NTSTATUS status;
650 TRACE( "(%p, %p, %08x, %p, %p, %p, %p, %p)\n",
651 descr, token, access, mapping, privs, retlen, access_granted, access_status );
653 if (!privs || !retlen) return STATUS_ACCESS_VIOLATION;
655 /* reuse the object attribute SD marshalling */
656 InitializeObjectAttributes( &attr, NULL, 0, 0, descr );
657 if ((status = alloc_object_attributes( &attr, &objattr, &len ))) return status;
659 SERVER_START_REQ( access_check )
661 req->handle = wine_server_obj_handle( token );
662 req->desired_access = access;
663 req->mapping_read = mapping->GenericRead;
664 req->mapping_write = mapping->GenericWrite;
665 req->mapping_execute = mapping->GenericExecute;
666 req->mapping_all = mapping->GenericAll;
667 wine_server_add_data( req, objattr + 1, objattr->sd_len );
668 wine_server_set_reply( req, privs->Privilege, *retlen - offsetof( PRIVILEGE_SET, Privilege ) );
670 status = wine_server_call( req );
672 *retlen = offsetof( PRIVILEGE_SET, Privilege ) + reply->privileges_len;
673 privs->PrivilegeCount = reply->privileges_len / sizeof(LUID_AND_ATTRIBUTES);
674 if (status == STATUS_SUCCESS)
676 *access_status = reply->access_status;
677 *access_granted = reply->access_granted;
680 SERVER_END_REQ;
681 free( objattr );
682 return status;
686 /***********************************************************************
687 * NtAccessCheckAndAuditAlarm (NTDLL.@)
689 NTSTATUS WINAPI NtAccessCheckAndAuditAlarm( UNICODE_STRING *subsystem, HANDLE handle,
690 UNICODE_STRING *typename, UNICODE_STRING *objectname,
691 PSECURITY_DESCRIPTOR descr, ACCESS_MASK access,
692 GENERIC_MAPPING *mapping, BOOLEAN creation,
693 ACCESS_MASK *access_granted, BOOLEAN *access_status,
694 BOOLEAN *onclose )
696 FIXME( "(%s, %p, %s, %p, 0x%08x, %p, %d, %p, %p, %p), stub\n",
697 debugstr_us(subsystem), handle, debugstr_us(typename), descr, access,
698 mapping, creation, access_granted, access_status, onclose );
699 return STATUS_NOT_IMPLEMENTED;
703 /***********************************************************************
704 * NtQuerySecurityObject (NTDLL.@)
706 NTSTATUS WINAPI NtQuerySecurityObject( HANDLE handle, SECURITY_INFORMATION info,
707 PSECURITY_DESCRIPTOR descr, ULONG length, ULONG *retlen )
709 SECURITY_DESCRIPTOR_RELATIVE *psd = descr;
710 NTSTATUS status;
711 void *buffer;
712 unsigned int buffer_size = 512;
714 TRACE( "(%p,0x%08x,%p,0x%08x,%p)\n", handle, info, descr, length, retlen );
716 for (;;)
718 if (!(buffer = malloc( buffer_size ))) return STATUS_NO_MEMORY;
720 SERVER_START_REQ( get_security_object )
722 req->handle = wine_server_obj_handle( handle );
723 req->security_info = info;
724 wine_server_set_reply( req, buffer, buffer_size );
725 status = wine_server_call( req );
726 buffer_size = reply->sd_len;
728 SERVER_END_REQ;
730 if (status == STATUS_BUFFER_TOO_SMALL)
732 free( buffer );
733 continue;
735 if (status == STATUS_SUCCESS)
737 struct security_descriptor *sd = buffer;
739 if (!buffer_size) memset( sd, 0, sizeof(*sd) );
740 *retlen = sizeof(*psd) + sd->owner_len + sd->group_len + sd->sacl_len + sd->dacl_len;
741 if (length >= *retlen)
743 DWORD len = sizeof(*psd);
744 memset( psd, 0, len );
745 psd->Revision = SECURITY_DESCRIPTOR_REVISION;
746 psd->Control = sd->control | SE_SELF_RELATIVE;
747 if (sd->owner_len) { psd->Owner = len; len += sd->owner_len; }
748 if (sd->group_len) { psd->Group = len; len += sd->group_len; }
749 if (sd->sacl_len) { psd->Sacl = len; len += sd->sacl_len; }
750 if (sd->dacl_len) { psd->Dacl = len; len += sd->dacl_len; }
751 /* owner, group, sacl and dacl are the same type as in the server
752 * and in the same order so we copy the memory in one block */
753 memcpy( psd + 1, sd + 1, len - sizeof(*psd) );
755 else status = STATUS_BUFFER_TOO_SMALL;
757 free( buffer );
758 return status;
763 /***********************************************************************
764 * NtSetSecurityObject (NTDLL.@)
766 NTSTATUS WINAPI NtSetSecurityObject( HANDLE handle, SECURITY_INFORMATION info, PSECURITY_DESCRIPTOR descr )
768 struct object_attributes *objattr;
769 struct security_descriptor *sd;
770 data_size_t len;
771 OBJECT_ATTRIBUTES attr;
772 NTSTATUS status;
774 TRACE( "%p 0x%08x %p\n", handle, info, descr );
776 if (!descr) return STATUS_ACCESS_VIOLATION;
778 /* reuse the object attribute SD marshalling */
779 InitializeObjectAttributes( &attr, NULL, 0, 0, descr );
780 if ((status = alloc_object_attributes( &attr, &objattr, &len ))) return status;
781 sd = (struct security_descriptor *)(objattr + 1);
782 if (info & OWNER_SECURITY_INFORMATION && !sd->owner_len) return STATUS_INVALID_SECURITY_DESCR;
783 if (info & GROUP_SECURITY_INFORMATION && !sd->group_len) return STATUS_INVALID_SECURITY_DESCR;
784 if (info & (SACL_SECURITY_INFORMATION | LABEL_SECURITY_INFORMATION)) sd->control |= SE_SACL_PRESENT;
785 if (info & DACL_SECURITY_INFORMATION) sd->control |= SE_DACL_PRESENT;
787 SERVER_START_REQ( set_security_object )
789 req->handle = wine_server_obj_handle( handle );
790 req->security_info = info;
791 wine_server_add_data( req, sd, objattr->sd_len );
792 status = wine_server_call( req );
794 SERVER_END_REQ;
795 free( objattr );
796 return status;
800 /***********************************************************************
801 * NtAllocateLocallyUniqueId (NTDLL.@)
803 NTSTATUS WINAPI NtAllocateLocallyUniqueId( LUID *luid )
805 NTSTATUS status;
807 TRACE( "%p\n", luid );
809 if (!luid) return STATUS_ACCESS_VIOLATION;
811 SERVER_START_REQ( allocate_locally_unique_id )
813 status = wine_server_call( req );
814 if (!status)
816 luid->LowPart = reply->luid.low_part;
817 luid->HighPart = reply->luid.high_part;
820 SERVER_END_REQ;
821 return status;
825 /***********************************************************************
826 * NtAllocateUuids (NTDLL.@)
828 NTSTATUS WINAPI NtAllocateUuids( ULARGE_INTEGER *time, ULONG *delta, ULONG *sequence, UCHAR *seed )
830 FIXME( "(%p,%p,%p,%p), stub.\n", time, delta, sequence, seed );
831 return STATUS_SUCCESS;