Changeset 134
- Timestamp:
- 01/16/09 13:36:04 (16 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/regfi.h
r132 r134 1 1 /* 2 * Branched from Samba project , Subversion repositoryversion #6903:2 * Branched from Samba project Subversion repository, version #6903: 3 3 * http://viewcvs.samba.org/cgi-bin/viewcvs.cgi/trunk/source/include/regfio.h?rev=6903&view=auto 4 4 * 5 * Unix SMB/CIFS implementation. 6 * Windows NT registry I/O library 5 * Windows NT (and later) registry parsing library 7 6 * 8 7 * Copyright (C) 2005-2009 Timothy D. Morgan … … 11 10 * This program is free software; you can redistribute it and/or modify 12 11 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; version 2of the License.12 * the Free Software Foundation; version 3 of the License. 14 13 * 15 14 * This program is distributed in the hope that it will be useful, … … 191 190 uint32 cell_size; /* ((start_offset - end_offset) & 0xfffffff8) */ 192 191 193 SEC_DESC* sec_desc;192 WINSEC_DESC* sec_desc; 194 193 uint32 hbin_off; /* offset from beginning of this hbin block */ 195 194 … … 316 315 int regfi_type_str2val(const char* str); 317 316 318 char* regfi_get_sacl( SEC_DESC* sec_desc);319 char* regfi_get_dacl( SEC_DESC* sec_desc);320 char* regfi_get_owner( SEC_DESC* sec_desc);321 char* regfi_get_group( SEC_DESC* sec_desc);317 char* regfi_get_sacl(WINSEC_DESC* sec_desc); 318 char* regfi_get_dacl(WINSEC_DESC* sec_desc); 319 char* regfi_get_owner(WINSEC_DESC* sec_desc); 320 char* regfi_get_group(WINSEC_DESC* sec_desc); 322 321 323 322 REGF_FILE* regfi_open(const char* filename); -
trunk/include/smb_deps.h
r132 r134 29 29 #include <stdlib.h> 30 30 #include <stdbool.h> 31 #include <stdint.h> 31 32 #include <stdio.h> 32 33 #include <string.h> … … 46 47 /* From includes.h */ 47 48 48 #define uint8 unsigned char 49 #define int16 short 50 #define uint16 unsigned short 51 #define int32 int 52 #define uint32 unsigned int 53 54 #define SMB_STRUCT_STAT struct stat 55 #define QSORT_CAST (int (*)(const void *, const void *)) 49 #define uint8 uint8_t 50 #define int16 int8_t 51 #define uint16 uint16_t 52 #define int32 int32_t 53 #define uint32 uint32_t 56 54 57 55 #define MIN(a,b) ((a)<(b)?(a):(b)) … … 59 57 60 58 extern int DEBUGLEVEL; 61 62 #define DLIST_ADD(list, p) \63 { \64 if (!(list)) { \65 (list) = (p); \66 (p)->next = (p)->prev = NULL; \67 } else { \68 (list)->prev = (p); \69 (p)->next = (list); \70 (p)->prev = NULL; \71 (list) = (p); \72 }\73 }74 59 75 60 /* End of stuff from includes.h */ … … 84 69 85 70 /* End of stuff from smb.h */ 86 87 /* From smb_macros.h */88 89 #define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)90 #define SMB_MALLOC_P(type) (type *)malloc_(sizeof(type))91 #define TALLOC_ARRAY(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)92 #define TALLOC_ZERO_ARRAY(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)93 #define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)94 95 /* End of stuff from smb_macros.h */96 97 /* From ntdomain.h */98 99 struct uuid {100 uint32 time_low;101 uint16 time_mid;102 uint16 time_hi_and_version;103 uint8 clock_seq[2];104 uint8 node[6];105 };106 107 typedef struct _prs_struct {108 bool io; /* parsing in or out of data stream */109 /*110 * If the (incoming) data is big-endian. On output we are111 * always little-endian.112 */113 bool bigendian_data;114 uint8 align; /* data alignment */115 bool is_dynamic; /* Do we own this memory or not ? */116 uint32 data_offset; /* Current working offset into data. */117 uint32 buffer_size; /* Current allocated size of the buffer. */118 uint32 grow_size; /* size requested via prs_grow() calls */119 char *data_p; /* The buffer itself. */120 void *mem_ctx; /* When unmarshalling, use this.... */121 } prs_struct;122 123 #define MARSHALL 0124 #define UNMARSHALL 1125 126 #define RPC_LITTLE_ENDIAN 0127 #define RPC_PARSE_ALIGN 4128 129 /* End of stuff from ntdomain.h */130 131 71 132 72 /* From lib/time.c */ … … 143 83 /* End of stuff from lib/time.c */ 144 84 145 /* From rpc_dce.h */146 147 #define MAX_PDU_FRAG_LEN 0x10b8 /* this is what w2k sets */148 149 /* End of stuff from rpc_dce.h */150 151 /* From parse_prs.h */152 153 bool prs_grow(prs_struct *ps, uint32 extra_space);154 bool prs_align(prs_struct *ps);155 bool prs_init(prs_struct *ps, uint32 size, void *ctx, bool io);156 char *prs_mem_get(prs_struct *ps, uint32 extra_size);157 bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32);158 bool prs_uint32s(const char *name, prs_struct *ps,159 int depth, uint32 *data32s, int len);160 bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16);161 bool prs_uint16_pre(const char *name, prs_struct *ps, int depth,162 uint16 *data16, uint32 *offset);163 bool prs_uint16_post(const char *name, prs_struct *ps, int depth,164 uint16 *data16, uint32 ptr_uint16, uint32 start_offset);165 bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8);166 bool prs_uint8s(const char *name, prs_struct *ps, int depth,167 uint8* data8s, int len);168 bool prs_set_offset(prs_struct *ps, uint32 offset);169 170 /* End of stuff from parse_prs.h */171 172 173 /* From pstring.h */174 175 #define FSTRING_LEN 256176 typedef char fstring[FSTRING_LEN];177 178 /* End of stuff from pstring.h */179 180 /* From rpc_parse/parse_misc.c */181 182 bool smb_io_uuid(const char *desc, struct uuid *uuid,183 prs_struct *ps, int depth);184 bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth);185 186 /* End of stuff from rpc_parse/parse_misc.c */187 188 85 #endif /* _SMB_DEPS_H */ -
trunk/include/winsec.h
r133 r134 3 3 * Security Descriptors. See: 4 4 * http://websvn.samba.org/cgi-bin/viewcvs.cgi/trunk/source/ 5 * 6 * Revisions have been made based on information provided by Microsoft 7 * at: 8 * http://msdn.microsoft.com/en-us/library/cc230366(PROT.10).aspx 5 9 * 6 10 * Copyright (C) 2005,2009 Timothy D. Morgan … … 23 27 */ 24 28 29 #ifndef _WINSEC_H 30 #define _WINSEC_H 31 25 32 #include <stdlib.h> 26 33 #include <stdbool.h> 34 #include <stdint.h> 27 35 #include <stdio.h> 28 36 #include <string.h> … … 36 44 37 45 38 #define MAXSUBAUTHS 15 46 /* This is the maximum number of subauths in a SID, as defined here: 47 * http://msdn.microsoft.com/en-us/library/cc230371(PROT.10).aspx 48 */ 49 #define WINSEC_MAX_SUBAUTHS 15 39 50 40 #define SEC_DESC_HEADER_SIZE (2 * sizeof(uint16) + 4 * sizeof(uint32)) 41 /*thanks for Jim McDonough <jmcd@us.ibm.com>*/ 42 #define SEC_DESC_DACL_PRESENT 0x0004 43 #define SEC_DESC_SACL_PRESENT 0x0010 51 #define WINSEC_DESC_HEADER_SIZE (5 * sizeof(uint32_t)) 52 #define WINSEC_ACL_HEADER_SIZE (2 * sizeof(uint32_t)) 53 #define WINSEC_ACE_MIN_SIZE 16 44 54 45 #define SEC_ACE_OBJECT_PRESENT 0x00000001 46 #define SEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002 47 #define SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT 0x5 48 #define SEC_ACE_TYPE_ACCESS_DENIED_OBJECT 0x6 49 #define SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT 0x7 50 #define SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT 0x8 55 /* TODO: Fill in definitions of other flags */ 56 /* This means offsets contained in the descriptor are relative to the 57 * descriptor's offset. This had better be true in the registry. 58 */ 59 #define WINSEC_DESC_SELF_RELATIVE 0x8000 60 #define WINSEC_DESC_SACL_PRESENT 0x0010 61 #define WINSEC_DESC_DACL_PRESENT 0x0004 62 63 #define WINSEC_ACE_OBJECT_PRESENT 0x00000001 64 #define WINSEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002 65 #define WINSEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT 0x5 66 #define WINSEC_ACE_TYPE_ACCESS_DENIED_OBJECT 0x6 67 #define WINSEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT 0x7 68 #define WINSEC_ACE_TYPE_SYSTEM_ALARM_OBJECT 0x8 51 69 52 70 53 typedef struct sid_info71 typedef struct _winsec_uuid 54 72 { 55 uint8 sid_rev_num; /**< SID revision number */ 56 uint8 num_auths; /**< Number of sub-authorities */ 57 uint8 id_auth[6]; /**< Identifier Authority */ 73 uint32 time_low; 74 uint16 time_mid; 75 uint16 time_hi_and_version; 76 uint8 clock_seq[2]; 77 uint8 node[6]; 78 } WINSEC_UUID; 79 80 81 typedef struct _winsec_sid 82 { 83 uint8_t sid_rev_num; /* SID revision number */ 84 uint8_t num_auths; /* Number of sub-authorities */ 85 uint8_t id_auth[6]; /* Identifier Authority */ 58 86 /* 59 87 * Pointer to sub-authorities. 60 88 * 61 * @note The values in these uint32 's are in *native* byteorder, not89 * @note The values in these uint32_t's are in *native* byteorder, not 62 90 * neccessarily little-endian...... JRA. 63 91 */ 64 uint32 sub_auths[MAXSUBAUTHS]; 65 } DOM_SID; 92 /* XXX: Make this dynamically allocated? */ 93 uint32_t sub_auths[WINSEC_MAX_SUBAUTHS]; 94 } WINSEC_DOM_SID; 66 95 67 96 68 typedef struct security_info_info97 typedef struct _winsec_ace 69 98 { 70 uint32 mask; 71 72 } SEC_ACCESS; 73 74 typedef struct security_ace_info 75 { 76 uint8 type; /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */ 77 uint8 flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */ 78 uint16 size; 79 80 SEC_ACCESS info; 99 uint8_t type; /* xxxx_xxxx_ACE_TYPE - e.g allowed / denied etc */ 100 uint8_t flags; /* xxxx_INHERIT_xxxx - e.g OBJECT_INHERIT_ACE */ 101 uint16_t size; 102 uint32_t access_mask; 81 103 82 104 /* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */ 83 uint32 obj_flags;/* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */84 struct uuidobj_guid; /* object GUID */85 struct uuidinh_guid; /* inherited object GUID */105 uint32_t obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */ 106 WINSEC_UUID* obj_guid; /* object GUID */ 107 WINSEC_UUID* inh_guid; /* inherited object GUID */ 86 108 /* eof object stuff */ 87 109 88 DOM_SIDtrustee;110 WINSEC_DOM_SID* trustee; 89 111 90 } SEC_ACE;112 } WINSEC_ACE; 91 113 92 typedef struct security_acl_info114 typedef struct _winsec_acl 93 115 { 94 uint16 revision; /* 0x0003 */95 uint16 size;/* size in bytes of the entire ACL structure */96 uint32 num_aces; /* number of Access Control Entries */116 uint16_t revision; /* 0x0003 */ 117 uint16_t size; /* size in bytes of the entire ACL structure */ 118 uint32_t num_aces; /* number of Access Control Entries */ 97 119 98 SEC_ACE *ace;120 WINSEC_ACE** aces; 99 121 100 } SEC_ACL;122 } WINSEC_ACL; 101 123 102 typedef struct security_descriptor_info124 typedef struct _winsec_desc 103 125 { 104 uint16 revision; /* 0x0001 */ 105 uint16 type; /* SEC_DESC_xxxx flags */ 126 uint8_t revision; /* 0x01 */ 127 uint8_t sbz1; /* "If the Control field has the RM flag set, 128 * then this field contains the resource 129 * manager (RM) control value. ... Otherwise, 130 * this field is reserved and MUST be set to 131 * zero." -- Microsoft. See reference above. 132 */ 133 uint16_t control; /* WINSEC_DESC_* flags */ 106 134 107 uint32 off_owner_sid; /* offset to owner sid */108 uint32 off_grp_sid ; /* offset to group sid */109 uint32 off_sacl ; /* offset to system list of permissions */110 uint32 off_dacl ; /* offset to list of permissions */135 uint32_t off_owner_sid; /* offset to owner sid */ 136 uint32_t off_grp_sid ; /* offset to group sid */ 137 uint32_t off_sacl ; /* offset to system list of permissions */ 138 uint32_t off_dacl ; /* offset to list of permissions */ 111 139 112 SEC_ACL *dacl; /* user ACL */113 SEC_ACL *sacl; /* system ACL */114 DOM_SID *owner_sid;115 DOM_SID *grp_sid;140 WINSEC_DOM_SID* owner_sid; 141 WINSEC_DOM_SID* grp_sid; 142 WINSEC_ACL* sacl; /* system ACL */ 143 WINSEC_ACL* dacl; /* user ACL */ 116 144 117 } SEC_DESC;145 } WINSEC_DESC; 118 146 119 147 148 /* XXX: Need API functions to deallocate these structures */ 149 WINSEC_DESC* winsec_parse_desc(const uint8_t* buf, uint32_t buf_len); 150 WINSEC_ACL* winsec_parse_acl(const uint8_t* buf, uint32_t buf_len); 151 WINSEC_ACE* winsec_parse_ace(const uint8_t* buf, uint32_t buf_len); 152 WINSEC_DOM_SID* winsec_parse_dom_sid(const uint8_t* buf, uint32_t buf_len); 153 WINSEC_UUID* winsec_parse_uuid(const uint8_t* buf, uint32_t buf_len); 120 154 121 bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth); 122 bool sec_io_access(const char *desc, SEC_ACCESS *t, prs_struct *ps, int depth); 123 bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, int depth); 124 bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth); 125 bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth); 155 size_t winsec_sid_size(const WINSEC_DOM_SID* sid); 156 int winsec_sid_compare_auth(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2); 157 int winsec_sid_compare(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2); 158 bool winsec_sid_equal(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2); 159 bool winsec_desc_equal(WINSEC_DESC* s1, WINSEC_DESC* s2); 160 bool winsec_acl_equal(WINSEC_ACL* s1, WINSEC_ACL* s2); 161 bool winsec_ace_equal(WINSEC_ACE* s1, WINSEC_ACE* s2); 162 bool winsec_ace_object(uint8_t type); 126 163 127 size_t sid_size(const DOM_SID *sid); 128 int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2); 129 int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2); 130 bool sec_ace_equal(SEC_ACE *s1, SEC_ACE *s2); 131 bool sec_acl_equal(SEC_ACL *s1, SEC_ACL *s2); 132 bool sec_desc_equal(SEC_DESC *s1, SEC_DESC *s2); 133 bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2); 134 bool sec_ace_object(uint8 type); 164 #endif /* _WINSEC_H */ -
trunk/lib/regfi.c
r133 r134 3 3 * http://viewcvs.samba.org/cgi-bin/viewcvs.cgi/trunk/source/registry/regfio.c?rev=7470&view=auto 4 4 * 5 * Unix SMB/CIFS implementation. 6 * Windows NT registry parsing library 5 * Windows NT (and later) registry parsing library 7 6 * 8 7 * Copyright (C) 2005-2009 Timothy D. Morgan … … 226 225 227 226 228 char* regfi_sid2str( DOM_SID* sid)229 { 230 uint32 i, size = MAXSUBAUTHS*11 + 24;227 char* regfi_sid2str(WINSEC_DOM_SID* sid) 228 { 229 uint32 i, size = WINSEC_MAX_SUBAUTHS*11 + 24; 231 230 uint32 left = size; 232 231 uint8 comps = sid->num_auths; … … 236 235 return NULL; 237 236 238 if(comps > MAXSUBAUTHS)239 comps = MAXSUBAUTHS;237 if(comps > WINSEC_MAX_SUBAUTHS) 238 comps = WINSEC_MAX_SUBAUTHS; 240 239 241 240 left -= sprintf(ret_val, "S-%u-%u", sid->sid_rev_num, sid->id_auth[5]); … … 248 247 249 248 250 char* regfi_get_acl( SEC_ACL* acl)249 char* regfi_get_acl(WINSEC_ACL* acl) 251 250 { 252 251 uint32 i, extra, size = 0; … … 263 262 for (i = 0; i < acl->num_aces && !failed; i++) 264 263 { 265 sid_str = regfi_sid2str( &acl->ace[i].trustee);266 type_str = regfi_ace_type2str(acl->ace [i].type);267 perms_str = regfi_ace_perms2str(acl->ace [i].info.mask);268 flags_str = regfi_ace_flags2str(acl->ace [i].flags);264 sid_str = regfi_sid2str(acl->aces[i]->trustee); 265 type_str = regfi_ace_type2str(acl->aces[i]->type); 266 perms_str = regfi_ace_perms2str(acl->aces[i]->access_mask); 267 flags_str = regfi_ace_flags2str(acl->aces[i]->flags); 269 268 270 269 if(flags_str != NULL && perms_str != NULL … … 307 306 308 307 309 char* regfi_get_sacl( SEC_DESC *sec_desc)308 char* regfi_get_sacl(WINSEC_DESC *sec_desc) 310 309 { 311 310 if (sec_desc->sacl) … … 316 315 317 316 318 char* regfi_get_dacl( SEC_DESC *sec_desc)317 char* regfi_get_dacl(WINSEC_DESC *sec_desc) 319 318 { 320 319 if (sec_desc->dacl) … … 325 324 326 325 327 char* regfi_get_owner( SEC_DESC *sec_desc)326 char* regfi_get_owner(WINSEC_DESC *sec_desc) 328 327 { 329 328 return regfi_sid2str(sec_desc->owner_sid); … … 331 330 332 331 333 char* regfi_get_group( SEC_DESC *sec_desc)332 char* regfi_get_group(WINSEC_DESC *sec_desc) 334 333 { 335 334 return regfi_sid2str(sec_desc->grp_sid); … … 447 446 { 448 447 uint32 i,j,k; 449 REGF_SUBKEY_LIST* ret_val = (REGF_SUBKEY_LIST*)zalloc(sizeof(REGF_SUBKEY_LIST)); 450 if(ret_val == NULL || lists == NULL) 448 REGF_SUBKEY_LIST* ret_val; 449 450 if(lists == NULL) 451 return NULL; 452 ret_val = (REGF_SUBKEY_LIST*)zalloc(sizeof(REGF_SUBKEY_LIST)); 453 454 if(ret_val == NULL) 451 455 return NULL; 452 456 … … 457 461 if(lists[i] == NULL) 458 462 { 459 ret_val->num_keys = 0; 460 break; 463 free(ret_val); 464 free(lists); 465 return NULL; 461 466 } 462 467 ret_val->num_keys += lists[i]->num_keys; … … 469 474 * ret_val->num_keys); 470 475 k=0; 476 471 477 if(ret_val->elements != NULL) 472 478 { … … 498 504 REGF_SUBKEY_LIST** sublists; 499 505 REGF_HBIN* sublist_hbin; 500 uint32 i, cell_length, length, num_sublists, off, max_length ;506 uint32 i, cell_length, length, num_sublists, off, max_length, elem_size; 501 507 uint8* hashes; 502 508 uint8 buf[REGFI_SUBKEY_LIST_MIN_LEN]; … … 541 547 sublists[i] = regfi_load_subkeylist(file, off, 0, max_length, strict); 542 548 } 543 549 free(hashes); 550 544 551 return regfi_merge_subkeylists(num_sublists, sublists, strict); 552 } 553 554 if(buf[0] == 'l' && buf[1] == 'i') 555 elem_size = sizeof(uint32); 556 else if((buf[0] == 'l') && (buf[1] == 'f' || buf[1] == 'h')) 557 elem_size = sizeof(REGF_SUBKEY_LIST_ELEM); 558 else 559 { 560 /* fprintf(stderr, "DEBUG: lf->header=%c%c\n", buf[0], buf[1]);*/ 561 return NULL; 545 562 } 546 563 … … 551 568 ret_val->offset = offset; 552 569 ret_val->cell_size = cell_length; 553 554 if((buf[0] != 'l' || buf[1] != 'f') && (buf[0] != 'l' || buf[1] != 'h'))555 {556 /*printf("DEBUG: lf->header=%c%c\n", buf[0], buf[1]);*/557 free(ret_val);558 return NULL;559 }560 561 570 ret_val->magic[0] = buf[0]; 562 571 ret_val->magic[1] = buf[1]; … … 579 588 580 589 if(cell_length - REGFI_SUBKEY_LIST_MIN_LEN - sizeof(uint32) 581 < ret_val->num_keys*sizeof(REGF_SUBKEY_LIST_ELEM)) 582 return NULL; 583 584 length = sizeof(REGF_SUBKEY_LIST_ELEM)*ret_val->num_keys; 585 ret_val->elements = (REGF_SUBKEY_LIST_ELEM*)zalloc(length); 590 < ret_val->num_keys*elem_size) 591 { 592 free(ret_val); 593 return NULL; 594 } 595 596 length = elem_size*ret_val->num_keys; 597 ret_val->elements 598 = (REGF_SUBKEY_LIST_ELEM*)zalloc(ret_val->num_keys 599 * sizeof(REGF_SUBKEY_LIST_ELEM)); 586 600 if(ret_val->elements == NULL) 587 601 { … … 599 613 600 614 if(regfi_read(file->fd, hashes, &length) != 0 601 || length != sizeof(REGF_SUBKEY_LIST_ELEM)*ret_val->num_keys)615 || length != elem_size*ret_val->num_keys) 602 616 { 603 617 free(ret_val->elements); … … 606 620 } 607 621 608 for (i=0; i < ret_val->num_keys; i++) 609 { 610 ret_val->elements[i].nk_off = IVAL(hashes, i*sizeof(REGF_SUBKEY_LIST_ELEM)); 611 ret_val->elements[i].hash = IVAL(hashes, i*sizeof(REGF_SUBKEY_LIST_ELEM)+4); 622 if(buf[0] == 'l' && buf[1] == 'i') 623 { 624 for (i=0; i < ret_val->num_keys; i++) 625 { 626 ret_val->elements[i].nk_off = IVAL(hashes, i*elem_size); 627 ret_val->elements[i].hash = 0; 628 } 629 } 630 else 631 { 632 for (i=0; i < ret_val->num_keys; i++) 633 { 634 ret_val->elements[i].nk_off = IVAL(hashes, i*elem_size); 635 ret_val->elements[i].hash = IVAL(hashes, i*elem_size+4); 636 } 612 637 } 613 638 free(hashes); … … 623 648 { 624 649 REGF_SK_REC* ret_val; 650 uint8* sec_desc_buf; 625 651 uint32 cell_length, length; 626 prs_struct ps;652 /*prs_struct ps;*/ 627 653 uint8 sk_header[REGFI_SK_MIN_LENGTH]; 628 654 bool unalloc = false; 629 630 655 631 656 if(!regfi_parse_cell(file->fd, offset, sk_header, REGFI_SK_MIN_LENGTH, … … 674 699 * code depends on the ps structure. 675 700 */ 701 /* 676 702 if(!prs_init(&ps, ret_val->desc_size, NULL, UNMARSHALL)) 677 703 { … … 687 713 return NULL; 688 714 } 689 690 /* XXX: call should look more like: */ 691 /*if (!(ret_val->sec_desc = winsec_parse_desc(sec_desc_buf, ret_val->desc_size)))*/ 692 if (!sec_io_desc("sec_desc", &ret_val->sec_desc, &ps, 0)) 693 { 694 free(ret_val); 695 return NULL; 696 } 697 698 free(ps.data_p); 715 */ 716 717 sec_desc_buf = (uint8*)zalloc(ret_val->desc_size); 718 if(ret_val == NULL) 719 { 720 free(ret_val); 721 return NULL; 722 } 723 724 length = ret_val->desc_size; 725 if(regfi_read(file->fd, sec_desc_buf, &length) != 0 726 || length != ret_val->desc_size) 727 { 728 free(ret_val); 729 return NULL; 730 } 731 732 if(!(ret_val->sec_desc = winsec_parse_desc(sec_desc_buf, ret_val->desc_size))) 733 { 734 free(sec_desc_buf); 735 free(ret_val); 736 return NULL; 737 } 738 free(sec_desc_buf); 739 740 /* free(ps.data_p);*/ 699 741 700 742 return ret_val; … … 893 935 off = nk->subkeys_off + REGF_BLOCKSIZE; 894 936 max_length = sub_hbin->block_size + sub_hbin->file_off - off; 895 nk->subkeys = regfi_load_subkeylist(file, off, nk->num_subkeys, 937 nk->subkeys = regfi_load_subkeylist(file, off, nk->num_subkeys, 896 938 max_length, true); 939 897 940 if(nk->subkeys == NULL) 898 941 { -
trunk/lib/smb_deps.c
r132 r134 142 142 143 143 /* End of stuff from lib/time.c */ 144 145 /* From parse_prs.c */146 147 /*******************************************************************148 Attempt, if needed, to grow a data buffer.149 Also depends on the data stream mode (io).150 ********************************************************************/151 bool prs_grow(prs_struct *ps, uint32 extra_space)152 {153 uint32 new_size;154 char *new_data;155 156 ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space);157 158 if(ps->data_offset + extra_space <= ps->buffer_size)159 return true;160 161 /*162 * We cannot grow the buffer if we're not reading163 * into the prs_struct, or if we don't own the memory.164 */165 166 if(ps->io || !ps->is_dynamic)167 return false;168 169 /*170 * Decide how much extra space we really need.171 */172 extra_space -= (ps->buffer_size - ps->data_offset);173 if(ps->buffer_size == 0)174 {175 /*176 * Ensure we have at least a PDU's length, or extra_space,177 * whichever is greater.178 */179 new_size = MAX(MAX_PDU_FRAG_LEN,extra_space);180 181 if((new_data = zalloc(new_size)) == NULL)182 return false;183 }184 else185 {186 /*187 * If the current buffer size is bigger than the space needed, just188 * double it, else add extra_space.189 */190 new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);191 192 if ((new_data = (char*)realloc(ps->data_p, new_size)) == NULL)193 return false;194 195 memset(&new_data[ps->buffer_size], '\0',196 (size_t)(new_size - ps->buffer_size));197 }198 ps->buffer_size = new_size;199 ps->data_p = new_data;200 201 return true;202 }203 204 205 /*******************************************************************206 Align a the data_len to a multiple of align bytes - filling with207 zeros.208 ********************************************************************/209 bool prs_align(prs_struct *ps)210 {211 uint32 mod = ps->data_offset & (ps->align-1);212 213 if (ps->align != 0 && mod != 0)214 {215 uint32 extra_space = (ps->align - mod);216 if(!prs_grow(ps, extra_space))217 return false;218 memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);219 ps->data_offset += extra_space;220 }221 222 return true;223 }224 225 226 /**227 * Initialise an expandable parse structure.228 *229 * @param size Initial buffer size. If >0, a new buffer will be230 * created with malloc().231 *232 * @return false if allocation fails, otherwise true.233 **/234 235 bool prs_init(prs_struct *ps, uint32 size, void *ctx, bool io)236 {237 if(ps == NULL)238 return false;239 memset(ps, 0, sizeof(prs_struct));240 241 ps->io = io;242 ps->bigendian_data = RPC_LITTLE_ENDIAN;243 ps->align = RPC_PARSE_ALIGN;244 ps->is_dynamic = false;245 ps->data_offset = 0;246 ps->buffer_size = 0;247 ps->data_p = NULL;248 ps->mem_ctx = ctx;249 250 if (size != 0)251 {252 ps->buffer_size = size;253 if((ps->data_p = (char *)zalloc((size_t)size)) == NULL)254 return false;255 256 ps->is_dynamic = true; /* We own this memory. */257 }258 259 return true;260 }261 262 263 char *prs_mem_get(prs_struct *ps, uint32 extra_size)264 {265 if(ps->io)266 {267 /*268 * If reading, ensure that we can read the requested size item.269 */270 if (ps->data_offset + extra_size > ps->buffer_size)271 return NULL;272 }273 else274 {275 /*276 * Writing - grow the buffer if needed.277 */278 if(!prs_grow(ps, extra_size))279 return NULL;280 }281 282 return &ps->data_p[ps->data_offset];283 }284 285 286 /*******************************************************************287 Stream a uint32.288 ********************************************************************/289 bool prs_uint32(const char *name, prs_struct *ps, int depth, uint32 *data32)290 {291 char *q = prs_mem_get(ps, sizeof(uint32));292 if (q == NULL)293 return false;294 295 if (ps->io)296 {297 if (ps->bigendian_data)298 *data32 = RIVAL(q,0);299 else300 *data32 = IVAL(q,0);301 }302 else303 {304 if (ps->bigendian_data)305 RSIVAL(q,0,*data32);306 else307 SIVAL(q,0,*data32);308 }309 ps->data_offset += sizeof(uint32);310 311 return true;312 }313 314 315 /******************************************************************316 Stream an array of uint32s. Length is number of uint32s.317 ********************************************************************/318 bool prs_uint32s(const char *name, prs_struct *ps,319 int depth, uint32 *data32s, int len)320 {321 int i;322 char *q = prs_mem_get(ps, len * sizeof(uint32));323 if (q == NULL)324 return false;325 326 if (ps->io)327 {328 if (ps->bigendian_data)329 {330 for (i = 0; i < len; i++)331 data32s[i] = RIVAL(q, 4*i);332 }333 else334 {335 for (i = 0; i < len; i++)336 data32s[i] = IVAL(q, 4*i);337 }338 }339 else340 {341 if (ps->bigendian_data)342 {343 for (i = 0; i < len; i++)344 RSIVAL(q, 4*i, data32s[i]);345 }346 else347 {348 for (i = 0; i < len; i++)349 SIVAL(q, 4*i, data32s[i]);350 }351 }352 ps->data_offset += (len * sizeof(uint32));353 354 return true;355 }356 357 358 /*******************************************************************359 Stream a uint16.360 ********************************************************************/361 bool prs_uint16(const char *name, prs_struct *ps, int depth, uint16 *data16)362 {363 char *q = prs_mem_get(ps, sizeof(uint16));364 if (q == NULL)365 return false;366 367 if (ps->io)368 {369 if (ps->bigendian_data)370 *data16 = RSVAL(q,0);371 else372 *data16 = SVAL(q,0);373 }374 else375 {376 if (ps->bigendian_data)377 RSSVAL(q,0,*data16);378 else379 SSVAL(q,0,*data16);380 }381 ps->data_offset += sizeof(uint16);382 383 return true;384 }385 386 387 /*******************************************************************388 prs_uint16 wrapper. Call this and it sets up a pointer to where the389 uint16 should be stored, or gets the size if reading.390 ********************************************************************/391 bool prs_uint16_pre(const char *name, prs_struct *ps, int depth,392 uint16 *data16, uint32 *offset)393 {394 *offset = ps->data_offset;395 if (ps->io)396 {397 /* reading. */398 return prs_uint16(name, ps, depth, data16);399 }400 else401 {402 char *q = prs_mem_get(ps, sizeof(uint16));403 if(q ==NULL)404 return false;405 ps->data_offset += sizeof(uint16);406 }407 return true;408 }409 410 411 /*******************************************************************412 prs_uint16 wrapper. call this and it retrospectively stores the size.413 does nothing on reading, as that is already handled by ...._pre()414 ********************************************************************/415 bool prs_uint16_post(const char *name, prs_struct *ps, int depth,416 uint16 *data16, uint32 ptr_uint16, uint32 start_offset)417 {418 if (!ps->io)419 {420 /*421 * Writing - temporarily move the offset pointer.422 */423 uint16 data_size = ps->data_offset - start_offset;424 uint32 old_offset = ps->data_offset;425 426 ps->data_offset = ptr_uint16;427 if(!prs_uint16(name, ps, depth, &data_size))428 {429 ps->data_offset = old_offset;430 return false;431 }432 ps->data_offset = old_offset;433 }434 else435 ps->data_offset = start_offset + (uint32)(*data16);436 437 return true;438 }439 440 441 /*******************************************************************442 Stream a uint8.443 ********************************************************************/444 bool prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8)445 {446 char *q = prs_mem_get(ps, 1);447 if (q == NULL)448 return false;449 450 if (ps->io)451 *data8 = CVAL(q,0);452 else453 SCVAL(q,0,*data8);454 455 ps->data_offset += 1;456 457 return true;458 }459 460 461 /******************************************************************462 Stream an array of uint8s. Length is number of uint8s.463 ********************************************************************/464 bool prs_uint8s(const char *name, prs_struct *ps, int depth,465 uint8* data8s, int len)466 {467 int i;468 char *q = prs_mem_get(ps, len);469 if (q == NULL)470 return false;471 472 if (ps->io)473 {474 for (i = 0; i < len; i++)475 data8s[i] = CVAL(q,i);476 }477 else478 {479 for (i = 0; i < len; i++)480 SCVAL(q, i, data8s[i]);481 }482 483 ps->data_offset += len;484 485 return true;486 }487 488 489 /*******************************************************************490 Set the current offset (external interface).491 ********************************************************************/492 bool prs_set_offset(prs_struct *ps, uint32 offset)493 {494 if(offset <= ps->data_offset)495 {496 ps->data_offset = offset;497 return true;498 }499 500 if(!prs_grow(ps, offset - ps->data_offset))501 return false;502 503 ps->data_offset = offset;504 return true;505 }506 507 /* End of stuff from parse_prs.c */508 509 /* From rpc_parse/parse_misc.c */510 511 /*******************************************************************512 Reads or writes a struct uuid513 ********************************************************************/514 bool smb_io_uuid(const char *desc, struct uuid *uuid,515 prs_struct *ps, int depth)516 {517 if (uuid == NULL)518 return false;519 depth++;520 521 if(!prs_uint32 ("data ", ps, depth, &uuid->time_low))522 return false;523 if(!prs_uint16 ("data ", ps, depth, &uuid->time_mid))524 return false;525 if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version))526 return false;527 528 if(!prs_uint8s ("data ", ps, depth,529 uuid->clock_seq, sizeof(uuid->clock_seq)))530 return false;531 532 if(!prs_uint8s ("data ", ps, depth, uuid->node, sizeof(uuid->node)))533 return false;534 535 return true;536 }537 538 539 /*******************************************************************540 Reads or writes an NTTIME structure.541 ********************************************************************/542 bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)543 {544 if (nttime == NULL)545 return false;546 depth++;547 548 if(!prs_align(ps))549 return false;550 551 if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */552 return false;553 if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */554 return false;555 556 return true;557 } -
trunk/lib/winsec.c
r133 r134 28 28 29 29 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 ******************************************************************************/ 33 WINSEC_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 ******************************************************************************/ 130 WINSEC_ACL* winsec_parse_acl(const uint8_t* buf, uint32_t buf_len) 131 { 132 uint32_t i, offset; 133 WINSEC_ACL* ret_val; 338 134 339 135 /* 340 136 * 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. 344 138 */ 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 375 160 * between a non-present DACL (allow all access) and a DACL with no ACE's 376 161 * (allow no access). 377 162 */ 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 ******************************************************************************/ 197 WINSEC_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 ******************************************************************************/ 264 WINSEC_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 ******************************************************************************/ 299 WINSEC_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)*/ 324 size_t winsec_sid_size(const WINSEC_DOM_SID* sid) 413 325 { 414 326 if (sid == NULL) 415 327 return 0; 416 328 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)*/ 337 int winsec_sid_compare_auth(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2) 425 338 { 426 339 int i; … … 444 357 445 358 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)*/ 363 int winsec_sid_compare(const WINSEC_DOM_SID* sid1, const WINSEC_DOM_SID* sid2) 450 364 { 451 365 int i; … … 466 380 return sid1->sub_auths[i] - sid2->sub_auths[i]; 467 381 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 ******************************************************************************/ 389 bool 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 ******************************************************************************/ 398 bool winsec_desc_equal(WINSEC_DESC* s1, WINSEC_DESC* s2) 399 { 400 /* Trivial cases */ 401 if (!s1 && !s2) 491 402 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 ******************************************************************************/ 438 bool winsec_acl_equal(WINSEC_ACL* s1, WINSEC_ACL* s2) 439 { 440 unsigned int i, j; 441 502 442 /* Trivial cases */ 503 443 if (!s1 && !s2) … … 507 447 508 448 /* 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 } 516 474 517 475 return true; … … 519 477 520 478 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 ******************************************************************************/ 482 bool winsec_ace_equal(WINSEC_ACE* s1, WINSEC_ACE* s2) 483 { 528 484 /* Trivial cases */ 529 485 if (!s1 && !s2) … … 533 489 534 490 /* 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; 560 498 561 499 return true; … … 563 501 564 502 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 ******************************************************************************/ 506 bool 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 } -
trunk/src/common.c
r126 r134 29 29 const char* common_special_chars = ",\"\\"; 30 30 31 #define REGLOOKUP_VERSION "0. 9.0"31 #define REGLOOKUP_VERSION "0.10.0" 32 32 33 33
Note: See TracChangeset
for help on using the changeset viewer.