/* $Id$ * reactos security thin manager emulation of libcaptive * Copyright (C) 2002-2003 Jan Kratochvil * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; exactly version 2 of June 1991 is required * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "reactos/ddk/setypes.h" /* self */ #include #include "reactos/ddk/status.h" #include "reactos/ddk/exfuncs.h" /* for ExAllocatePool() */ /** * SeLockSubjectContext: * @SubjectContext: Security context to read lock. * %NULL value is forbidden. * * Obtain read locks on the security context @SubjectContext. * @SubjectContext must be already acquired by SeCaptureSubjectContext(). * * This functions is a NOP in libcaptive as there is no threading implemented. * FIXME: No sanity checks are currently done by libcaptive. */ VOID SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) { g_return_if_fail(SubjectContext!=NULL); /* NOP; TODO:thread */ } /** * SeUnlockSubjectContext: * @SubjectContext: Security context to unlock. * %NULL value is forbidden. * * Release read locks on the security context @SubjectContext. * @SubjectContext must be currently locked by SeLockSubjectContext(). * * This functions is a NOP in libcaptive as there is no threading implemented. * FIXME: No sanity checks are currently done by libcaptive. */ VOID SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext) { g_return_if_fail(SubjectContext!=NULL); /* NOP; TODO:thread */ } static SID *SID_dup(SID *sid,SECURITY_DESCRIPTOR *src,SECURITY_DESCRIPTOR *dest,gpointer *destdatap) { SID *r; gsize size; /* 'sid' may be NULL */ g_return_val_if_fail(src!=NULL,NULL); g_return_val_if_fail(dest!=NULL,NULL); g_return_val_if_fail(destdatap!=NULL,NULL); g_return_val_if_fail(*destdatap!=NULL,NULL); if (!sid) return NULL; if (src->Control & SE_SELF_RELATIVE) sid=(SID *)(((ULONG)sid)+((ULONG)src)); if (!sid) return NULL; size=sizeof(*r)+sizeof(*r->SubAuthority)*(sid->SubAuthorityCount-1); g_assert(size==(gsize)((*(guint8 *)(((char *)sid)+0x01))*4+8)); /* 0x14h is sizeof(SECURITY_DESCRIPTOR) */ g_assert(!(size&3)); /* sizeof(ULONG)-alignment */ r=*destdatap; (*(char **)destdatap)+=size; memcpy(r,sid,size); if (dest->Control & SE_SELF_RELATIVE) r=(SID *)(((ULONG)r)-((ULONG)dest)); return r; } static ACL *ACL_dup(ACL *acl,SECURITY_DESCRIPTOR *src,SECURITY_DESCRIPTOR *dest,gpointer *destdatap) { ACL *r; gsize size; /* 'acl' may be NULL */ g_return_val_if_fail(src!=NULL,NULL); g_return_val_if_fail(dest!=NULL,NULL); g_return_val_if_fail(destdatap!=NULL,NULL); g_return_val_if_fail(*destdatap!=NULL,NULL); if (!acl) return NULL; if (src->Control & SE_SELF_RELATIVE) acl=(ACL *)(((ULONG)acl)+((ULONG)src)); if (!acl) r=NULL; else { /* W32 undocumented: ReactOS uses '&0xFF' notation, I have seen value PAGE_SIZE. * W32 doc says it is a regular size. */ size=acl->AclSize; g_assert(!(size&3)); /* sizeof(ULONG)-alignment */ r=*destdatap; (*(char **)destdatap)+=size; memcpy(r,acl,size); } if (dest->Control & SE_SELF_RELATIVE) r=(ACL *)(((ULONG)r)-((ULONG)dest)); return r; } /** * SeAssignSecurity: * @ParentDescriptor: Optional parent object security descriptor. * %NULL value is permitted. * @ExplicitDescriptor: Optional overriding descriptor for the new object. * FIXME: %NULL value should be permitted but it is currently forbidden by libcaptive. * @NewDescriptor: Returns the new generated descriptor. * %NULL value is forbidden. * @IsDirectoryObject: Will the new object contain its subobjects? * @SubjectContext: Security context of the caller. * %NULL value is forbidden. * @GenericMapping: Rights mapping (?). * %NULL value is forbidden. * @PoolType: #POOL_TYPE to allocate new @NewDescriptor from. * * libcaptive requires either @ExplicitDescriptor or @ParentDescriptor * to be presents and it recursively copies the structures to the * target (allocated) @NewDescriptor. @ExplicitDescriptor is preferred * over @ParentDescriptor if present. No structures merging is done. * * Returns: %STATUS_SUCCESS if @NewDescriptor was successfuly filled. */ NTSTATUS SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,PSECURITY_DESCRIPTOR *NewDescriptor, BOOLEAN IsDirectoryObject,PSECURITY_SUBJECT_CONTEXT SubjectContext,PGENERIC_MAPPING GenericMapping,POOL_TYPE PoolType) { SECURITY_DESCRIPTOR *src,*dest; ULONG size; gpointer destdata; g_return_val_if_fail(NewDescriptor!=NULL,STATUS_INVALID_PARAMETER); g_return_val_if_fail(SubjectContext!=NULL,STATUS_INVALID_PARAMETER); g_return_val_if_fail(GenericMapping!=NULL,STATUS_INVALID_PARAMETER); /* #2 0x40067021 in SeAssignSecurity (ParentDescriptor=0x0, * ExplicitDescriptor=0xbfffe7f4, NewDescriptor=0x40b5873c, * IsDirectoryObject=0 '\0', SubjectContext=0x409d2ff0, * GenericMapping=0x40088014, PoolType=1) at semgr.c:79 * #2 0x4006fe45 in SeAssignSecurity (ParentDescriptor=0x411b3fd0, * ExplicitDescriptor=0x0, NewDescriptor=0xbfffe39c, * IsDirectoryObject=1 '\001', SubjectContext=0xbfffe90c, * GenericMapping=0x40094014, PoolType=1) at semgr.c:99 */ g_return_val_if_fail(ExplicitDescriptor!=NULL || ParentDescriptor!=NULL,STATUS_NOT_IMPLEMENTED); /* NOT YET IMPLEMENTED */ src=(ExplicitDescriptor ? ExplicitDescriptor : ParentDescriptor); size=RtlLengthSecurityDescriptor(src); g_assert(!(size&3)); /* sizeof(ULONG)-alignment */ dest=ExAllocatePool(PagedPool,size); g_return_val_if_fail(dest!=NULL,STATUS_NO_MEMORY); dest->Revision=src->Revision; dest->Control=src->Control; destdata=(dest+1); dest->Owner=SID_dup(src->Owner,src,dest,&destdata); dest->Group=SID_dup(src->Group,src,dest,&destdata); if (src->Control & SE_SACL_PRESENT) { /* 'SE_SACL_PRESENT' may be site while 'Sacl==NULL'. * FIXME: How it differs from '!SE_SACL_PRESENT'? */ dest->Sacl=ACL_dup(src->Sacl,src,dest,&destdata); } else dest->Sacl=NULL; if (src->Control & SE_DACL_PRESENT) { /* 'SE_DACL_PRESENT' may be site while 'Dacl==NULL'. * FIXME: How it differs from '!SE_DACL_PRESENT'? */ dest->Dacl=ACL_dup(src->Dacl,src,dest,&destdata); } else dest->Dacl=NULL; g_assert(((char *)dest)+size==destdata); *NewDescriptor=dest; return STATUS_SUCCESS; } /** * SeAccessCheck: * @SecurityDescriptor: IGNORED; ignored by libcaptive. * %NULL value is forbidden. * @SubjectSecurityContext: IGNORED; ignored by libcaptive. * %NULL value is forbidden. * @SubjectContextLocked: IGNORED; ignored by libcaptive. * @DesiredAccess: IGNORED; ignored by libcaptive. * @PreviouslyGrantedAccess: IGNORED; ignored by libcaptive. * @Privileges: IGNORED; ignored by libcaptive. * %NULL value is forbidden. * @GenericMapping: IGNORED; ignored by libcaptive. * %NULL value is forbidden. * @AccessMode: IGNORED; ignored by libcaptive. * @GrantedAccess: IGNORED; ignored by libcaptive. * %NULL value is forbidden. * @AccessStatus: IGNORED; ignored by libcaptive. * %NULL value is forbidden. * * Query the rights of IGNORED to access IGNORED. * * libcaptive does not support any security and therefore it always returns %TRUE. * * Returns: %TRUE if the access is granted. */ BOOLEAN SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, IN BOOLEAN SubjectContextLocked,IN ACCESS_MASK DesiredAccess,IN ACCESS_MASK PreviouslyGrantedAccess, OUT PPRIVILEGE_SET* Privileges,IN PGENERIC_MAPPING GenericMapping,IN KPROCESSOR_MODE AccessMode, OUT PACCESS_MODE GrantedAccess,OUT PNTSTATUS AccessStatus) { g_return_val_if_fail(SecurityDescriptor!=NULL,FALSE); /* means 'access denied' */ g_return_val_if_fail(SubjectSecurityContext!=NULL,FALSE); /* means 'access denied' */ g_return_val_if_fail(Privileges!=NULL,FALSE); /* means 'access denied' */ g_return_val_if_fail(GenericMapping!=NULL,FALSE); /* means 'access denied' */ g_return_val_if_fail(GrantedAccess!=NULL,FALSE); /* means 'access denied' */ g_return_val_if_fail(AccessStatus!=NULL,FALSE); /* means 'access denied' */ return TRUE; /* access granted */ }