Changeset 134 for trunk/lib/winsec.c
- Timestamp:
- 01/16/09 13:36:04 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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 }
Note: See TracChangeset
for help on using the changeset viewer.