Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / se / semgr.c
index 8970003..d63eaae 100644 (file)
@@ -1,6 +1,6 @@
 /* $Id$
  * reactos security thin manager emulation of libcaptive
- * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
+ * Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
  * 
  * 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
@@ -63,6 +63,69 @@ VOID SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
 }
 
 
+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.
@@ -78,8 +141,10 @@ VOID SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
  * %NULL value is forbidden.
  * @PoolType: #POOL_TYPE to allocate new @NewDescriptor from.
  *
- * libcaptive requires @ExplicitDescriptor to be presents and it simply
- * copies it to the target @NewDescriptor.
+ * 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.
  */
@@ -87,6 +152,10 @@ 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);
@@ -95,12 +164,87 @@ NTSTATUS SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
         *     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,STATUS_NOT_IMPLEMENTED);  /* NOT YET IMPLEMENTED */
+       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;
 
-       /* FIXME: Copy substructure recursively? */
-       *NewDescriptor=ExAllocatePool(PagedPool,sizeof(**NewDescriptor));
-       **NewDescriptor=*ExplicitDescriptor;    /* copy the contents */
+       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 */
+}