BOOL smb_io_relsecdesc(const char *desc, RPC_BUFFER *buffer, int depth, SEC_DESC **secdesc) { prs_struct *ps= &buffer->prs; prs_debug(ps, depth, desc, "smb_io_relsecdesc"); depth++; if (MARSHALLING(ps)) { uint32 struct_offset = prs_offset(ps); uint32 relative_offset; if (! *secdesc) { relative_offset = 0; if (!prs_uint32("offset", ps, depth, &relative_offset)) return False; return True; } if (*secdesc != NULL) { buffer->string_at_end -= sec_desc_size(*secdesc); if(!prs_set_offset(ps, buffer->string_at_end)) return False; /* write the secdesc */ if (!sec_io_desc(desc, secdesc, ps, depth)) return False; 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 { uint32 old_offset; /* 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; /* read the sd */ if (!sec_io_desc(desc, secdesc, ps, depth)) return False; if(!prs_set_offset(ps, old_offset)) return False; } return True; }
SEC_DESC *get_share_security( TALLOC_CTX *ctx, const char *servicename, size_t *psize) { prs_struct ps; fstring key; SEC_DESC *psd = NULL; if (!share_info_db_init()) { return NULL; } *psize = 0; /* Fetch security descriptor from tdb */ slprintf(key, sizeof(key)-1, "SECDESC/%s", servicename); if (tdb_prs_fetch(share_tdb, key, &ps, ctx)!=0 || !sec_io_desc("get_share_security", &psd, &ps, 1)) { DEBUG(4, ("get_share_security: using default secdesc for %s\n", servicename)); return get_share_security_default(ctx, psize, GENERIC_ALL_ACCESS); } if (psd) *psize = sec_desc_size(psd); prs_mem_free(&ps); return psd; }
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 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; }
/**************************************************************************** query the security descriptor for a open file ****************************************************************************/ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, TALLOC_CTX *mem_ctx) { char param[8]; char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; prs_struct pd; SEC_DESC *psd = NULL; SIVAL(param, 0, fnum); SIVAL(param, 4, 0x7); if (!cli_send_nt_trans(cli, NT_TRANSACT_QUERY_SECURITY_DESC, 0, NULL, 0, 0, param, 8, 4, NULL, 0, 0x10000)) { DEBUG(1,("Failed to send NT_TRANSACT_QUERY_SECURITY_DESC\n")); goto cleanup; } if (!cli_receive_nt_trans(cli, &rparam, &rparam_count, &rdata, &rdata_count)) { DEBUG(1,("Failed to recv NT_TRANSACT_QUERY_SECURITY_DESC\n")); goto cleanup; } prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL); prs_copy_data_in(&pd, rdata, rdata_count); prs_set_offset(&pd,0); if (!sec_io_desc("sd data", &psd, &pd, 1)) { DEBUG(1,("Failed to parse secdesc\n")); goto cleanup; } cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); prs_mem_free(&pd); return psd; }
BOOL set_share_security(const char *share_name, SEC_DESC *psd) { prs_struct ps; TALLOC_CTX *mem_ctx = NULL; fstring key; BOOL ret = False; if (!share_info_db_init()) { return False; } mem_ctx = talloc_init("set_share_security"); if (mem_ctx == NULL) return False; prs_init(&ps, (uint32)sec_desc_size(psd), mem_ctx, MARSHALL); if (!sec_io_desc("share_security", &psd, &ps, 1)) goto out; slprintf(key, sizeof(key)-1, "SECDESC/%s", share_name); if (tdb_prs_store(share_tdb, key, &ps)==0) { ret = True; DEBUG(5,("set_share_security: stored secdesc for %s\n", share_name )); } else { DEBUG(1,("set_share_security: Failed to store secdesc for %s\n", share_name )); } /* Free malloc'ed memory */ out: prs_mem_free(&ps); if (mem_ctx) talloc_destroy(mem_ctx); return ret; }
/**************************************************************************** set the security descriptor for a open file ****************************************************************************/ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) { char param[8]; char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; uint32 sec_info = 0; TALLOC_CTX *mem_ctx; prs_struct pd; BOOL ret = False; if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) { DEBUG(0,("talloc_init failed.\n")); goto cleanup; } prs_init(&pd, 0, mem_ctx, MARSHALL); prs_give_memory(&pd, NULL, 0, True); if (!sec_io_desc("sd data", &sd, &pd, 1)) { DEBUG(1,("Failed to marshall secdesc\n")); goto cleanup; } SIVAL(param, 0, fnum); if (sd->off_dacl) sec_info |= DACL_SECURITY_INFORMATION; if (sd->off_owner_sid) sec_info |= OWNER_SECURITY_INFORMATION; if (sd->off_grp_sid) sec_info |= GROUP_SECURITY_INFORMATION; SSVAL(param, 4, sec_info); if (!cli_send_nt_trans(cli, NT_TRANSACT_SET_SECURITY_DESC, 0, NULL, 0, 0, param, 8, 0, prs_data_p(&pd), prs_offset(&pd), 0)) { DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); goto cleanup; } if (!cli_receive_nt_trans(cli, &rparam, &rparam_count, &rdata, &rdata_count)) { DEBUG(1,("NT_TRANSACT_SET_SECURITY_DESC failed\n")); goto cleanup; } ret = True; cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); talloc_destroy(mem_ctx); prs_mem_free(&pd); return ret; }
static void fill_in_printer_values( NT_PRINTER_INFO_LEVEL_2 *info2, REGVAL_CTR *values ) { DEVICEMODE *devmode; prs_struct prs; uint32 offset; UNISTR2 data; char *p; uint32 printer_status = PRINTER_STATUS_OK; regval_ctr_addvalue( values, "Attributes", REG_DWORD, (char*)&info2->attributes, sizeof(info2->attributes) ); regval_ctr_addvalue( values, "Priority", REG_DWORD, (char*)&info2->priority, sizeof(info2->attributes) ); regval_ctr_addvalue( values, "ChangeID", REG_DWORD, (char*)&info2->changeid, sizeof(info2->changeid) ); regval_ctr_addvalue( values, "Default Priority", REG_DWORD, (char*)&info2->default_priority, sizeof(info2->default_priority) ); /* lie and say everything is ok since we don't want to call print_queue_length() to get the real status */ regval_ctr_addvalue( values, "Status", REG_DWORD, (char*)&printer_status, sizeof(info2->status) ); regval_ctr_addvalue( values, "StartTime", REG_DWORD, (char*)&info2->starttime, sizeof(info2->starttime) ); regval_ctr_addvalue( values, "UntilTime", REG_DWORD, (char*)&info2->untiltime, sizeof(info2->untiltime) ); /* strip the \\server\ from this string */ if ( !(p = strrchr( info2->printername, '\\' ) ) ) p = info2->printername; else p++; init_unistr2( &data, p, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->location, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->comment, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->portname, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Print Processor", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); init_unistr2( &data, "RAW", UNI_STR_TERMINATE); regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) ); /* use a prs_struct for converting the devmode and security descriptor to REG_BINARY */ prs_init( &prs, RPC_MAX_PDU_FRAG_LEN, values, MARSHALL); /* stream the device mode */ if ( (devmode = construct_dev_mode( info2->sharename )) != NULL ) { if ( spoolss_io_devmode( "devmode", &prs, 0, devmode ) ) { offset = prs_offset( &prs ); regval_ctr_addvalue( values, "Default Devmode", REG_BINARY, prs_data_p(&prs), offset ); } } prs_mem_clear( &prs ); prs_set_offset( &prs, 0 ); /* stream the printer security descriptor */ if ( info2->secdesc_buf && info2->secdesc_buf->len ) { if ( sec_io_desc("sec_desc", &info2->secdesc_buf->sec, &prs, 0 ) ) { offset = prs_offset( &prs ); regval_ctr_addvalue( values, "Security", REG_BINARY, prs_data_p(&prs), offset ); } } prs_mem_free( &prs ); return; }