Changeset 132 for trunk/lib


Ignore:
Timestamp:
01/11/09 16:44:33 (16 years ago)
Author:
tim
Message:

separated ACL parsing code from smb_deps into new winsec library

Location:
trunk/lib
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/Makefile

    r108 r132  
    33################################################################################
    44
    5 FILES=regfi.o smb_deps.o void_stack.o range_list.o lru_cache.o
     5FILES=regfi.o smb_deps.o winsec.o void_stack.o range_list.o lru_cache.o
    66
    77all: $(FILES)
     
    1212smb_deps.o: smb_deps.c
    1313        $(CC) $(CFLAGS) $(OPTS) $(INC) -c -o $@ smb_deps.c
     14
     15winsec.o: winsec.c
     16        $(CC) $(CFLAGS) $(OPTS) $(INC) -c -o $@ winsec.c
    1417
    1518void_stack.o: void_stack.c
  • trunk/lib/regfi.c

    r131 r132  
    66 * Windows NT registry parsing library
    77 *
    8  * Copyright (C) 2005-2008 Timothy D. Morgan
     8 * Copyright (C) 2005-2009 Timothy D. Morgan
    99 * Copyright (C) 2005 Gerald (Jerry) Carter
    1010 *
  • trunk/lib/smb_deps.c

    r111 r132  
    44 *   http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/
    55 *
    6  * Copyright (C) 2005-2006 Timothy D. Morgan
     6 * Copyright (C) 2005-2006,2009 Timothy D. Morgan
    77 * Copyright (C) 1992-2005 Samba development team
    88 *               (see individual files under Subversion for details.)
     
    556556  return true;
    557557}
    558 
    559 
    560 /*******************************************************************
    561  Reads or writes a DOM_SID structure.
    562 ********************************************************************/
    563 bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
    564 {
    565   int i;
    566 
    567   if (sid == NULL)
    568     return false;
    569   depth++;
    570 
    571   if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
    572     return false;
    573 
    574   if(!prs_uint8 ("num_auths  ", ps, depth, &sid->num_auths))
    575     return false;
    576 
    577   for (i = 0; i < 6; i++)
    578   {
    579     fstring tmp;
    580     snprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
    581     if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
    582       return false;
    583   }
    584 
    585   /* oops! XXXX should really issue a warning here... */
    586   if (sid->num_auths > MAXSUBAUTHS)
    587     sid->num_auths = MAXSUBAUTHS;
    588 
    589   if(!prs_uint32s("sub_auths ", ps, depth,
    590                   sid->sub_auths, sid->num_auths))
    591   { return false; }
    592 
    593   return true;
    594 }
    595 
    596 /* End of stuff from rpc_parse/parse_misc.c */
    597 
    598 /* From lib/util_sid.c */
    599 
    600 /*****************************************************************
    601  Calculates size of a sid.
    602 *****************************************************************/ 
    603 size_t sid_size(const DOM_SID *sid)
    604 {
    605   if (sid == NULL)
    606     return 0;
    607 
    608   return sid->num_auths * sizeof(uint32) + 8;
    609 }
    610 
    611 
    612 /*****************************************************************
    613  Compare the auth portion of two sids.
    614 *****************************************************************/ 
    615 int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
    616 {
    617   int i;
    618 
    619   if (sid1 == sid2)
    620     return 0;
    621   if (!sid1)
    622     return -1;
    623   if (!sid2)
    624     return 1;
    625 
    626   if (sid1->sid_rev_num != sid2->sid_rev_num)
    627     return sid1->sid_rev_num - sid2->sid_rev_num;
    628 
    629   for (i = 0; i < 6; i++)
    630     if (sid1->id_auth[i] != sid2->id_auth[i])
    631       return sid1->id_auth[i] - sid2->id_auth[i];
    632 
    633   return 0;
    634 }
    635 
    636 
    637 /*****************************************************************
    638  Compare two sids.
    639 *****************************************************************/ 
    640 int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
    641 {
    642   int i;
    643 
    644   if (sid1 == sid2)
    645     return 0;
    646   if (!sid1)
    647     return -1;
    648   if (!sid2)
    649     return 1;
    650 
    651   /* Compare most likely different rids, first: i.e start at end */
    652   if (sid1->num_auths != sid2->num_auths)
    653     return sid1->num_auths - sid2->num_auths;
    654 
    655   for (i = sid1->num_auths-1; i >= 0; --i)
    656     if (sid1->sub_auths[i] != sid2->sub_auths[i])
    657       return sid1->sub_auths[i] - sid2->sub_auths[i];
    658 
    659   return sid_compare_auth(sid1, sid2);
    660 }
    661 
    662 
    663 /*****************************************************************
    664  Compare two sids.
    665 *****************************************************************/ 
    666 bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
    667 {
    668   return sid_compare(sid1, sid2) == 0;
    669 }
    670 
    671 /* End of stuff from lib/util_sid.c */
    672 
    673 /* From lib/secace.c */
    674 
    675 /*******************************************************************
    676  Check if ACE has OBJECT type.
    677 ********************************************************************/
    678 
    679 bool sec_ace_object(uint8 type)
    680 {
    681   if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ||
    682       type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ||
    683       type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT ||
    684       type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) {
    685     return true;
    686   }
    687   return false;
    688 }
    689 
    690 /* End of stuff from lib/secace.c */
    691 
    692 /* From rpc_parse/parse_sec.c */
    693 
    694 /*******************************************************************
    695  Reads or writes a SEC_ACCESS structure.
    696 ********************************************************************/
    697 bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
    698 {
    699   if (t == NULL)
    700     return false;
    701 
    702   depth++;
    703        
    704   if(!prs_uint32("mask", ps, depth, &t->mask))
    705     return false;
    706 
    707   return true;
    708 }
    709 
    710 
    711 /*******************************************************************
    712  Reads or writes a SEC_ACE structure.
    713 ********************************************************************/
    714 bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
    715 {
    716   uint32 old_offset;
    717   uint32 offset_ace_size;
    718 
    719   if (psa == NULL)
    720     return false;
    721 
    722   depth++;
    723        
    724   old_offset = ps->data_offset;
    725 
    726   if(!prs_uint8("type ", ps, depth, &psa->type))
    727     return false;
    728 
    729   if(!prs_uint8("flags", ps, depth, &psa->flags))
    730     return false;
    731 
    732   if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
    733     return false;
    734 
    735   if(!sec_io_access("info ", &psa->info, ps, depth))
    736     return false;
    737 
    738   /* check whether object access is present */
    739   if (!sec_ace_object(psa->type))
    740   {
    741     if (!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
    742       return false;
    743   }
    744   else
    745   {
    746     if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags))
    747       return false;
    748 
    749     if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT)
    750       if (!smb_io_uuid("obj_guid", &psa->obj_guid, ps,depth))
    751         return false;
    752 
    753     if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT)
    754       if (!smb_io_uuid("inh_guid", &psa->inh_guid, ps,depth))
    755         return false;
    756 
    757     if(!smb_io_dom_sid("trustee  ", &psa->trustee , ps, depth))
    758       return false;
    759   }
    760 
    761   /* Theorectically an ACE can have a size greater than the
    762    * sum of its components. When marshalling, pad with extra null bytes
    763    * up to the
    764    * correct size.
    765    */
    766   if (!ps->io && (psa->size > ps->data_offset - old_offset))
    767   {
    768     uint32 extra_len = psa->size - (ps->data_offset - old_offset);
    769     uint32 i;
    770     uint8 c = 0;
    771 
    772     for (i = 0; i < extra_len; i++)
    773     {
    774       if (!prs_uint8("ace extra space", ps, depth, &c))
    775         return false;
    776     }
    777   }
    778 
    779   if(!prs_uint16_post("size ", ps, depth, &psa->size,
    780                       offset_ace_size, old_offset))
    781   { return false; }
    782 
    783   return true;
    784 }
    785 
    786 
    787 /*******************************************************************
    788  Reads or writes a SEC_ACL structure. 
    789 
    790  First of the xx_io_xx functions that allocates its data structures
    791  for you as it reads them.
    792 ********************************************************************/
    793 bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
    794 {
    795   unsigned int i;
    796   uint32 old_offset;
    797   uint32 offset_acl_size;
    798   SEC_ACL* psa;
    799 
    800   /*
    801    * Note that the size is always a multiple of 4 bytes due to the
    802    * nature of the data structure.  Therefore the prs_align() calls
    803    * have been removed as they through us off when doing two-layer
    804    * marshalling such as in the printing code (RPC_BUFFER).  --jerry
    805    */
    806 
    807   if (ppsa == NULL || ps == NULL)
    808     return false;
    809 
    810   psa = *ppsa;
    811 
    812   if(ps->io && psa == NULL)
    813   {
    814     /*
    815      * This is a read and we must allocate the stuct to read into.
    816      */
    817     if((psa = (SEC_ACL*)zalloc(sizeof(SEC_ACL))) == NULL)
    818       return false;
    819     *ppsa = psa;
    820   }
    821 
    822   depth++;     
    823   old_offset = ps->data_offset;
    824 
    825   if(!prs_uint16("revision", ps, depth, &psa->revision)
    826      || !prs_uint16_pre("size     ", ps, depth, &psa->size, &offset_acl_size)
    827      || !prs_uint32("num_aces ", ps, depth, &psa->num_aces))
    828   {
    829     free(psa);
    830     *ppsa = NULL;
    831     return false;
    832   }
    833 
    834   if (ps->io)
    835   {
    836     /*
    837      * Even if the num_aces is zero, allocate memory as there's a difference
    838      * between a non-present DACL (allow all access) and a DACL with no ACE's
    839      * (allow no access).
    840      */
    841     if((psa->ace = (SEC_ACE*)zcalloc(sizeof(SEC_ACE), psa->num_aces+1)) == NULL)
    842     {
    843       free(psa);
    844       *ppsa = NULL;
    845       return false;
    846     }
    847   }
    848 
    849   for (i = 0; i < psa->num_aces; i++)
    850   {
    851     fstring tmp;
    852     snprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
    853     if(!sec_io_ace(tmp, &psa->ace[i], ps, depth))
    854     {
    855       free(psa);
    856       *ppsa = NULL;
    857       return false;
    858     }
    859   }
    860 
    861   /* Theoretically an ACL can have a size greater than the
    862    *  sum of its components. When marshalling, pad with extra null
    863    *  bytes up to the
    864    *  correct size.
    865    */
    866   if (!ps->io && (psa->size > ps->data_offset - old_offset))
    867   {
    868     uint32 extra_len = psa->size - (ps->data_offset - old_offset);
    869     uint8 c = 0;
    870 
    871     for (i = 0; i < extra_len; i++)
    872     {
    873       if (!prs_uint8("acl extra space", ps, depth, &c))
    874       {
    875         free(psa);
    876         *ppsa = NULL;
    877         return false;
    878       }
    879     }
    880   }
    881 
    882   if(!prs_uint16_post("size     ", ps, depth, &psa->size,
    883                       offset_acl_size, old_offset))
    884   {
    885     free(psa);
    886     *ppsa = NULL;
    887     return false;
    888   }
    889 
    890   return true;
    891 }
    892 
    893 
    894 /*******************************************************************
    895  Reads or writes a SEC_DESC structure.
    896  If reading and the *ppsd = NULL, allocates the structure.
    897 ********************************************************************/
    898 bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
    899 {
    900   uint32 old_offset;
    901   uint32 max_offset = 0; /* after we're done, move offset to end */
    902   uint32 tmp_offset = 0;
    903 
    904   SEC_DESC *psd;
    905 
    906   if (ppsd == NULL || ps == NULL)
    907     return false;
    908 
    909   psd = *ppsd;
    910   if (psd == NULL)
    911   {
    912     if(ps->io)
    913     {
    914       if((psd = (SEC_DESC*)zalloc(sizeof(SEC_DESC))) == NULL)
    915         return false;
    916       *ppsd = psd;
    917     }
    918     else
    919     {
    920       /* Marshalling - just ignore. */
    921       return true;
    922     }
    923   }
    924 
    925   depth++;
    926 
    927   /* start of security descriptor stored for back-calc offset purposes */
    928   old_offset = ps->data_offset;
    929 
    930   if(!prs_uint16("revision ", ps, depth, &psd->revision)
    931      || !prs_uint16("type     ", ps, depth, &psd->type))
    932   {
    933     free(psd);
    934     *ppsd = NULL;
    935     return false;
    936   }
    937 
    938   if (!ps->io)
    939   {
    940     uint32 offset = SEC_DESC_HEADER_SIZE;
    941 
    942     /*
    943      * Work out the offsets here, as we write it out.
    944      */
    945 
    946     if (psd->sacl != NULL)
    947     {
    948       psd->off_sacl = offset;
    949       offset += psd->sacl->size;
    950     }
    951     else
    952       psd->off_sacl = 0;
    953 
    954     if (psd->dacl != NULL)
    955     {
    956       psd->off_dacl = offset;
    957       offset += psd->dacl->size;
    958     }
    959     else
    960       psd->off_dacl = 0;
    961 
    962     if (psd->owner_sid != NULL)
    963     {
    964       psd->off_owner_sid = offset;
    965       offset += sid_size(psd->owner_sid);
    966     }
    967     else
    968       psd->off_owner_sid = 0;
    969 
    970     if (psd->grp_sid != NULL)
    971     {
    972       psd->off_grp_sid = offset;
    973       offset += sid_size(psd->grp_sid);
    974     }
    975     else
    976       psd->off_grp_sid = 0;
    977   }
    978 
    979   if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid)
    980      || !prs_uint32("off_grp_sid  ", ps, depth, &psd->off_grp_sid)
    981      || !prs_uint32("off_sacl     ", ps, depth, &psd->off_sacl)
    982      || !prs_uint32("off_dacl     ", ps, depth, &psd->off_dacl))
    983   {
    984     free(psd);
    985     *ppsd = NULL;   
    986     return false;
    987   }
    988   max_offset = MAX(max_offset, ps->data_offset);
    989 
    990   if (psd->off_owner_sid != 0)
    991   {
    992     tmp_offset = ps->data_offset;
    993     if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
    994     {
    995       free(psd);
    996       *ppsd = NULL;
    997       return false;
    998     }
    999 
    1000     if (ps->io)
    1001     {
    1002       /* reading */
    1003       if((psd->owner_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
    1004       {
    1005         free(psd);
    1006         *ppsd = NULL;
    1007         return false;
    1008       }
    1009     }
    1010 
    1011     if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
    1012     {
    1013       if(ps->io)
    1014         free(psd->owner_sid);
    1015       free(psd);
    1016       *ppsd = NULL;
    1017       return false;
    1018     }
    1019 
    1020     max_offset = MAX(max_offset, ps->data_offset);
    1021 
    1022     if (!prs_set_offset(ps,tmp_offset))
    1023     {
    1024       if(ps->io)
    1025         free(psd->owner_sid);
    1026       free(psd);
    1027       *ppsd = NULL;
    1028       return false;
    1029     }
    1030   }
    1031 
    1032   if (psd->off_grp_sid != 0)
    1033   {
    1034     tmp_offset = ps->data_offset;
    1035     if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
    1036     {
    1037       if(ps->io)
    1038         free(psd->owner_sid);
    1039       free(psd);
    1040       *ppsd = NULL;
    1041       return false;
    1042     }
    1043 
    1044     if (ps->io)
    1045     {
    1046       /* reading */
    1047       if((psd->grp_sid = (DOM_SID*)zalloc(sizeof(DOM_SID))) == NULL)
    1048       {
    1049         free(psd->owner_sid);
    1050         free(psd);
    1051         *ppsd = NULL;
    1052         return false;
    1053       }
    1054     }
    1055 
    1056     if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
    1057     {
    1058       if(ps->io)
    1059       {
    1060         free(psd->grp_sid);
    1061         free(psd->owner_sid);
    1062       }
    1063       free(psd);
    1064       *ppsd = NULL;
    1065       return false;
    1066     }
    1067                        
    1068     max_offset = MAX(max_offset, ps->data_offset);
    1069 
    1070     if (!prs_set_offset(ps,tmp_offset))
    1071     {
    1072       if(ps->io)
    1073       {
    1074         free(psd->grp_sid);
    1075         free(psd->owner_sid);
    1076       }
    1077       free(psd);
    1078       *ppsd = NULL;
    1079       return false;
    1080     }
    1081   }
    1082 
    1083   if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl)
    1084   {
    1085     tmp_offset = ps->data_offset;
    1086     if(!prs_set_offset(ps, old_offset + psd->off_sacl)
    1087        || !sec_io_acl("sacl", &psd->sacl, ps, depth))
    1088     {
    1089       if(ps->io)
    1090       {
    1091         free(psd->grp_sid);
    1092         free(psd->owner_sid);
    1093       }
    1094       free(psd);
    1095       *ppsd = NULL;
    1096       return false;
    1097     }
    1098     max_offset = MAX(max_offset, ps->data_offset);
    1099     if (!prs_set_offset(ps,tmp_offset))
    1100     {
    1101       if(ps->io)
    1102       {
    1103         free(psd->grp_sid);
    1104         free(psd->owner_sid);
    1105       }
    1106       free(psd);
    1107       *ppsd = NULL;
    1108       return false;
    1109     }
    1110   }
    1111 
    1112   if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0)
    1113   {
    1114     tmp_offset = ps->data_offset;
    1115     if(!prs_set_offset(ps, old_offset + psd->off_dacl)
    1116        || !sec_io_acl("dacl", &psd->dacl, ps, depth))
    1117     {
    1118       if(ps->io)
    1119       {
    1120         free(psd->grp_sid);
    1121         free(psd->owner_sid);
    1122       }
    1123       free(psd);
    1124       *ppsd = NULL;
    1125       return false;
    1126     }
    1127     max_offset = MAX(max_offset, ps->data_offset);
    1128     if (!prs_set_offset(ps,tmp_offset))
    1129     {
    1130       if(ps->io)
    1131       {
    1132         free(psd->grp_sid);
    1133         free(psd->owner_sid);
    1134       }
    1135       free(psd);
    1136       *ppsd = NULL;
    1137       return false;
    1138     }
    1139   }
    1140 
    1141   if(!prs_set_offset(ps, max_offset))
    1142   {
    1143       if(ps->io)
    1144       {
    1145         free(psd->grp_sid);
    1146         free(psd->owner_sid);
    1147       }
    1148       free(psd);
    1149       *ppsd = NULL;
    1150       return false;
    1151   }
    1152 
    1153   return true;
    1154 }
    1155 
    1156 /* End of stuff from rpc_parse/parse_sec.c */
    1157 
    1158 /* From lib/secace.c */
    1159 
    1160 /*******************************************************************
    1161  Compares two SEC_ACE structures
    1162 ********************************************************************/
    1163 bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2)
    1164 {
    1165   /* Trivial cases */
    1166   if (!s1 && !s2)
    1167     return true;
    1168   if (!s1 || !s2)
    1169     return false;
    1170 
    1171   /* Check top level stuff */
    1172   if (s1->type != s2->type || s1->flags != s2->flags ||
    1173       s1->info.mask != s2->info.mask)
    1174   { return false; }
    1175 
    1176   /* Check SID */
    1177   if (!sid_equal(&s1->trustee, &s2->trustee))
    1178     return false;
    1179 
    1180   return true;
    1181 }
    1182 
    1183 /* End of stuff from lib/secace.c */
    1184 
    1185 /* From lib/secacl.c */
    1186 
    1187 /*******************************************************************
    1188  Compares two SEC_ACL structures
    1189 ********************************************************************/
    1190 
    1191 bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2)
    1192 {
    1193   unsigned int i, j;
    1194 
    1195   /* Trivial cases */
    1196   if (!s1 && !s2)
    1197     return true;
    1198   if (!s1 || !s2)
    1199     return false;
    1200 
    1201   /* Check top level stuff */
    1202   if (s1->revision != s2->revision)
    1203     return false;
    1204 
    1205   if (s1->num_aces != s2->num_aces)
    1206     return false;
    1207 
    1208   /* The ACEs could be in any order so check each ACE in s1 against
    1209      each ACE in s2. */
    1210 
    1211   for (i = 0; i < s1->num_aces; i++)
    1212   {
    1213     bool found = false;
    1214 
    1215     for (j = 0; j < s2->num_aces; j++)
    1216     {
    1217       if (sec_ace_equal(&s1->ace[i], &s2->ace[j]))
    1218       {
    1219         found = true;
    1220         break;
    1221       }
    1222     }
    1223 
    1224     if (!found)
    1225       return false;
    1226   }
    1227 
    1228   return true;
    1229 }
    1230 
    1231 /* End of stuff from lib/secacl.c */
    1232 
    1233 /* From lib/secdesc.c */
    1234 
    1235 /*******************************************************************
    1236  Compares two SEC_DESC structures
    1237 ********************************************************************/
    1238 bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2)
    1239 {
    1240   /* Trivial cases */
    1241   if (!s1 && !s2)
    1242     return true;
    1243   if (!s1 || !s2)
    1244     return false;
    1245 
    1246   /* Check top level stuff */
    1247   if (s1->revision != s2->revision)
    1248     return false;
    1249 
    1250   if (s1->type!= s2->type)
    1251     return false;
    1252 
    1253   /* Check owner and group */
    1254   if (!sid_equal(s1->owner_sid, s2->owner_sid))
    1255     return false;
    1256 
    1257   if (!sid_equal(s1->grp_sid, s2->grp_sid))
    1258     return false;
    1259 
    1260   /* Check ACLs present in one but not the other */
    1261   if ((s1->dacl && !s2->dacl) || (!s1->dacl && s2->dacl) ||
    1262       (s1->sacl && !s2->sacl) || (!s1->sacl && s2->sacl))
    1263   { return false; }
    1264 
    1265   /* Sigh - we have to do it the hard way by iterating over all
    1266      the ACEs in the ACLs */
    1267   if(!sec_acl_equal(s1->dacl, s2->dacl) || !sec_acl_equal(s1->sacl, s2->sacl))
    1268     return false;
    1269 
    1270   return true;
    1271 }
    1272 
    1273 /* End of stuff from lib/secdesc.c */
Note: See TracChangeset for help on using the changeset viewer.