lib/secace.c

説明を見る。
00001 /* 
00002  *  Unix SMB/Netbios implementation.
00003  *  SEC_ACE handling functions
00004  *  Copyright (C) Andrew Tridgell              1992-1998,
00005  *  Copyright (C) Jeremy R. Allison            1995-2003.
00006  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
00007  *  Copyright (C) Paul Ashton                  1997-1998.
00008  *  
00009  *  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *  
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU General Public License for more details.
00018  *  
00019  *  You should have received a copy of the GNU General Public License
00020  *  along with this program; if not, write to the Free Software
00021  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00022  */
00023 
00024 #include "includes.h"
00025 
00026 /*******************************************************************
00027  Check if ACE has OBJECT type.
00028 ********************************************************************/
00029 
00030 BOOL sec_ace_object(uint8 type)
00031 {
00032         if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
00033             type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
00034             type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
00035             type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
00036                 return True;
00037         }
00038         return False;
00039 }
00040 
00041 /*******************************************************************
00042  copy a SEC_ACE structure.
00043 ********************************************************************/
00044 void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src)
00045 {
00046         ace_dest->type  = ace_src->type;
00047         ace_dest->flags = ace_src->flags;
00048         ace_dest->size  = ace_src->size;
00049         ace_dest->access_mask = ace_src->access_mask;
00050         ace_dest->obj_flags = ace_src->obj_flags;
00051         memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, sizeof(struct GUID));
00052         memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, sizeof(struct GUID));
00053         sid_copy(&ace_dest->trustee, &ace_src->trustee);
00054 }
00055 
00056 /*******************************************************************
00057  Sets up a SEC_ACE structure.
00058 ********************************************************************/
00059 
00060 void init_sec_ace(SEC_ACE *t, const DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
00061 {
00062         t->type = type;
00063         t->flags = flag;
00064         t->size = sid_size(sid) + 8;
00065         t->access_mask = mask;
00066 
00067         ZERO_STRUCTP(&t->trustee);
00068         sid_copy(&t->trustee, sid);
00069 }
00070 
00071 /*******************************************************************
00072  adds new SID with its permissions to ACE list
00073 ********************************************************************/
00074 
00075 NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, unsigned *num, DOM_SID *sid, uint32 mask)
00076 {
00077         unsigned int i = 0;
00078         
00079         if (!ctx || !pp_new || !old || !sid || !num)  return NT_STATUS_INVALID_PARAMETER;
00080 
00081         *num += 1;
00082         
00083         if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0)
00084                 return NT_STATUS_NO_MEMORY;
00085 
00086         for (i = 0; i < *num - 1; i ++)
00087                 sec_ace_copy(&(*pp_new)[i], &old[i]);
00088 
00089         (*pp_new)[i].type  = 0;
00090         (*pp_new)[i].flags = 0;
00091         (*pp_new)[i].size  = SEC_ACE_HEADER_SIZE + sid_size(sid);
00092         (*pp_new)[i].access_mask = mask;
00093         sid_copy(&(*pp_new)[i].trustee, sid);
00094         return NT_STATUS_OK;
00095 }
00096 
00097 /*******************************************************************
00098   modify SID's permissions at ACL 
00099 ********************************************************************/
00100 
00101 NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask)
00102 {
00103         unsigned int i = 0;
00104 
00105         if (!ace || !sid)  return NT_STATUS_INVALID_PARAMETER;
00106 
00107         for (i = 0; i < num; i ++) {
00108                 if (sid_compare(&ace[i].trustee, sid) == 0) {
00109                         ace[i].access_mask = mask;
00110                         return NT_STATUS_OK;
00111                 }
00112         }
00113         return NT_STATUS_NOT_FOUND;
00114 }
00115 
00116 /*******************************************************************
00117  delete SID from ACL
00118 ********************************************************************/
00119 
00120 NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **pp_new, SEC_ACE *old, uint32 *num, DOM_SID *sid)
00121 {
00122         unsigned int i     = 0;
00123         unsigned int n_del = 0;
00124 
00125         if (!ctx || !pp_new || !old || !sid || !num)  return NT_STATUS_INVALID_PARAMETER;
00126 
00127         if (*num) {
00128                 if((pp_new[0] = TALLOC_ZERO_ARRAY(ctx, SEC_ACE, *num )) == 0)
00129                         return NT_STATUS_NO_MEMORY;
00130         } else {
00131                 pp_new[0] = NULL;
00132         }
00133 
00134         for (i = 0; i < *num; i ++) {
00135                 if (sid_compare(&old[i].trustee, sid) != 0)
00136                         sec_ace_copy(&(*pp_new)[i], &old[i]);
00137                 else
00138                         n_del ++;
00139         }
00140         if (n_del == 0)
00141                 return NT_STATUS_NOT_FOUND;
00142         else {
00143                 *num -= n_del;
00144                 return NT_STATUS_OK;
00145         }
00146 }
00147 
00148 /*******************************************************************
00149  Compares two SEC_ACE structures
00150 ********************************************************************/
00151 
00152 BOOL sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
00153 {
00154         /* Trivial case */
00155 
00156         if (!s1 && !s2) {
00157                 return True;
00158         }
00159 
00160         if (!s1 || !s2) {
00161                 return False;
00162         }
00163 
00164         /* Check top level stuff */
00165 
00166         if (s1->type != s2->type || s1->flags != s2->flags ||
00167             s1->access_mask != s2->access_mask) {
00168                 return False;
00169         }
00170 
00171         /* Check SID */
00172 
00173         if (!sid_equal(&s1->trustee, &s2->trustee)) {
00174                 return False;
00175         }
00176 
00177         return True;
00178 }
00179 
00180 int nt_ace_inherit_comp( SEC_ACE *a1, SEC_ACE *a2)
00181 {
00182         int a1_inh = a1->flags & SEC_ACE_FLAG_INHERITED_ACE;
00183         int a2_inh = a2->flags & SEC_ACE_FLAG_INHERITED_ACE;
00184 
00185         if (a1_inh == a2_inh)
00186                 return 0;
00187 
00188         if (!a1_inh && a2_inh)
00189                 return -1;
00190         return 1;
00191 }
00192 
00193 /*******************************************************************
00194   Comparison function to apply the order explained below in a group.
00195 *******************************************************************/
00196 
00197 int nt_ace_canon_comp( SEC_ACE *a1, SEC_ACE *a2)
00198 {
00199         if ((a1->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
00200                                 (a2->type != SEC_ACE_TYPE_ACCESS_DENIED))
00201                 return -1;
00202 
00203         if ((a2->type == SEC_ACE_TYPE_ACCESS_DENIED) &&
00204                                 (a1->type != SEC_ACE_TYPE_ACCESS_DENIED))
00205                 return 1;
00206 
00207         /* Both access denied or access allowed. */
00208 
00209         /* 1. ACEs that apply to the object itself */
00210 
00211         if (!(a1->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
00212                         (a2->flags & SEC_ACE_FLAG_INHERIT_ONLY))
00213                 return -1;
00214         else if (!(a2->flags & SEC_ACE_FLAG_INHERIT_ONLY) &&
00215                         (a1->flags & SEC_ACE_FLAG_INHERIT_ONLY))
00216                 return 1;
00217 
00218         /* 2. ACEs that apply to a subobject of the object, such as
00219          * a property set or property. */
00220 
00221         if (a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
00222                         !(a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
00223                 return -1;
00224         else if (a2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT) &&
00225                         !(a1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT)))
00226                 return 1;
00227 
00228         return 0;
00229 }
00230 
00231 /*******************************************************************
00232  Functions to convert a SEC_DESC ACE DACL list into canonical order.
00233  JRA.
00234 
00235 --- from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/order_of_aces_in_a_dacl.asp
00236 
00237 The following describes the preferred order:
00238 
00239  To ensure that noninherited ACEs have precedence over inherited ACEs,
00240  place all noninherited ACEs in a group before any inherited ACEs.
00241  This ordering ensures, for example, that a noninherited access-denied ACE
00242  is enforced regardless of any inherited ACE that allows access.
00243 
00244  Within the groups of noninherited ACEs and inherited ACEs, order ACEs according to ACE type, as the following shows:
00245         1. Access-denied ACEs that apply to the object itself
00246         2. Access-denied ACEs that apply to a subobject of the object, such as a property set or property
00247         3. Access-allowed ACEs that apply to the object itself
00248         4. Access-allowed ACEs that apply to a subobject of the object"
00249 
00250 ********************************************************************/
00251 
00252 void dacl_sort_into_canonical_order(SEC_ACE *srclist, unsigned int num_aces)
00253 {
00254         unsigned int i;
00255 
00256         if (!srclist || num_aces == 0)
00257                 return;
00258 
00259         /* Sort so that non-inherited ACE's come first. */
00260         qsort( srclist, num_aces, sizeof(srclist[0]), QSORT_CAST nt_ace_inherit_comp);
00261 
00262         /* Find the boundary between non-inherited ACEs. */
00263         for (i = 0; i < num_aces; i++ ) {
00264                 SEC_ACE *curr_ace = &srclist[i];
00265 
00266                 if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE)
00267                         break;
00268         }
00269 
00270         /* i now points at entry number of the first inherited ACE. */
00271 
00272         /* Sort the non-inherited ACEs. */
00273         if (i)
00274                 qsort( srclist, i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
00275 
00276         /* Now sort the inherited ACEs. */
00277         if (num_aces - i)
00278                 qsort( &srclist[i], num_aces - i, sizeof(srclist[0]), QSORT_CAST nt_ace_canon_comp);
00279 }
00280 
00281 /*******************************************************************
00282  Check if this ACE has a SID in common with the token.
00283 ********************************************************************/
00284 
00285 BOOL token_sid_in_ace(const NT_USER_TOKEN *token, const SEC_ACE *ace)
00286 {
00287         size_t i;
00288 
00289         for (i = 0; i < token->num_sids; i++) {
00290                 if (sid_equal(&ace->trustee, &token->user_sids[i]))
00291                         return True;
00292         }
00293 
00294         return False;
00295 }

Sambaに対してSat Aug 29 21:22:59 2009に生成されました。  doxygen 1.4.7