2 * reactos security thin manager emulation of libcaptive
3 * Copyright (C) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; exactly version 2 of June 1991 is required
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "reactos/ddk/setypes.h" /* self */
23 #include <glib/gmessages.h>
24 #include "reactos/ddk/status.h"
25 #include "reactos/ddk/exfuncs.h" /* for ExAllocatePool() */
29 * SeLockSubjectContext:
30 * @SubjectContext: Security context to read lock.
31 * %NULL value is forbidden.
33 * Obtain read locks on the security context @SubjectContext.
34 * @SubjectContext must be already acquired by SeCaptureSubjectContext().
36 * This functions is a NOP in libcaptive as there is no threading implemented.
37 * FIXME: No sanity checks are currently done by libcaptive.
39 VOID SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
41 g_return_if_fail(SubjectContext!=NULL);
43 /* NOP; TODO:thread */
48 * SeUnlockSubjectContext:
49 * @SubjectContext: Security context to unlock.
50 * %NULL value is forbidden.
52 * Release read locks on the security context @SubjectContext.
53 * @SubjectContext must be currently locked by SeLockSubjectContext().
55 * This functions is a NOP in libcaptive as there is no threading implemented.
56 * FIXME: No sanity checks are currently done by libcaptive.
58 VOID SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
60 g_return_if_fail(SubjectContext!=NULL);
62 /* NOP; TODO:thread */
66 static SID *SID_dup(SID *sid,SECURITY_DESCRIPTOR *src,SECURITY_DESCRIPTOR *dest,gpointer *destdatap)
71 /* 'sid' may be NULL */
72 g_return_val_if_fail(src!=NULL,NULL);
73 g_return_val_if_fail(dest!=NULL,NULL);
74 g_return_val_if_fail(destdatap!=NULL,NULL);
75 g_return_val_if_fail(*destdatap!=NULL,NULL);
79 if (src->Control & SE_SELF_RELATIVE)
80 sid=(SID *)(((ULONG)sid)+((ULONG)src));
84 size=sizeof(*r)+sizeof(*r->SubAuthority)*(sid->SubAuthorityCount-1);
85 g_assert(size==(gsize)((*(guint8 *)(((char *)sid)+0x01))*4+8)); /* 0x14h is sizeof(SECURITY_DESCRIPTOR) */
86 g_assert(!(size&3)); /* sizeof(ULONG)-alignment */
88 (*(char **)destdatap)+=size;
90 if (dest->Control & SE_SELF_RELATIVE)
91 r=(SID *)(((ULONG)r)-((ULONG)dest));
96 static ACL *ACL_dup(ACL *acl,SECURITY_DESCRIPTOR *src,SECURITY_DESCRIPTOR *dest,gpointer *destdatap)
101 /* 'acl' may be NULL */
102 g_return_val_if_fail(src!=NULL,NULL);
103 g_return_val_if_fail(dest!=NULL,NULL);
104 g_return_val_if_fail(destdatap!=NULL,NULL);
105 g_return_val_if_fail(*destdatap!=NULL,NULL);
109 if (src->Control & SE_SELF_RELATIVE)
110 acl=(ACL *)(((ULONG)acl)+((ULONG)src));
114 /* W32 undocumented: ReactOS uses '&0xFF' notation, I have seen value PAGE_SIZE.
115 * W32 doc says it is a regular size.
118 g_assert(!(size&3)); /* sizeof(ULONG)-alignment */
120 (*(char **)destdatap)+=size;
123 if (dest->Control & SE_SELF_RELATIVE)
124 r=(ACL *)(((ULONG)r)-((ULONG)dest));
131 * @ParentDescriptor: Optional parent object security descriptor.
132 * %NULL value is permitted.
133 * @ExplicitDescriptor: Optional overriding descriptor for the new object.
134 * FIXME: %NULL value should be permitted but it is currently forbidden by libcaptive.
135 * @NewDescriptor: Returns the new generated descriptor.
136 * %NULL value is forbidden.
137 * @IsDirectoryObject: Will the new object contain its subobjects?
138 * @SubjectContext: Security context of the caller.
139 * %NULL value is forbidden.
140 * @GenericMapping: Rights mapping (?).
141 * %NULL value is forbidden.
142 * @PoolType: #POOL_TYPE to allocate new @NewDescriptor from.
144 * libcaptive requires either @ExplicitDescriptor or @ParentDescriptor
145 * to be presents and it recursively copies the structures to the
146 * target (allocated) @NewDescriptor. @ExplicitDescriptor is preferred
147 * over @ParentDescriptor if present. No structures merging is done.
149 * Returns: %STATUS_SUCCESS if @NewDescriptor was successfuly filled.
151 NTSTATUS SeAssignSecurity(PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
152 PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL,PSECURITY_DESCRIPTOR *NewDescriptor,
153 BOOLEAN IsDirectoryObject,PSECURITY_SUBJECT_CONTEXT SubjectContext,PGENERIC_MAPPING GenericMapping,POOL_TYPE PoolType)
155 SECURITY_DESCRIPTOR *src,*dest;
159 g_return_val_if_fail(NewDescriptor!=NULL,STATUS_INVALID_PARAMETER);
160 g_return_val_if_fail(SubjectContext!=NULL,STATUS_INVALID_PARAMETER);
161 g_return_val_if_fail(GenericMapping!=NULL,STATUS_INVALID_PARAMETER);
163 /* #2 0x40067021 in SeAssignSecurity (ParentDescriptor=0x0,
164 * ExplicitDescriptor=0xbfffe7f4, NewDescriptor=0x40b5873c,
165 * IsDirectoryObject=0 '\0', SubjectContext=0x409d2ff0,
166 * GenericMapping=0x40088014, PoolType=1) at semgr.c:79
167 * #2 0x4006fe45 in SeAssignSecurity (ParentDescriptor=0x411b3fd0,
168 * ExplicitDescriptor=0x0, NewDescriptor=0xbfffe39c,
169 * IsDirectoryObject=1 '\001', SubjectContext=0xbfffe90c,
170 * GenericMapping=0x40094014, PoolType=1) at semgr.c:99
172 g_return_val_if_fail(ExplicitDescriptor!=NULL || ParentDescriptor!=NULL,STATUS_NOT_IMPLEMENTED); /* NOT YET IMPLEMENTED */
174 src=(ExplicitDescriptor ? ExplicitDescriptor : ParentDescriptor);
176 size=RtlLengthSecurityDescriptor(src);
177 g_assert(!(size&3)); /* sizeof(ULONG)-alignment */
179 dest=ExAllocatePool(PagedPool,size);
180 g_return_val_if_fail(dest!=NULL,STATUS_NO_MEMORY);
182 dest->Revision=src->Revision;
183 dest->Control=src->Control;
185 dest->Owner=SID_dup(src->Owner,src,dest,&destdata);
186 dest->Group=SID_dup(src->Group,src,dest,&destdata);
187 if (src->Control & SE_SACL_PRESENT) {
188 /* 'SE_SACL_PRESENT' may be site while 'Sacl==NULL'.
189 * FIXME: How it differs from '!SE_SACL_PRESENT'?
191 dest->Sacl=ACL_dup(src->Sacl,src,dest,&destdata);
195 if (src->Control & SE_DACL_PRESENT) {
196 /* 'SE_DACL_PRESENT' may be site while 'Dacl==NULL'.
197 * FIXME: How it differs from '!SE_DACL_PRESENT'?
199 dest->Dacl=ACL_dup(src->Dacl,src,dest,&destdata);
204 g_assert(((char *)dest)+size==destdata);
208 return STATUS_SUCCESS;
214 * @SecurityDescriptor: IGNORED; ignored by libcaptive.
215 * %NULL value is forbidden.
216 * @SubjectSecurityContext: IGNORED; ignored by libcaptive.
217 * %NULL value is forbidden.
218 * @SubjectContextLocked: IGNORED; ignored by libcaptive.
219 * @DesiredAccess: IGNORED; ignored by libcaptive.
220 * @PreviouslyGrantedAccess: IGNORED; ignored by libcaptive.
221 * @Privileges: IGNORED; ignored by libcaptive.
222 * %NULL value is forbidden.
223 * @GenericMapping: IGNORED; ignored by libcaptive.
224 * %NULL value is forbidden.
225 * @AccessMode: IGNORED; ignored by libcaptive.
226 * @GrantedAccess: IGNORED; ignored by libcaptive.
227 * %NULL value is forbidden.
228 * @AccessStatus: IGNORED; ignored by libcaptive.
229 * %NULL value is forbidden.
231 * Query the rights of IGNORED to access IGNORED.
233 * libcaptive does not support any security and therefore it always returns %TRUE.
235 * Returns: %TRUE if the access is granted.
237 BOOLEAN SeAccessCheck(IN PSECURITY_DESCRIPTOR SecurityDescriptor,IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
238 IN BOOLEAN SubjectContextLocked,IN ACCESS_MASK DesiredAccess,IN ACCESS_MASK PreviouslyGrantedAccess,
239 OUT PPRIVILEGE_SET* Privileges,IN PGENERIC_MAPPING GenericMapping,IN KPROCESSOR_MODE AccessMode,
240 OUT PACCESS_MODE GrantedAccess,OUT PNTSTATUS AccessStatus)
242 g_return_val_if_fail(SecurityDescriptor!=NULL,FALSE); /* means 'access denied' */
243 g_return_val_if_fail(SubjectSecurityContext!=NULL,FALSE); /* means 'access denied' */
244 g_return_val_if_fail(Privileges!=NULL,FALSE); /* means 'access denied' */
245 g_return_val_if_fail(GenericMapping!=NULL,FALSE); /* means 'access denied' */
246 g_return_val_if_fail(GrantedAccess!=NULL,FALSE); /* means 'access denied' */
247 g_return_val_if_fail(AccessStatus!=NULL,FALSE); /* means 'access denied' */
249 return TRUE; /* access granted */