BOOL prs_unistr2(BOOL charmode, const char *name, prs_struct *ps, int depth, UNISTR2 *str) { char *p; char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16)); if (q == NULL) return False; /* If the string is empty, we don't have anything to stream */ if (str->uni_str_len==0) return True; if (UNMARSHALLING(ps)) { str->buffer = (uint16 *)prs_alloc_mem(ps,str->uni_max_len * sizeof(uint16)); if (str->buffer == NULL) return False; } p = (char *)str->buffer; dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len); ps->data_offset += (str->uni_str_len * sizeof(uint16)); return True; }
BOOL prs_string2(BOOL charmode, const char *name, prs_struct *ps, int depth, STRING2 *str) { int i; char *q = prs_mem_get(ps, str->str_max_len); if (q == NULL) return False; if (UNMARSHALLING(ps)) { str->buffer = (unsigned char *)prs_alloc_mem(ps,str->str_max_len); if (str->buffer == NULL) return False; } if (UNMARSHALLING(ps)) { for (i = 0; i < str->str_str_len; i++) str->buffer[i] = CVAL(q,i); } else { for (i = 0; i < str->str_str_len; i++) SCVAL(q, i, str->buffer[i]); } DEBUG(5,("%s%04x %s: ", tab_depth(depth), ps->data_offset, name)); if (charmode) print_asc(5, (unsigned char*)str->buffer, str->str_str_len); else { for (i = 0; i < str->str_str_len; i++) DEBUG(5,("%02x ", str->buffer[i])); } DEBUG(5,("\n")); ps->data_offset += str->str_str_len; return True; }
BOOL sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth) { uint32 off_len; uint32 off_max_len; uint32 old_offset; uint32 size; SEC_DESC_BUF *psdb; if (ppsdb == NULL) return False; psdb = *ppsdb; if (UNMARSHALLING(ps) && psdb == NULL) { if((psdb = (SEC_DESC_BUF *)prs_alloc_mem(ps,sizeof(SEC_DESC_BUF))) == NULL) return False; *ppsdb = psdb; } prs_debug(ps, depth, desc, "sec_io_desc_buf"); depth++; if(!prs_align(ps)) return False; if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len)) return False; if(!prs_uint32 ("ptr ", ps, depth, &psdb->ptr)) return False; if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len)) return False; old_offset = prs_offset(ps); /* reading, length is non-zero; writing, descriptor is non-NULL */ if ((UNMARSHALLING(ps) && psdb->len != 0) || (MARSHALLING(ps) && psdb->sec != NULL)) { if(!sec_io_desc("sec ", &psdb->sec, ps, depth)) return False; } if(!prs_align(ps)) return False; size = prs_offset(ps) - old_offset; if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size)) return False; if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size)) return False; return True; }
static BOOL ds_io_dominfobasic( const char *desc, prs_struct *ps, int depth, DSROLE_PRIMARY_DOMAIN_INFO_BASIC **basic) { DSROLE_PRIMARY_DOMAIN_INFO_BASIC *p = *basic; if ( UNMARSHALLING(ps) ) p = *basic = (DSROLE_PRIMARY_DOMAIN_INFO_BASIC *)prs_alloc_mem(ps, sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC)); if ( !p ) return False; if ( !prs_uint16("machine_role", ps, depth, &p->machine_role) ) return False; if ( !prs_uint16("unknown", ps, depth, &p->unknown) ) return False; if ( !prs_uint32("flags", ps, depth, &p->flags) ) return False; if ( !prs_uint32("netbios_ptr", ps, depth, &p->netbios_ptr) ) return False; if ( !prs_uint32("dnsname_ptr", ps, depth, &p->dnsname_ptr) ) return False; if ( !prs_uint32("forestname_ptr", ps, depth, &p->forestname_ptr) ) return False; if ( !prs_uint8s(False, "domain_guid", ps, depth, p->domain_guid.info, GUID_SIZE) ) return False; if ( !smb_io_unistr2( "netbios_domain", &p->netbios_domain, p->netbios_ptr, ps, depth) ) return False; if ( !prs_align(ps) ) return False; if ( !smb_io_unistr2( "dns_domain", &p->dns_domain, p->dnsname_ptr, ps, depth) ) return False; if ( !prs_align(ps) ) return False; if ( !smb_io_unistr2( "forest_domain", &p->forest_domain, p->forestname_ptr, ps, depth) ) return False; if ( !prs_align(ps) ) return False; return True; }
BOOL prs_unistr3(BOOL charmode, const char *name, UNISTR3 *str, prs_struct *ps, int depth) { char *p; char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16)); if (q == NULL) return False; if (UNMARSHALLING(ps)) { str->str.buffer = (uint16 *)prs_alloc_mem(ps,str->uni_str_len * sizeof(uint16)); if (str->str.buffer == NULL) return False; } p = (char *)str->str.buffer; dbg_rw_punival(charmode, name, depth, ps, q, p, str->uni_str_len); ps->data_offset += (str->uni_str_len * sizeof(uint16)); return True; }
BOOL prs_buffer2(BOOL charmode, const char *name, prs_struct *ps, int depth, BUFFER2 *str) { char *p; char *q = prs_mem_get(ps, str->buf_len); if (q == NULL) return False; if (UNMARSHALLING(ps)) { str->buffer = (uint16 *)prs_alloc_mem(ps,str->buf_len); if (str->buffer == NULL) return False; } p = (char *)str->buffer; dbg_rw_punival(charmode, name, depth, ps, q, p, str->buf_len/2); ps->data_offset += str->buf_len; return True; }
BOOL dfs_io_dfs_storage_info(const char *desc, DFS_INFO_3* info3, prs_struct *ps, int depth) { int i=0; if(info3 == NULL) return False; prs_debug(ps, depth, desc, "smb_io_dfs_storage_info"); depth++; if(UNMARSHALLING(ps)) { info3->storages = (DFS_STORAGE_INFO *)prs_alloc_mem(ps, info3->num_storage_infos*sizeof(DFS_STORAGE_INFO)); if (!info3->storages) return False; } for(i=0;i<info3->num_storage_infos;i++) { if(!prs_uint32("storage_state", ps, depth, &info3->storages[i].state)) return False; if(!prs_uint32("ptr_servername", ps, depth, &info3->storages[i].ptr_servername)) return False; if(!prs_uint32("ptr_sharename", ps, depth, &info3->storages[i].ptr_sharename)) return False; } for(i=0;i<info3->num_storage_infos;i++) { if(!smb_io_unistr2("servername", &info3->storages[i].servername, info3->storages[i].ptr_servername, ps, depth)) return False; if(!prs_align(ps)) return False; if(!smb_io_unistr2("sharename", &info3->storages[i].sharename, info3->storages[i].ptr_sharename, ps, depth)) return False; if(!prs_align(ps)) return False; } return True; }
BOOL sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth) { uint32 old_offset; uint32 max_offset = 0; /* after we're done, move offset to end */ uint32 tmp_offset = 0; SEC_DESC *psd; if (ppsd == NULL) return False; psd = *ppsd; if (psd == NULL) { if(UNMARSHALLING(ps)) { if((psd = (SEC_DESC *)prs_alloc_mem(ps,sizeof(SEC_DESC))) == NULL) return False; *ppsd = psd; } else { /* Marshalling - just ignore. */ return True; } } prs_debug(ps, depth, desc, "sec_io_desc"); depth++; #if 0 /* * if alignment is needed, should be done by the the * caller. Not here. This caused me problems when marshalling * printer info into a buffer. --jerry */ if(!prs_align(ps)) return False; #endif /* start of security descriptor stored for back-calc offset purposes */ old_offset = prs_offset(ps); if(!prs_uint16("revision ", ps, depth, &psd->revision)) return False; if(!prs_uint16("type ", ps, depth, &psd->type)) return False; if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid)) return False; if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid)) return False; if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl)) return False; if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl)) return False; max_offset = MAX(max_offset, prs_offset(ps)); if (psd->off_owner_sid != 0) { tmp_offset = prs_offset(ps); if(!prs_set_offset(ps, old_offset + psd->off_owner_sid)) return False; if (UNMARSHALLING(ps)) { /* reading */ if((psd->owner_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->owner_sid))) == NULL) return False; } if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth)) return False; max_offset = MAX(max_offset, prs_offset(ps)); if (!prs_set_offset(ps,tmp_offset)) return False; } if (psd->off_grp_sid != 0) { tmp_offset = prs_offset(ps); if(!prs_set_offset(ps, old_offset + psd->off_grp_sid)) return False; if (UNMARSHALLING(ps)) { /* reading */ if((psd->grp_sid = (DOM_SID *)prs_alloc_mem(ps,sizeof(*psd->grp_sid))) == NULL) return False; } if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth)) return False; max_offset = MAX(max_offset, prs_offset(ps)); if (!prs_set_offset(ps,tmp_offset)) return False; } if ((psd->type & SEC_DESC_SACL_PRESENT) && psd->off_sacl) { tmp_offset = prs_offset(ps); if(!prs_set_offset(ps, old_offset + psd->off_sacl)) return False; if(!sec_io_acl("sacl", &psd->sacl, ps, depth)) return False; max_offset = MAX(max_offset, prs_offset(ps)); if (!prs_set_offset(ps,tmp_offset)) return False; } if ((psd->type & SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) { tmp_offset = prs_offset(ps); if(!prs_set_offset(ps, old_offset + psd->off_dacl)) return False; if(!sec_io_acl("dacl", &psd->dacl, ps, depth)) return False; max_offset = MAX(max_offset, prs_offset(ps)); if (!prs_set_offset(ps,tmp_offset)) return False; } if(!prs_set_offset(ps, max_offset)) return False; return True; }
BOOL sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth) { unsigned int i; uint32 old_offset; uint32 offset_acl_size; SEC_ACL *psa; /* * Note that the size is always a multiple of 4 bytes due to the * nature of the data structure. Therefore the prs_align() calls * have been removed as they through us off when doing two-layer * marshalling such as in the printing code (NEW_BUFFER). --jerry */ if (ppsa == NULL) return False; psa = *ppsa; if(UNMARSHALLING(ps) && psa == NULL) { /* * This is a read and we must allocate the stuct to read into. */ if((psa = (SEC_ACL *)prs_alloc_mem(ps, sizeof(SEC_ACL))) == NULL) return False; *ppsa = psa; } prs_debug(ps, depth, desc, "sec_io_acl"); depth++; old_offset = prs_offset(ps); if(!prs_uint16("revision", ps, depth, &psa->revision)) return False; if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size)) return False; if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces)) return False; if (UNMARSHALLING(ps)) { /* * Even if the num_aces is zero, allocate memory as there's a difference * between a non-present DACL (allow all access) and a DACL with no ACE's * (allow no access). */ if((psa->ace = (SEC_ACE *)prs_alloc_mem(ps,sizeof(psa->ace[0]) * (psa->num_aces+1))) == NULL) return False; } for (i = 0; i < psa->num_aces; i++) { fstring tmp; slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i); if(!sec_io_ace(tmp, &psa->ace[i], ps, depth)) return False; } if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset)) return False; return True; }
BOOL prs_unistr(const char *name, prs_struct *ps, int depth, UNISTR *str) { int len = 0; unsigned char *p = (unsigned char *)str->buffer; uint8 *start; char *q; uint32 max_len; uint16* ptr; if (MARSHALLING(ps)) { for(len = 0; str->buffer[len] != 0; len++) ; q = prs_mem_get(ps, (len+1)*2); if (q == NULL) return False; start = (uint8*)q; for(len = 0; str->buffer[len] != 0; len++) { if(ps->bigendian_data) { /* swap bytes - p is little endian, q is big endian. */ q[0] = (char)p[1]; q[1] = (char)p[0]; p += 2; q += 2; } else { q[0] = (char)p[0]; q[1] = (char)p[1]; p += 2; q += 2; } } /* * even if the string is 'empty' (only an \0 char) * at this point the leading \0 hasn't been parsed. * so parse it now */ q[0] = 0; q[1] = 0; q += 2; len++; dump_data(5+depth, (char *)start, len * 2); } else { /* unmarshalling */ uint32 alloc_len = 0; q = prs_data_p(ps) + prs_offset(ps); /* * Work out how much space we need and talloc it. */ max_len = (ps->buffer_size - ps->data_offset)/sizeof(uint16); /* the test of the value of *ptr helps to catch the circumstance where we have an emtpty (non-existent) string in the buffer */ for ( ptr = (uint16 *)q; *ptr && (alloc_len <= max_len); alloc_len++) /* do nothing */ ; /* should we allocate anything at all? */ str->buffer = (uint16 *)prs_alloc_mem(ps,alloc_len * sizeof(uint16)); if ((str->buffer == NULL) && (alloc_len > 0)) return False; p = (unsigned char *)str->buffer; len = 0; /* the (len < alloc_len) test is to prevent us from overwriting memory that is not ours...if we get that far, we have a non-null terminated string in the buffer and have messed up somewhere */ while ((len < alloc_len) && (*(uint16 *)q != 0)) { if(ps->bigendian_data) { /* swap bytes - q is big endian, p is little endian. */ p[0] = (unsigned char)q[1]; p[1] = (unsigned char)q[0]; p += 2; q += 2; } else { p[0] = (unsigned char)q[0]; p[1] = (unsigned char)q[1]; p += 2; q += 2; } len++; } if (len < alloc_len) { /* NULL terminate the UNISTR */ str->buffer[len++] = '\0'; } } /* set the offset in the prs_struct; 'len' points to the terminiating NULL in the UNISTR so we need to go one more uint16 */ ps->data_offset += (len)*2; return True; }
BOOL dfs_io_dfs_info_ctr(const char *desc, DFS_INFO_CTR* ctr, uint32 num_entries, uint32 level, prs_struct* ps, int depth) { int i=0; switch(level) { case 1: depth++; /* should depend on whether marshalling or unmarshalling! */ if(UNMARSHALLING(ps)) { ctr->dfs.info1 = (DFS_INFO_1 *)prs_alloc_mem(ps, sizeof(DFS_INFO_1)*num_entries); if (!ctr->dfs.info1) return False; } for(i=0;i<num_entries;i++) { if(!prs_uint32("ptr_entrypath",ps, depth, &ctr->dfs.info1[i].ptr_entrypath)) return False; } for(i=0;i<num_entries;i++) { if(!smb_io_unistr2("", &ctr->dfs.info1[i].entrypath, ctr->dfs.info1[i].ptr_entrypath, ps, depth)) return False; if(!prs_align(ps)) return False; } depth--; break; case 2: depth++; if(UNMARSHALLING(ps)) { ctr->dfs.info2 = (DFS_INFO_2 *)prs_alloc_mem(ps, num_entries*sizeof(DFS_INFO_2)); if (!ctr->dfs.info2) return False; } for(i=0;i<num_entries;i++) { if(!prs_uint32("ptr_entrypath", ps, depth, &ctr->dfs.info2[i].ptr_entrypath)) return False; if(!prs_uint32("ptr_comment", ps, depth, &ctr->dfs.info2[i].ptr_comment)) return False; if(!prs_uint32("state", ps, depth, &ctr->dfs.info2[i].state)) return False; if(!prs_uint32("num_storages", ps, depth, &ctr->dfs.info2[i].num_storages)) return False; } for(i=0;i<num_entries;i++) { if(!smb_io_unistr2("", &ctr->dfs.info2[i].entrypath, ctr->dfs.info2[i].ptr_entrypath, ps, depth)) return False; if(!prs_align(ps)) return False; if(!smb_io_unistr2("",&ctr->dfs.info2[i].comment, ctr->dfs.info2[i].ptr_comment, ps, depth)) return False; if(!prs_align(ps)) return False; } depth--; break; case 3: depth++; if(UNMARSHALLING(ps)) { ctr->dfs.info3 = (DFS_INFO_3 *)prs_alloc_mem(ps, num_entries*sizeof(DFS_INFO_3)); if (!ctr->dfs.info3) return False; } for(i=0;i<num_entries;i++) { if(!prs_uint32("ptr_entrypath", ps, depth, &ctr->dfs.info3[i].ptr_entrypath)) return False; if(!prs_uint32("ptr_comment", ps, depth, &ctr->dfs.info3[i].ptr_comment)) return False; if(!prs_uint32("state", ps, depth, &ctr->dfs.info3[i].state)) return False; if(!prs_uint32("num_storages", ps, depth, &ctr->dfs.info3[i].num_storages)) return False; if(!prs_uint32("ptr_storages", ps, depth, &ctr->dfs.info3[i].ptr_storages)) return False; } for(i=0;i<num_entries;i++) { if(!smb_io_unistr2("", &ctr->dfs.info3[i].entrypath, ctr->dfs.info3[i].ptr_entrypath, ps, depth)) return False; if(!prs_align(ps)) return False; if(!smb_io_unistr2("", &ctr->dfs.info3[i].comment, ctr->dfs.info3[i].ptr_comment, ps, depth)) return False; if(!prs_align(ps)) return False; if(!prs_uint32("num_storage_infos", ps, depth, &ctr->dfs.info3[i].num_storage_infos)) return False; if(!dfs_io_dfs_storage_info("storage_info", &ctr->dfs.info3[i], ps, depth)) return False; } } return True; }