Changeset 134 for trunk/lib/winsec.c


Ignore:
Timestamp:
01/16/09 13:36:04 (15 years ago)
Author:
tim
Message:

rewrote winsec library, stripping out Samba dependencies

eliminated remaining Samba prs functions

added support for 'li' subkey list records

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/winsec.c

    r133 r134  
    2828
    2929
    30 /*******************************************************************
    31  * Parses a SEC_DESC structure.
    32  *******************************************************************/
    33 bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
    34 {
    35   uint32 old_offset;
    36   uint32 max_offset = 0; /* after we're done, move offset to end */
    37   uint32 tmp_offset = 0;
    38 
    39   SEC_DESC *psd;
    40 
    41   if (ppsd == NULL || ps == NULL)
    42     return false;
    43 
    44   psd = *ppsd;
    45   if (psd == NULL)
    46   {
    47     if((psd = (SEC_DESC*)zalloc(sizeof(SEC_DESC))) == NULL)
    48       return false;
    49     *ppsd = psd;
    50   }
    51 
    52   depth++;
    53 
    54   /* start of security descriptor stored for back-calc offset purposes */
    55   old_offset = ps->data_offset;
    56 
    57   if(!prs_uint16("revision ", ps, depth, &psd->revision)
    58      || !prs_uint16("type     ", ps, depth, &psd->type))
    59   {
    60     free(psd);
    61     *ppsd = NULL;
    62     return false;
    63   }
    64 
    65   if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid)
    66      || !prs_uint32("off_grp_sid  ", ps, depth, &psd->off_grp_sid)
    67      || !prs_uint32("off_sacl     ", ps, depth, &psd->off_sacl)
    68      || !prs_uint32("off_dacl     ", ps, depth, &psd->off_dacl))
    69   {
    70     free(psd);
    71     *ppsd = NULL;   
    72     return false;
    73   }
    74   max_offset = MAX(max_offset, ps->data_offset);
    75 
    76   if (psd->off_owner_sid != 0)
    77   {
    78     tmp_offset = ps->data_offset;
    79     if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
    80     {
    81       free(psd);
    82       *ppsd = NULL;
    83       return false;
    84     }
    85 
    86     /* reading */
    87     if((psd->owner_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
    88     {
    89       free(psd);
    90       *ppsd = NULL;
    91       return false;
    92     }
    93 
    94     if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
    95     {
    96       free(psd->owner_sid);
    97       free(psd);
    98       *ppsd = NULL;
    99       return false;
    100     }
    101 
    102     max_offset = MAX(max_offset, ps->data_offset);
    103 
    104     if (!prs_set_offset(ps,tmp_offset))
    105     {
    106       free(psd->owner_sid);
    107       free(psd);
    108       *ppsd = NULL;
    109       return false;
    110     }
    111   }
    112 
    113   if (psd->off_grp_sid != 0)
    114   {
    115     tmp_offset = ps->data_offset;
    116     if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
    117     {
    118       free(psd->owner_sid);
    119       free(psd);
    120       *ppsd = NULL;
    121       return false;
    122     }
    123 
    124     /* reading */
    125     if((psd->grp_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
    126     {
    127       free(psd->owner_sid);
    128       free(psd);
    129       *ppsd = NULL;
    130       return false;
    131     }
    132 
    133     if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
    134     {
    135       free(psd->grp_sid);
    136       free(psd->owner_sid);
    137       free(psd);
    138       *ppsd = NULL;
    139       return false;
    140     }
    141                        
    142     max_offset = MAX(max_offset, ps->data_offset);
    143 
    144     if (!prs_set_offset(ps,tmp_offset))
    145     {
    146       free(psd->grp_sid);
    147       free(psd->owner_sid);
    148       free(psd);
    149       *ppsd = NULL;
    150       return false;
    151     }
    152   }
    153 
    154   if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl)
    155   {
    156     tmp_offset = ps->data_offset;
    157     if(!prs_set_offset(ps, old_offset + psd->off_sacl)
    158        || !sec_io_acl("sacl", &psd->sacl, ps, depth))
    159     {
    160       free(psd->grp_sid);
    161       free(psd->owner_sid);
    162       free(psd);
    163       *ppsd = NULL;
    164       return false;
    165     }
    166     max_offset = MAX(max_offset, ps->data_offset);
    167     if (!prs_set_offset(ps,tmp_offset))
    168     {
    169       free(psd->grp_sid);
    170       free(psd->owner_sid);
    171       free(psd);
    172       *ppsd = NULL;
    173       return false;
    174     }
    175   }
    176 
    177   if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0)
    178   {
    179     tmp_offset = ps->data_offset;
    180     if(!prs_set_offset(ps, old_offset + psd->off_dacl)
    181        || !sec_io_acl("dacl", &psd->dacl, ps, depth))
    182     {
    183       free(psd->grp_sid);
    184       free(psd->owner_sid);
    185       free(psd);
    186       *ppsd = NULL;
    187       return false;
    188     }
    189     max_offset = MAX(max_offset, ps->data_offset);
    190     if (!prs_set_offset(ps,tmp_offset))
    191     {
    192       free(psd->grp_sid);
    193       free(psd->owner_sid);
    194       free(psd);
    195       *ppsd = NULL;
    196       return false;
    197     }
    198   }
    199 
    200   if(!prs_set_offset(ps, max_offset))
    201   {
    202     free(psd->grp_sid);
    203     free(psd->owner_sid);
    204     free(psd);
    205     *ppsd = NULL;
    206     return false;
    207   }
    208 
    209   return true;
    210 }
    211 
    212 
    213 /*******************************************************************
    214  Reads or writes a DOM_SID structure.
    215 ********************************************************************/
    216 bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
    217 {
    218   int i;
    219 
    220   if (sid == NULL)
    221     return false;
    222   depth++;
    223 
    224   if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
    225     return false;
    226 
    227   if(!prs_uint8 ("num_auths  ", ps, depth, &sid->num_auths))
    228     return false;
    229 
    230   for (i = 0; i < 6; i++)
    231   {
    232     fstring tmp;
    233     snprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
    234     if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
    235       return false;
    236   }
    237 
    238   /* oops! XXXX should really issue a warning here... */
    239   if (sid->num_auths > MAXSUBAUTHS)
    240     sid->num_auths = MAXSUBAUTHS;
    241 
    242   if(!prs_uint32s("sub_auths ", ps, depth,
    243                   sid->sub_auths, sid->num_auths))
    244   { return false; }
    245 
    246   return true;
    247 }
    248 
    249 
    250 
    251 /*******************************************************************
    252  Reads or writes a SEC_ACCESS structure.
    253 ********************************************************************/
    254 bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
    255 {
    256   if (t == NULL)
    257     return false;
    258 
    259   depth++;
    260        
    261   if(!prs_uint32("mask", ps, depth, &t->mask))
    262     return false;
    263 
    264   return true;
    265 }
    266 
    267 
    268 /*******************************************************************
    269  Reads or writes a SEC_ACE structure.
    270 ********************************************************************/
    271 bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
    272 {
    273   uint32 old_offset;
    274   uint32 offset_ace_size;
    275 
    276   if (psa == NULL)
    277     return false;
    278 
    279   depth++;
    280        
    281   old_offset = ps->data_offset;
    282 
    283   if(!prs_uint8("type ", ps, depth, &psa->type))
    284     return false;
    285 
    286   if(!prs_uint8("flags", ps, depth, &psa->flags))
    287     return false;
    288 
    289   if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
    290     return false;
    291 
    292   if(!sec_io_access("info ", &psa->info, ps, depth))
    293     return false;
    294 
    295   /* check whether object access is present */
    296   if (!sec_ace_object(psa->type))
    297   {
    298     if (!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
    299       return false;
    300   }
    301   else
    302   {
    303     if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
    304       return false;
    305 
    306     if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
    307       if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
    308         return false;
    309 
    310     if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
    311       if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
    312         return false;
    313 
    314     if(!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
    315       return false;
    316   }
    317 
    318   if(!prs_uint16_post("size ", ps, depth, &psa->size,
    319                       offset_ace_size, old_offset))
    320   { return false; }
    321 
    322   return true;
    323 }
    324 
    325 
    326 /*******************************************************************
    327  Reads or writes a SEC_ACL structure. 
    328 
    329  First of the xx_io_xx functions that allocates its data structures
    330  for you as it reads them.
    331 ********************************************************************/
    332 bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
    333 {
    334   unsigned int i;
    335   uint32 old_offset;
    336   uint32 offset_acl_size;
    337   SEC_ACL* psa;
     30/******************************************************************************
     31 * Parses a WINSEC_DESC structure and substructures.
     32 ******************************************************************************/
     33WINSEC_DESC* winsec_parse_desc(const uint8_t* buf, uint32_t buf_len)
     34{
     35  WINSEC_DESC* ret_val;
     36
     37  if (buf == NULL || buf_len <  WINSEC_DESC_HEADER_SIZE)
     38    return NULL;
     39
     40  if((ret_val = (WINSEC_DESC*)zalloc(sizeof(WINSEC_DESC))) == NULL)
     41    return NULL;
     42
     43  ret_val->revision = buf[0];
     44  ret_val->sbz1 = buf[1];
     45  ret_val->control = SVAL(buf, 0x2);
     46
     47  if(!(ret_val->control & WINSEC_DESC_SELF_RELATIVE))
     48    fprintf(stderr, "DEBUG: NOT self-relative!\n");
     49
     50  ret_val->off_owner_sid = IVAL(buf, 0x4);
     51  ret_val->off_grp_sid = IVAL(buf, 0x8);
     52  ret_val->off_sacl = IVAL(buf, 0xC);
     53  ret_val->off_dacl = IVAL(buf, 0x10);
     54
     55  /* A basic sanity check to ensure our offsets are within our buffer.
     56   * Additional length checking is done in secondary parsing functions.
     57   */
     58  if((ret_val->off_owner_sid >= buf_len)
     59     || (ret_val->off_grp_sid >= buf_len)
     60     || (ret_val->off_sacl >= buf_len)
     61     || (ret_val->off_dacl >= buf_len))
     62  {
     63    free(ret_val);
     64    return NULL;
     65  }
     66
     67  if(ret_val->off_owner_sid != 0)
     68  {
     69    ret_val->owner_sid = winsec_parse_dom_sid(buf + ret_val->off_owner_sid,
     70                                              buf_len - ret_val->off_owner_sid);
     71    if(ret_val->owner_sid == NULL)
     72    {
     73      free(ret_val);
     74      return NULL;
     75    }
     76  }
     77
     78  if (ret_val->off_grp_sid != 0)
     79  {
     80    ret_val->grp_sid = winsec_parse_dom_sid(buf + ret_val->off_grp_sid,
     81                                            buf_len - ret_val->off_grp_sid);
     82    if(ret_val->grp_sid == NULL)
     83    {
     84      if(ret_val->owner_sid != NULL)
     85        free(ret_val->owner_sid);
     86      free(ret_val);
     87      return NULL;
     88    }
     89  }
     90
     91  if ((ret_val->control & WINSEC_DESC_SACL_PRESENT) && ret_val->off_sacl)
     92  {
     93    ret_val->sacl = winsec_parse_acl(buf + ret_val->off_sacl,
     94                                     buf_len - ret_val->off_sacl);
     95    if(ret_val->sacl == NULL)
     96    {
     97      if(ret_val->owner_sid != NULL)
     98        free(ret_val->owner_sid);
     99      if(ret_val->grp_sid != NULL)
     100        free(ret_val->grp_sid);
     101      free(ret_val);
     102      return NULL;
     103    }
     104  }
     105
     106  if ((ret_val->control & WINSEC_DESC_DACL_PRESENT) && ret_val->off_dacl != 0)
     107  {
     108    ret_val->dacl = winsec_parse_acl(buf + ret_val->off_dacl,
     109                                     buf_len - ret_val->off_dacl);
     110    if(ret_val->dacl == NULL)
     111    {
     112      if(ret_val->owner_sid != NULL)
     113        free(ret_val->owner_sid);
     114      if(ret_val->grp_sid != NULL)
     115        free(ret_val->grp_sid);
     116      if(ret_val->sacl != NULL)
     117        free(ret_val->sacl);
     118      free(ret_val);
     119      return NULL;
     120    }
     121  }
     122
     123  return ret_val;
     124}
     125
     126
     127/******************************************************************************
     128 * Parses a WINSEC_ACL structure and all substructures.
     129 ******************************************************************************/
     130WINSEC_ACL* winsec_parse_acl(const uint8_t* buf, uint32_t buf_len)
     131{
     132  uint32_t i, offset;
     133  WINSEC_ACL* ret_val;
    338134
    339135  /*
    340136   * Note that the size is always a multiple of 4 bytes due to the
    341    * nature of the data structure.  Therefore the prs_align() calls
    342    * have been removed as they through us off when doing two-layer
    343    * marshalling such as in the printing code (RPC_BUFFER).  --jerry
     137   * nature of the data structure.
    344138   */
    345 
    346   if (ppsa == NULL || ps == NULL)
    347     return false;
    348 
    349   psa = *ppsa;
    350 
    351   if(psa == NULL)
    352   {
    353     /*
    354      * This is a read and we must allocate the stuct to read into.
    355      */
    356     if((psa = (SEC_ACL*)zalloc(sizeof(SEC_ACL))) == NULL)
    357       return false;
    358     *ppsa = psa;
    359   }
    360 
    361   depth++;     
    362   old_offset = ps->data_offset;
    363 
    364   if(!prs_uint16("revision", ps, depth, &psa->revision)
    365      || !prs_uint16_pre("size     ", ps, depth, &psa->size, &offset_acl_size)
    366      || !prs_uint32("num_aces ", ps, depth, &psa->num_aces))
    367   {
    368     free(psa);
    369     *ppsa = NULL;
    370     return false;
    371   }
    372 
    373   /*
    374    * Even if the num_aces is zero, allocate memory as there's a difference
     139  if (buf == NULL || buf_len < 8)
     140    return NULL;
     141
     142  if((ret_val = (WINSEC_ACL*)zalloc(sizeof(WINSEC_ACL))) == NULL)
     143    return NULL;
     144 
     145  ret_val->revision = SVAL(buf, 0x0);
     146  ret_val->size     = SVAL(buf, 0x2);
     147  ret_val->num_aces = IVAL(buf, 0x4);
     148
     149  /* The num_aces can be at most around 4k because anything greater
     150   * wouldn't fit in the 16 bit size even if every ace was as small as
     151   * possible.
     152   */
     153  if((ret_val->size > buf_len) || (ret_val->num_aces > 4095))
     154  {
     155    free(ret_val);
     156    return NULL;
     157  }
     158
     159  /* Even if the num_aces is zero, allocate memory as there's a difference
    375160   * between a non-present DACL (allow all access) and a DACL with no ACE's
    376161   * (allow no access).
    377162   */
    378   if((psa->ace = (SEC_ACE*)zcalloc(sizeof(SEC_ACE), psa->num_aces+1)) == NULL)
    379   {
    380     free(psa);
    381     *ppsa = NULL;
    382     return false;
    383   }
    384 
    385   for (i = 0; i < psa->num_aces; i++)
    386   {
    387     fstring tmp;
    388     snprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
    389     if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
    390     {
    391       free(psa);
    392       *ppsa = NULL;
    393       return false;
    394     }
    395   }
    396 
    397   if(!prs_uint16_post("size     ", ps, depth, &psa->size,
    398                       offset_acl_size, old_offset))
    399   {
    400     free(psa);
    401     *ppsa = NULL;
    402     return false;
    403   }
    404 
    405   return true;
    406 }
    407 
    408 
    409 /*****************************************************************
    410  Calculates size of a sid.
    411 *****************************************************************/ 
    412 size_t sid_size(const DOM_SID *sid)
     163  if((ret_val->aces = (WINSEC_ACE**)zcalloc(sizeof(WINSEC_ACE*),
     164                                           ret_val->num_aces+1)) == NULL)
     165  {
     166    free(ret_val);
     167    return NULL;
     168  }
     169
     170  offset = 8;
     171  for(i=0; i < ret_val->num_aces; i++)
     172  {
     173    ret_val->aces[i] = winsec_parse_ace(buf+offset, buf_len-offset);
     174    if(ret_val->aces[i] == NULL)
     175    {
     176      free(ret_val->aces);
     177      free(ret_val);
     178      return NULL;
     179    }
     180
     181    offset += ret_val->aces[i]->size;
     182    if(offset > buf_len)
     183    {
     184      free(ret_val->aces);
     185      free(ret_val);
     186      return NULL;
     187    }
     188  }
     189
     190  return ret_val;
     191}
     192
     193
     194/******************************************************************************
     195 * Parses a WINSEC_ACE structure and all substructures.
     196 ******************************************************************************/
     197WINSEC_ACE* winsec_parse_ace(const uint8_t* buf, uint32_t buf_len)
     198{
     199  uint32_t offset;
     200  WINSEC_ACE* ret_val;
     201
     202  if(buf == NULL || buf_len < WINSEC_ACE_MIN_SIZE)
     203    return NULL;
     204
     205  if((ret_val = (WINSEC_ACE*)zalloc(sizeof(WINSEC_ACE))) == NULL)
     206    return NULL;
     207
     208  ret_val->type = buf[0];
     209  ret_val->flags = buf[1];
     210  ret_val->size = SVAL(buf, 0x2);
     211  ret_val->access_mask = IVAL(buf, 0x4);
     212
     213  offset = 0x8;
     214
     215  /* check whether object access is present */
     216  if (winsec_ace_object(ret_val->type))
     217  {
     218    ret_val->obj_flags = IVAL(buf, offset);
     219    offset += 4;
     220
     221    if(ret_val->obj_flags & WINSEC_ACE_OBJECT_PRESENT)
     222    {
     223      ret_val->obj_guid = winsec_parse_uuid(buf+offset, buf_len-offset);
     224      if(ret_val->obj_guid == NULL)
     225      {
     226        free(ret_val);
     227        return NULL;
     228      }
     229      offset += sizeof(WINSEC_UUID);
     230    }
     231
     232    if(ret_val->obj_flags & WINSEC_ACE_OBJECT_INHERITED_PRESENT)
     233    {
     234      ret_val->inh_guid = winsec_parse_uuid(buf+offset, buf_len-offset);
     235      if(ret_val->inh_guid == NULL)
     236      {
     237        if(ret_val->obj_guid != NULL)
     238          free(ret_val->obj_guid);
     239        free(ret_val);
     240        return NULL;
     241      }
     242      offset += sizeof(WINSEC_UUID);
     243    }
     244  }
     245
     246  ret_val->trustee = winsec_parse_dom_sid(buf+offset, buf_len-offset);
     247  if(ret_val->trustee == NULL)
     248  {
     249    if(ret_val->obj_guid != NULL)
     250      free(ret_val->obj_guid);
     251    if(ret_val->inh_guid != NULL)
     252      free(ret_val->inh_guid);
     253    free(ret_val);
     254        return NULL;
     255  }
     256 
     257  return ret_val;
     258}
     259
     260
     261/******************************************************************************
     262 * Parses a WINSEC_DOM_SID structure.
     263 ******************************************************************************/
     264WINSEC_DOM_SID* winsec_parse_dom_sid(const uint8_t* buf, uint32_t buf_len)
     265{
     266  uint32_t i;
     267  WINSEC_DOM_SID* ret_val;
     268
     269  if(buf == NULL || buf_len < 8)
     270    return NULL;
     271
     272  if((ret_val = (WINSEC_DOM_SID*)zalloc(sizeof(WINSEC_DOM_SID))) == NULL)
     273    return NULL;
     274
     275  ret_val->sid_rev_num = buf[0];
     276  ret_val->num_auths = buf[1];
     277  memcpy(ret_val->id_auth, buf+2, 6);
     278
     279  /* XXX: should really issue a warning here... */
     280  if (ret_val->num_auths > WINSEC_MAX_SUBAUTHS)
     281    ret_val->num_auths = WINSEC_MAX_SUBAUTHS;
     282
     283  if(buf_len < ret_val->num_auths*sizeof(uint32_t)+8)
     284  {
     285    free(ret_val);
     286    return NULL;
     287  }
     288 
     289  for(i=0; i < ret_val->num_auths; i++)
     290    ret_val->sub_auths[i] = IVAL(buf, 8+i*sizeof(uint32_t));
     291
     292  return ret_val;
     293}
     294
     295
     296/******************************************************************************
     297 * Parses a WINSEC_UUID struct.
     298 ******************************************************************************/
     299WINSEC_UUID* winsec_parse_uuid(const uint8_t* buf, uint32_t buf_len)
     300{
     301  WINSEC_UUID* ret_val;
     302
     303  if(buf == NULL || buf_len < sizeof(WINSEC_UUID))
     304    return false;
     305
     306  if((ret_val = (WINSEC_UUID*)zalloc(sizeof(WINSEC_UUID))) == NULL)
     307    return NULL;
     308 
     309  ret_val->time_low = IVAL(buf, 0x0);
     310  ret_val->time_mid = SVAL(buf, 0x4);
     311  ret_val->time_hi_and_version = SVAL(buf, 0x6);
     312 
     313  memcpy(ret_val->clock_seq, buf+0x8, 2);
     314  memcpy(ret_val->node, buf+0xB, 6);
     315
     316  return ret_val;
     317}
     318
     319
     320/******************************************************************************
     321 * Calculates the size of a SID.
     322 ******************************************************************************/
     323/*size_t sid_size(const WINSEC_DOM_SID *sid)*/
     324size_t winsec_sid_size(const WINSEC_DOM_SID* sid)
    413325{
    414326  if (sid == NULL)
    415327    return 0;
    416328
    417   return sid->num_auths * sizeof(uint32) + 8;
    418 }
    419 
    420 
    421 /*****************************************************************
    422  Compare the auth portion of two sids.
    423 *****************************************************************/ 
    424 int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
     329  return sid->num_auths * sizeof(uint32_t) + 8;
     330}
     331
     332
     333/******************************************************************************
     334 * Compare the auth portion of two SIDs.
     335 ******************************************************************************/
     336/*int sid_compare_auth(const WINSEC_DOM_SID *sid1, const WINSEC_DOM_SID *sid2)*/
     337int winsec_sid_compare_auth(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2)
    425338{
    426339  int i;
     
    444357
    445358
    446 /*****************************************************************
    447  Compare two sids.
    448 *****************************************************************/ 
    449 int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
     359/******************************************************************************
     360 * Compare two SIDs.
     361 ******************************************************************************/
     362/*int sid_compare(const WINSEC_DOM_SID *sid1, const WINSEC_DOM_SID *sid2)*/
     363int winsec_sid_compare(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2)
    450364{
    451365  int i;
     
    466380      return sid1->sub_auths[i] - sid2->sub_auths[i];
    467381
    468   return sid_compare_auth(sid1, sid2);
    469 }
    470 
    471 
    472 /*****************************************************************
    473  Compare two sids.
    474 *****************************************************************/ 
    475 bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
    476 {
    477   return sid_compare(sid1, sid2) == 0;
    478 }
    479 
    480 
    481 
    482 /*******************************************************************
    483  Check if ACE has OBJECT type.
    484 ********************************************************************/
    485 bool sec_ace_object(uint8 type)
    486 {
    487   if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
    488       type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
    489       type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
    490       type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
     382  return winsec_sid_compare_auth(sid1, sid2);
     383}
     384
     385
     386/******************************************************************************
     387 * Compare two SIDs.
     388 ******************************************************************************/
     389bool winsec_sid_equal(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2)
     390{
     391  return winsec_sid_compare(sid1, sid2) == 0;
     392}
     393
     394
     395/******************************************************************************
     396 * Compares two WINSEC_DESC structures.
     397 ******************************************************************************/
     398bool winsec_desc_equal(WINSEC_DESC* s1, WINSEC_DESC* s2)
     399{
     400  /* Trivial cases */
     401  if (!s1 && !s2)
    491402    return true;
    492   }
    493   return false;
    494 }
    495 
    496 
    497 /*******************************************************************
    498  Compares two SEC_ACE structures
    499 ********************************************************************/
    500 bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
    501 {
     403  if (!s1 || !s2)
     404    return false;
     405
     406  /* Check top level stuff */
     407  if (s1->revision != s2->revision)
     408    return false;
     409
     410  if (s1->control != s2->control)
     411    return false;
     412
     413  /* Check owner and group */
     414  if (!winsec_sid_equal(s1->owner_sid, s2->owner_sid))
     415    return false;
     416
     417  if (!winsec_sid_equal(s1->grp_sid, s2->grp_sid))
     418    return false;
     419
     420  /* Check ACLs present in one but not the other */
     421  if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
     422      (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl))
     423  { return false; }
     424
     425  /* Sigh - we have to do it the hard way by iterating over all
     426     the ACEs in the ACLs */
     427  if(!winsec_acl_equal(s1->dacl, s2->dacl) || !winsec_acl_equal(s1->sacl, s2->sacl))
     428    return false;
     429
     430  return true;
     431}
     432
     433
     434
     435/******************************************************************************
     436 * Compares two WINSEC_ACL structures.
     437 ******************************************************************************/
     438bool winsec_acl_equal(WINSEC_ACL* s1, WINSEC_ACL* s2)
     439{
     440  unsigned int i, j;
     441
    502442  /* Trivial cases */
    503443  if (!s1 && !s2)
     
    507447
    508448  /* Check top level stuff */
    509   if (s1->type != s2->type || s1->flags != s2->flags ||
    510       s1->info.mask != s2->info.mask)
    511   { return false; }
    512 
    513   /* Check SID */
    514   if (!sid_equal(&s1->trustee, &s2->trustee))
    515     return false;
     449  if (s1->revision != s2->revision)
     450    return false;
     451
     452  if (s1->num_aces != s2->num_aces)
     453    return false;
     454
     455  /* The ACEs could be in any order so check each ACE in s1 against
     456     each ACE in s2. */
     457
     458  for (i = 0; i < s1->num_aces; i++)
     459  {
     460    bool found = false;
     461
     462    for (j = 0; j < s2->num_aces; j++)
     463    {
     464      if (winsec_ace_equal(s1->aces[i], s2->aces[j]))
     465      {
     466        found = true;
     467        break;
     468      }
     469    }
     470
     471    if (!found)
     472      return false;
     473  }
    516474
    517475  return true;
     
    519477
    520478
    521 /*******************************************************************
    522  Compares two SEC_ACL structures
    523 ********************************************************************/
    524 bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
    525 {
    526   unsigned int i, j;
    527 
     479/******************************************************************************
     480 * Compares two WINSEC_ACE structures.
     481 ******************************************************************************/
     482bool winsec_ace_equal(WINSEC_ACE* s1, WINSEC_ACE* s2)
     483{
    528484  /* Trivial cases */
    529485  if (!s1 && !s2)
     
    533489
    534490  /* Check top level stuff */
    535   if (s1->revision != s2->revision)
    536     return false;
    537 
    538   if (s1->num_aces != s2->num_aces)
    539     return false;
    540 
    541   /* The ACEs could be in any order so check each ACE in s1 against
    542      each ACE in s2. */
    543 
    544   for (i = 0; i < s1->num_aces; i++)
    545   {
    546     bool found = false;
    547 
    548     for (j = 0; j < s2->num_aces; j++)
    549     {
    550       if (sec_ace_equal(&s1->ace[i], &s2->ace[j]))
    551       {
    552         found = true;
    553         break;
    554       }
    555     }
    556 
    557     if (!found)
    558       return false;
    559   }
     491  if (s1->type != s2->type || s1->flags != s2->flags ||
     492      s1->access_mask != s2->access_mask)
     493  { return false; }
     494
     495  /* Check SID */
     496  if (!winsec_sid_equal(s1->trustee, s2->trustee))
     497    return false;
    560498
    561499  return true;
     
    563501
    564502
    565 /*******************************************************************
    566  Compares two SEC_DESC structures
    567 ********************************************************************/
    568 bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
    569 {
    570   /* Trivial cases */
    571   if (!s1 && !s2)
    572     return true;
    573   if (!s1 || !s2)
    574     return false;
    575 
    576   /* Check top level stuff */
    577   if (s1->revision != s2->revision)
    578     return false;
    579 
    580   if (s1->type!= s2->type)
    581     return false;
    582 
    583   /* Check owner and group */
    584   if (!sid_equal(s1->owner_sid, s2->owner_sid))
    585     return false;
    586 
    587   if (!sid_equal(s1->grp_sid, s2->grp_sid))
    588     return false;
    589 
    590   /* Check ACLs present in one but not the other */
    591   if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
    592       (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl))
    593   { return false; }
    594 
    595   /* Sigh - we have to do it the hard way by iterating over all
    596      the ACEs in the ACLs */
    597   if(!sec_acl_equal(s1->dacl, s2->dacl) || !sec_acl_equal(s1->sacl, s2->sacl))
    598     return false;
    599 
    600   return true;
    601 }
     503/******************************************************************************
     504 * Check if ACE has OBJECT type.
     505 ******************************************************************************/
     506bool winsec_ace_object(uint8_t type)
     507{
     508  if (type == WINSEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
     509      type == WINSEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
     510      type == WINSEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
     511      type == WINSEC_ACE_TYPE_SYSTEM_ALARM_OBJECT)
     512  { return true; }
     513
     514  return false;
     515}
Note: See TracChangeset for help on using the changeset viewer.