BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth) { if (pol == NULL) return False; prs_debug(ps, depth, desc, "smb_io_pol_hnd"); depth++; if(!prs_align(ps)) return False; if(UNMARSHALLING(ps)) ZERO_STRUCTP(pol); if (!prs_uint32("data1", ps, depth, &pol->data1)) return False; if (!prs_uint32("data2", ps, depth, &pol->data2)) return False; if (!prs_uint16("data3", ps, depth, &pol->data3)) return False; if (!prs_uint16("data4", ps, depth, &pol->data4)) return False; if(!prs_uint8s (False, "data5", ps, depth, pol->data5, sizeof(pol->data5))) return False; return True; }
BOOL prs_ev_open_unknown0( const char *desc, prs_struct *ps, int depth, EVENTLOG_OPEN_UNKNOWN0 *u ) { if ( !u ) return False; if ( !prs_uint16("", ps, depth, &u->unknown1) ) return False; if ( !prs_uint16("", ps, depth, &u->unknown2) ) return False; return True; }
BOOL prs_unistr4_hdr(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4) { prs_debug(ps, depth, desc, "prs_unistr4_hdr"); depth++; if ( !prs_uint16("length", ps, depth, &uni4->length) ) return False; if ( !prs_uint16("size", ps, depth, &uni4->size) ) return False; if ( !prs_io_unistr2_p(desc, ps, depth, &uni4->string) ) return False; return True; }
bool smb_io_rpc_hdr(const char *desc, RPC_HDR *rpc, prs_struct *ps, int depth) { if (rpc == NULL) return False; prs_debug(ps, depth, desc, "smb_io_rpc_hdr"); depth++; if(!prs_uint8 ("major ", ps, depth, &rpc->major)) return False; if(!prs_uint8 ("minor ", ps, depth, &rpc->minor)) return False; if(!prs_uint8 ("pkt_type ", ps, depth, &rpc->pkt_type)) return False; if(!prs_uint8 ("flags ", ps, depth, &rpc->flags)) return False; /* We always marshall in little endian format. */ if (MARSHALLING(ps)) rpc->pack_type[0] = 0x10; if(!prs_uint8("pack_type0", ps, depth, &rpc->pack_type[0])) return False; if(!prs_uint8("pack_type1", ps, depth, &rpc->pack_type[1])) return False; if(!prs_uint8("pack_type2", ps, depth, &rpc->pack_type[2])) return False; if(!prs_uint8("pack_type3", ps, depth, &rpc->pack_type[3])) return False; /* * If reading and pack_type[0] == 0 then the data is in big-endian * format. Set the flag in the prs_struct to specify reverse-endainness. */ if (UNMARSHALLING(ps) && rpc->pack_type[0] == 0) { DEBUG(10,("smb_io_rpc_hdr: PDU data format is big-endian. Setting flag.\n")); prs_set_endian_data(ps, RPC_BIG_ENDIAN); } if(!prs_uint16("frag_len ", ps, depth, &rpc->frag_len)) return False; if(!prs_uint16("auth_len ", ps, depth, &rpc->auth_len)) return False; if(!prs_uint32("call_id ", ps, depth, &rpc->call_id)) return False; return True; }
BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth) { if (loginfo == NULL) return False; prs_debug(ps, depth, desc, "smb_io_log_info"); depth++; if(!prs_align(ps)) return False; if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer)) return False; if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth)) return False; if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth)) return False; if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan)) return False; if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth)) return False; return True; }
static bool smb_io_rpc_hdr_bba(const char *desc, RPC_HDR_BBA *rpc, prs_struct *ps, int depth) { if (rpc == NULL) return False; prs_debug(ps, depth, desc, "smb_io_rpc_hdr_bba"); depth++; if(!prs_uint16("max_tsize", ps, depth, &rpc->max_tsize)) return False; if(!prs_uint16("max_rsize", ps, depth, &rpc->max_rsize)) return False; if(!prs_uint32("assoc_gid", ps, depth, &rpc->assoc_gid)) return False; return True; }
bool smb_io_rpc_context(const char *desc, RPC_CONTEXT *rpc_ctx, prs_struct *ps, int depth) { int i; if (rpc_ctx == NULL) return False; if(!prs_align(ps)) return False; if(!prs_uint16("context_id ", ps, depth, &rpc_ctx->context_id )) return False; if(!prs_uint8 ("num_transfer_syntaxes", ps, depth, &rpc_ctx->num_transfer_syntaxes)) return False; /* num_transfer_syntaxes must not be zero. */ if (rpc_ctx->num_transfer_syntaxes == 0) return False; if(!smb_io_rpc_iface("", &rpc_ctx->abstract, ps, depth)) return False; if (UNMARSHALLING(ps)) { if (!(rpc_ctx->transfer = PRS_ALLOC_MEM(ps, RPC_IFACE, rpc_ctx->num_transfer_syntaxes))) { return False; } } for (i = 0; i < rpc_ctx->num_transfer_syntaxes; i++ ) { if (!smb_io_rpc_iface("", &rpc_ctx->transfer[i], ps, depth)) return False; } return True; }
static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth) { if (sam == NULL) return False; prs_debug(ps, depth, desc, "smb_io_sam_info"); depth++; if(!prs_align(ps)) return False; if(!smb_io_clnt_info2("", &sam->client, ps, depth)) return False; if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred)) return False; if(!smb_io_cred("", &sam->rtn_cred, ps, depth)) return False; if(!prs_uint16("logon_level ", ps, depth, &sam->logon_level)) return False; if (sam->logon_level != 0 && sam->ctr != NULL) { if(!net_io_id_info_ctr("logon_info", sam->ctr, ps, depth)) return False; } return True; }
static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth) { if (ctr == NULL) return False; prs_debug(ps, depth, desc, "smb_io_sam_info"); depth++; /* don't 4-byte align here! */ if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value)) return False; switch (ctr->switch_value) { case 1: if(!net_io_id_info1("", &ctr->auth.id1, ps, depth)) return False; break; case 2: if(!net_io_id_info2("", &ctr->auth.id2, ps, depth)) return False; break; default: /* PANIC! */ DEBUG(4,("smb_io_sam_info: unknown switch_value!\n")); break; } return True; }
BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth) { if (r_l == NULL) return False; prs_debug(ps, depth, desc, "net_io_r_sam_logon"); depth++; if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */ return False; if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */ return False; if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value)) return False; if(!prs_align(ps)) return False; if (r_l->switch_value != 0) { if(!net_io_user_info3("", r_l->user, ps, depth)) return False; } if(!prs_uint32("auth_resp ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */ return False; if(!prs_uint32("status ", ps, depth, &r_l->status)) return False; if(!prs_align(ps)) return False; return True; }
bool smb_io_rpc_hdr_req(const char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth) { if (rpc == NULL) return False; prs_debug(ps, depth, desc, "smb_io_rpc_hdr_req"); depth++; if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint)) return False; if(!prs_uint16("context_id", ps, depth, &rpc->context_id)) return False; if(!prs_uint16("opnum ", ps, depth, &rpc->opnum)) 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 smb_io_lockout_string_hdr(const char *desc, HDR_LOCKOUT_STRING *hdr_account_lockout, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "smb_io_lockout_string_hdr"); depth++; if(!prs_align(ps)) return False; if(!prs_uint16("size", ps, depth, &hdr_account_lockout->size)) return False; if(!prs_uint16("length", ps, depth, &hdr_account_lockout->length)) return False; if(!prs_uint32("buffer", ps, depth, &hdr_account_lockout->buffer)) return False; return True; }
static bool hbin_prs_lf_records(const char *desc, REGF_HBIN *hbin, int depth, REGF_NK_REC *nk) { int i; REGF_LF_REC *lf = &nk->subkeys; uint32 data_size, start_off, end_off; depth++; /* check if we have anything to do first */ if ( nk->num_subkeys == 0 ) return true; /* move to the LF record */ if ( !prs_set_offset( &hbin->ps, nk->subkeys_off + HBIN_HDR_SIZE - hbin->first_hbin_off ) ) return false; /* backup and get the data_size */ if ( !prs_set_offset( &hbin->ps, hbin->ps.data_offset-sizeof(uint32)) ) return false; start_off = hbin->ps.data_offset; if ( !prs_uint32( "rec_size", &hbin->ps, depth, &lf->rec_size )) return false; if(!prs_uint8s("header", &hbin->ps, depth, lf->header, sizeof(lf->header))) return false; if ( !prs_uint16( "num_keys", &hbin->ps, depth, &lf->num_keys)) return false; if ( hbin->ps.io ) { if ( !(lf->hashes = (REGF_HASH_REC*)zcalloc(sizeof(REGF_HASH_REC), lf->num_keys )) ) return false; } for ( i=0; i<lf->num_keys; i++ ) { if ( !prs_hash_rec( "hash_rec", &hbin->ps, depth, &lf->hashes[i] ) ) return false; } end_off = hbin->ps.data_offset; /* data_size must be divisible by 8 and large enough to hold the original record */ data_size = ((start_off - end_off) & 0xfffffff8 ); /* if ( data_size > lf->rec_size )*/ /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->rec_size));*/ if ( !hbin->ps.io ) hbin->dirty = true; return true; }
BOOL smb_io_strhdr(const char *desc, STRHDR *hdr, prs_struct *ps, int depth) { if (hdr == NULL) return False; prs_debug(ps, depth, desc, "smb_io_strhdr"); depth++; prs_align(ps); if(!prs_uint16("str_str_len", ps, depth, &hdr->str_str_len)) return False; if(!prs_uint16("str_max_len", ps, depth, &hdr->str_max_len)) return False; if(!prs_uint32("buffer ", ps, depth, &hdr->buffer)) return False; return True; }
BOOL prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4) { void *ptr; prs_debug(ps, depth, desc, "prs_unistr4"); depth++; if ( !prs_uint16("length", ps, depth, &uni4->length )) return False; if ( !prs_uint16("size", ps, depth, &uni4->size )) return False; ptr = uni4->string; if ( !prs_pointer( desc, ps, depth, &ptr, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) ) return False; uni4->string = (UNISTR2 *)ptr; return True; }
BOOL ds_io_q_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_Q_GETPRIMDOMINFO *q_u) { prs_debug(ps, depth, desc, "ds_io_q_getprimdominfo"); depth++; if(!prs_align(ps)) return False; if ( !prs_uint16( "level", ps, depth, &q_u->level ) ) return False; return True; }
BOOL ds_io_r_getprimdominfo( const char *desc, prs_struct *ps, int depth, DS_R_GETPRIMDOMINFO *r_u) { prs_debug(ps, depth, desc, "ds_io_r_getprimdominfo"); depth++; if(!prs_align(ps)) return False; if ( !prs_uint32( "ptr", ps, depth, &r_u->ptr ) ) return False; if ( r_u->ptr ) { if ( !prs_uint16( "level", ps, depth, &r_u->level ) ) return False; if ( !prs_uint16( "unknown0", ps, depth, &r_u->unknown0 ) ) return False; switch ( r_u->level ) { case DsRolePrimaryDomainInfoBasic: if ( !ds_io_dominfobasic( "dominfobasic", ps, depth, &r_u->info.basic ) ) return False; break; default: return False; } } if ( !prs_align(ps) ) return False; if ( !prs_ntstatus("status", ps, depth, &r_u->status ) ) return False; return True; }
BOOL prs_uint16_pre(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset) { *offset = ps->data_offset; if (UNMARSHALLING(ps)) { /* reading. */ return prs_uint16(name, ps, depth, data16); } else { char *q = prs_mem_get(ps, sizeof(uint16)); if(q ==NULL) return False; ps->data_offset += sizeof(uint16); } return True; }
static bool hbin_prs_sk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_SK_REC *sk ) { prs_struct *ps = &hbin->ps; uint16 tag = 0xFFFF; uint32 data_size, start_off, end_off; depth++; if ( !prs_set_offset( &hbin->ps, sk->sk_off + HBIN_HDR_SIZE - hbin->first_hbin_off ) ) return false; /* backup and get the data_size */ if ( !prs_set_offset( &hbin->ps, hbin->ps.data_offset-sizeof(uint32)) ) return false; start_off = hbin->ps.data_offset; if ( !prs_uint32( "rec_size", &hbin->ps, depth, &sk->rec_size )) return false; if (!prs_uint8s("header", ps, depth, sk->header, sizeof(sk->header))) return false; if ( !prs_uint16( "tag", ps, depth, &tag)) return false; if ( !prs_uint32( "prev_sk_off", ps, depth, &sk->prev_sk_off)) return false; if ( !prs_uint32( "next_sk_off", ps, depth, &sk->next_sk_off)) return false; if ( !prs_uint32( "ref_count", ps, depth, &sk->ref_count)) return false; if ( !prs_uint32( "size", ps, depth, &sk->size)) return false; if ( !sec_io_desc( "sec_desc", &sk->sec_desc, ps, depth )) return false; end_off = hbin->ps.data_offset; /* data_size must be divisible by 8 and large enough to hold the original record */ data_size = ((start_off - end_off) & 0xfffffff8 ); /* if ( data_size > sk->rec_size )*/ /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->rec_size));*/ if ( !hbin->ps.io ) hbin->dirty = true; return true; }
static bool smb_io_rpc_results(const char *desc, RPC_RESULTS *res, prs_struct *ps, int depth) { if (res == NULL) return False; prs_debug(ps, depth, desc, "smb_io_rpc_results"); depth++; if(!prs_align(ps)) return False; if(!prs_uint8 ("num_results", ps, depth, &res->num_results)) return False; if(!prs_align(ps)) return False; if(!prs_uint16("result ", ps, depth, &res->result)) return False; if(!prs_uint16("reason ", ps, depth, &res->reason)) return False; return True; }
BOOL smb_io_uuid(const char *desc, struct uuid *uuid, prs_struct *ps, int depth) { if (uuid == NULL) return False; prs_debug(ps, depth, desc, "smb_io_uuid"); depth++; if(!prs_uint32 ("data ", ps, depth, &uuid->time_low)) return False; if(!prs_uint16 ("data ", ps, depth, &uuid->time_mid)) return False; if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version)) return False; if(!prs_uint8s (False, "data ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq))) return False; if(!prs_uint8s (False, "data ", ps, depth, uuid->node, sizeof(uuid->node))) return False; return True; }
static bool smb_io_rpc_addr_str(const char *desc, RPC_ADDR_STR *str, prs_struct *ps, int depth) { if (str == NULL) return False; prs_debug(ps, depth, desc, "smb_io_rpc_addr_str"); depth++; if(!prs_align(ps)) return False; if(!prs_uint16 ( "len", ps, depth, &str->len)) return False; if(!prs_uint8s (True, "str", ps, depth, (uchar*)str->str, MIN(str->len, sizeof(str->str)) )) return False; return True; }
bool smb_io_rpc_hdr_resp(const char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth) { if (rpc == NULL) return False; prs_debug(ps, depth, desc, "smb_io_rpc_hdr_resp"); depth++; if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint)) return False; if(!prs_uint16("context_id", ps, depth, &rpc->context_id)) return False; if(!prs_uint8 ("cancel_ct ", ps, depth, &rpc->cancel_count)) return False; if(!prs_uint8 ("reserved ", ps, depth, &rpc->reserved)) return False; return True; }
BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth) { if (q_l == NULL) return False; prs_debug(ps, depth, desc, "net_io_q_sam_logon"); depth++; if(!prs_align(ps)) return False; if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) /* domain SID */ return False; if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level)) return False; return True; }
BOOL prs_uint16_post(const char *name, prs_struct *ps, int depth, uint16 *data16, uint32 ptr_uint16, uint32 start_offset) { if (MARSHALLING(ps)) { /* * Writing - temporarily move the offset pointer. */ uint16 data_size = ps->data_offset - start_offset; uint32 old_offset = ps->data_offset; ps->data_offset = ptr_uint16; if(!prs_uint16(name, ps, depth, &data_size)) { ps->data_offset = old_offset; return False; } ps->data_offset = old_offset; } else { ps->data_offset = start_offset + (uint32)(*data16); } return True; }
BOOL smb_io_dom_rid(const char *desc, DOM_RID *rid, prs_struct *ps, int depth) { if (rid == NULL) return False; prs_debug(ps, depth, desc, "smb_io_dom_rid"); depth++; if(!prs_align(ps)) return False; if(!prs_uint16("type ", ps, depth, &rid->type)) return False; if(!prs_align(ps)) return False; if(!prs_uint32("rid ", ps, depth, &rid->rid)) return False; if(!prs_uint32("rid_idx", ps, depth, &rid->rid_idx)) 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 smb_io_relarraystr(const char *desc, RPC_BUFFER *buffer, int depth, uint16 **string) { UNISTR chaine; prs_struct *ps=&buffer->prs; if (MARSHALLING(ps)) { uint32 struct_offset = prs_offset(ps); uint32 relative_offset; uint16 *p; uint16 *q; uint16 zero=0; p=*string; q=*string; /* first write the last 0 */ buffer->string_at_end -= 2; if(!prs_set_offset(ps, buffer->string_at_end)) return False; if(!prs_uint16("leading zero", ps, depth, &zero)) return False; while (p && (*p!=0)) { while (*q!=0) q++; /* Yes this should be malloc not talloc. Don't change. */ chaine.buffer = (uint16 *) SMB_MALLOC((q-p+1)*sizeof(uint16)); if (chaine.buffer == NULL) return False; memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16)); buffer->string_at_end -= (q-p+1)*sizeof(uint16); if(!prs_set_offset(ps, buffer->string_at_end)) { SAFE_FREE(chaine.buffer); return False; } /* write the string */ if (!smb_io_unistr(desc, &chaine, ps, depth)) { SAFE_FREE(chaine.buffer); return False; } q++; p=q; SAFE_FREE(chaine.buffer); } if(!prs_set_offset(ps, struct_offset)) return False; relative_offset=buffer->string_at_end - buffer->struct_start; /* write its offset */ if (!prs_uint32("offset", ps, depth, &relative_offset)) return False; } else { /* UNMARSHALLING */ uint32 old_offset; uint16 *chaine2=NULL; int l_chaine=0; int l_chaine2=0; size_t realloc_size = 0; *string=NULL; /* read the offset */ if (!prs_uint32("offset", ps, depth, &buffer->string_at_end)) return False; old_offset = prs_offset(ps); if(!prs_set_offset(ps, buffer->string_at_end + buffer->struct_start)) return False; do { if (!smb_io_unistr(desc, &chaine, ps, depth)) return False; l_chaine=str_len_uni(&chaine); /* we're going to add two more bytes here in case this is the last string in the array and we need to add an extra NULL for termination */ if (l_chaine > 0) { realloc_size = (l_chaine2+l_chaine+2)*sizeof(uint16); /* Yes this should be realloc - it's freed below. JRA */ if((chaine2=(uint16 *)SMB_REALLOC(chaine2, realloc_size)) == NULL) { return False; } memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16)); l_chaine2+=l_chaine+1; } } while(l_chaine!=0); /* the end should be bould NULL terminated so add the second one here */ if (chaine2) { chaine2[l_chaine2] = '\0'; *string=(uint16 *)TALLOC_MEMDUP(prs_get_mem_context(ps),chaine2,realloc_size); if (!*string) { return False; } SAFE_FREE(chaine2); } if(!prs_set_offset(ps, old_offset)) return False; } return True; }