static void filter_reply(char *buf) { int msg_type = CVAL(buf,0); int type = CVAL(buf,smb_com); unsigned x; if (msg_type) return; switch (type) { case SMBnegprot: /* force the security bits */ x = CVAL(buf, smb_vwv1); x = (x | SECURITY_SET) & ~SECURITY_MASK; SCVAL(buf, smb_vwv1, x); /* force the capabilities */ x = IVAL(buf,smb_vwv9+1); x = (x | CAPABILITY_SET) & ~CAPABILITY_MASK; SIVAL(buf, smb_vwv9+1, x); break; } }
void srv_calculate_sign_mac(struct smbd_server_connection *conn, char *outbuf, uint32_t seqnum) { uint8_t *outhdr; size_t len; /* Check if it's a non-session message. */ if(CVAL(outbuf,0)) { return; } len = smb_len(outbuf); outhdr = (uint8_t *)outbuf + NBT_HDR_SIZE; smb_signing_sign_pdu(conn->smb1.signing_state, outhdr, len, seqnum); }
static void reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS status) { files_struct *fsp = blr->fsp; uint16 num_ulocks = SVAL(blr->req->vwv+6, 0); uint64_t count = (uint64_t)0, offset = (uint64_t) 0; uint32 lock_pid; unsigned char locktype = CVAL(blr->req->vwv+3, 0); bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); uint8_t *data; int i; data = (uint8_t *)blr->req->buf + ((large_file_format ? 20 : 10)*num_ulocks); /* * Data now points at the beginning of the list * of smb_lkrng structs. */ /* * Ensure we don't do a remove on the lock that just failed, * as under POSIX rules, if we have a lock already there, we * will delete it (and we shouldn't) ..... */ for(i = blr->lock_num - 1; i >= 0; i--) { bool err; lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); /* * We know err cannot be set as if it was the lock * request would never have been queued. JRA. */ do_unlock(smbd_messaging_context(), fsp, lock_pid, count, offset, WINDOWS_LOCK); } generic_blocking_lock_error(blr, status); }
BOOL prs_uint8(const char *name, prs_struct *ps, int depth, uint8 *data8) { char *q = prs_mem_get(ps, 1); if (q == NULL) return False; if (UNMARSHALLING(ps)) *data8 = CVAL(q,0); else SCVAL(q,0,*data8); DEBUG(5,("%s%04x %s: %02x\n", tab_depth(depth), ps->data_offset, name, *data8)); ps->data_offset += 1; return True; }
NTSTATUS cli_nt_error(struct cli_state *cli) { int flgs2 = SVAL(cli->inbuf,smb_flg2); /* Deal with socket errors first. */ if (cli->fd == -1 && cli->smb_rw_error) { return cli_smb_rw_error_to_ntstatus(cli); } if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) { int e_class = CVAL(cli->inbuf,smb_rcls); int code = SVAL(cli->inbuf,smb_err); return dos_to_ntstatus(e_class, code); } return NT_STATUS(IVAL(cli->inbuf,smb_rcls)); }
static void undo_locks_obtained(struct blocking_lock_record *blr) { files_struct *fsp = blr->fsp; uint16 num_ulocks = SVAL(blr->req->vwv+6, 0); uint64_t count = (uint64_t)0, offset = (uint64_t) 0; uint64_t smblctx; unsigned char locktype = CVAL(blr->req->vwv+3, 0); bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); uint8_t *data; int i; data = discard_const_p(uint8_t, blr->req->buf) + ((large_file_format ? 20 : 10)*num_ulocks); /* * Data now points at the beginning of the list * of smb_lkrng structs. */ /* * Ensure we don't do a remove on the lock that just failed, * as under POSIX rules, if we have a lock already there, we * will delete it (and we shouldn't) ..... */ for(i = blr->lock_num - 1; i >= 0; i--) { bool err; smblctx = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); /* * We know err cannot be set as if it was the lock * request would never have been queued. JRA. */ do_unlock(fsp->conn->sconn->msg_ctx, fsp, smblctx, count, offset, WINDOWS_LOCK); } }
static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) { char *inbuf = blr->inbuf; files_struct *fsp = blr->fsp; connection_struct *conn = conn_find(SVAL(inbuf,smb_tid)); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); SMB_BIG_UINT count = (SMB_BIG_UINT)0, offset = (SMB_BIG_UINT) 0; uint16 lock_pid; unsigned char locktype = CVAL(inbuf,smb_vwv3); BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); char *data; int i; data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); /* * Data now points at the beginning of the list * of smb_lkrng structs. */ /* * Ensure we don't do a remove on the lock that just failed, * as under POSIX rules, if we have a lock already there, we * will delete it (and we shouldn't) ..... */ for(i = blr->lock_num - 1; i >= 0; i--) { BOOL err; lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); /* * We know err cannot be set as if it was the lock * request would never have been queued. JRA. */ do_unlock(fsp,conn,lock_pid,count,offset); } generic_blocking_lock_error(blr, status); }
void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck) { struct blocking_lock_record *blr, *blr_cancelled, *next = NULL; for(blr = blocking_lock_queue; blr; blr = next) { unsigned char locktype = 0; next = blr->next; if (blr->fsp->fnum != fsp->fnum) { continue; } if (blr->req->cmd == SMBlockingX) { locktype = CVAL(blr->req->vwv+3, 0); } DEBUG(10, ("remove_pending_lock_requests_by_fid - removing " "request type %d for file %s fnum = %d\n", blr->req->cmd, fsp->fsp_name, fsp->fnum)); blr_cancelled = blocking_lock_cancel(fsp, blr->lock_pid, blr->offset, blr->count, blr->lock_flav, locktype, NT_STATUS_RANGE_NOT_LOCKED); SMB_ASSERT(blr_cancelled == blr); brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav, blr); /* We're closing the file fsp here, so ensure * we don't have a dangling pointer. */ blr->fsp = NULL; } }
char *va_to_string(Value value) { switch (value.type) { case VAL_TYPE_STR: return strdup(SVAL(value)); case VAL_TYPE_BOOL: return strdup(IVAL(value) ? "true" : "false"); case VAL_TYPE_INT: { char *num_str = malloc(VALUE_STR_CONVERT_SIZE); if (num_str == NULL) { return NULL; } snprintf(num_str, VALUE_STR_CONVERT_SIZE, "%ld", IVAL(value)); return num_str; } case VAL_TYPE_FLOAT: { char *num_str = malloc(VALUE_STR_CONVERT_SIZE); if (num_str == NULL) { return NULL; } snprintf(num_str, VALUE_STR_CONVERT_SIZE, "%f", FVAL(value)); return num_str; } case VAL_TYPE_REGEX: return strdup(RVAL(value).regex_pattern); case VAL_TYPE_SHELL_COMMAND: return strdup(CVAL(value)); default: assert(!"Invalid value type"); break; } return NULL; }
const char *sum_as_hex(const char *sum) { static char buf[MAX_DIGEST_LEN*2+1]; int i, x1, x2; char *c = buf + checksum_len*2; assert(c - buf < (int)sizeof buf); *c = '\0'; for (i = checksum_len; --i >= 0; ) { x1 = CVAL(sum, i); x2 = x1 >> 4; x1 &= 0xF; *--c = x1 <= 9 ? x1 + '0' : x1 + 'a' - 10; *--c = x2 <= 9 ? x2 + '0' : x2 + 'a' - 10; } return buf; }
ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout) { ssize_t len; for(;;) { len = read_smb_length_return_keepalive(fd, inbuf, timeout); if(len < 0) return len; /* Ignore session keepalives. */ if(CVAL(inbuf,0) != 0x85) break; } DEBUG(10,("read_smb_length: got smb length of %d\n",len)); return len; }
bool cli_is_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; /* A socket error is always an error. */ if (cli->fd == -1 && cli->smb_rw_error != 0) { return True; } if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { /* Return error is error bits are set */ rcls = IVAL(cli->inbuf, smb_rcls); return (rcls & 0xF0000000) == 0xC0000000; } /* Return error if error class in non-zero */ rcls = CVAL(cli->inbuf, smb_rcls); return rcls != 0; }
bool srv_check_sign_mac(struct smbd_server_connection *conn, const char *inbuf, uint32_t *seqnum, bool trusted_channel) { const uint8_t *inhdr; size_t len; /* Check if it's a non-session message. */ if(CVAL(inbuf,0)) { return true; } len = smb_len(inbuf); inhdr = (const uint8_t *)inbuf + NBT_HDR_SIZE; if (trusted_channel) { NTSTATUS status; if (len < (HDR_SS_FIELD + 8)) { DEBUG(1,("smb_signing_check_pdu: Can't check signature " "on short packet! smb_len = %u\n", (unsigned)len)); return false; } status = NT_STATUS(IVAL(inhdr, HDR_SS_FIELD + 4)); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("smb_signing_check_pdu: trusted channel passed %s\n", nt_errstr(status))); return false; } *seqnum = IVAL(inhdr, HDR_SS_FIELD); return true; } *seqnum = smb_signing_next_seqnum(conn->smb1.signing_state, false); return smb_signing_check_pdu(conn->smb1.signing_state, inhdr, len, *seqnum); }
/* parse a data blob into a ncacn_packet structure. This handles both input and output packets */ static NTSTATUS ncacn_pull(struct dcerpc_connection *c, DATA_BLOB *blob, TALLOC_CTX *mem_ctx, struct ncacn_packet *pkt) { struct ndr_pull *ndr; enum ndr_err_code ndr_err; ndr = ndr_pull_init_flags(c, blob, mem_ctx); if (!ndr) { return NT_STATUS_NO_MEMORY; } if (! (CVAL(blob->data, DCERPC_DREP_OFFSET) & DCERPC_DREP_LE)) { ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, pkt); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } return NT_STATUS_OK; }
BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) { BOOL ret; for(;;) { ret = receive_smb(fd, buffer, timeout); if (!ret) { DEBUG(10,("client_receive_smb failed\n")); show_msg(buffer); return ret; } /* Ignore session keepalive packets. */ if(CVAL(buffer,0) != 0x85) break; } show_msg(buffer); return ret; }
static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { *finfo = def_finfo; finfo->cli = cli; finfo->mode = CVAL(p,21); /* this date is converted to GMT by make_unix_date */ finfo->ctime_ts.tv_sec = cli_make_unix_date(cli, p+22); finfo->ctime_ts.tv_nsec = 0; finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec; finfo->mtime_ts.tv_nsec = finfo->atime_ts.tv_nsec = 0; finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1); finfo->short_name[sizeof(finfo->short_name)-1] = '\0'; } return(DIR_STRUCT_SIZE); }
static void announce_local_master_browser_to_domain_master_browser( struct work_record *work) { pstring outbuf; char *p; if(ismyip(work->dmb_addr)) { if( DEBUGLVL( 2 ) ) { dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" ); dbgtext( "We are both a domain and a local master browser for " ); dbgtext( "workgroup %s. ", work->work_group ); dbgtext( "Do not announce to ourselves.\n" ); } return; } memset(outbuf,'\0',sizeof(outbuf)); p = outbuf; CVAL(p,0) = ANN_MasterAnnouncement; p++; StrnCpy(p,global_myname,15); strupper(p); p = skip_string(p,1); if( DEBUGLVL( 4 ) ) { dbgtext( "announce_local_master_browser_to_domain_master_browser:\n" ); dbgtext( "Sending local master announce to " ); dbgtext( "%s for workgroup %s.\n", nmb_namestr(&work->dmb_name), work->work_group ); } send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf), global_myname, 0x0, work->dmb_name.name, 0x0, work->dmb_addr, FIRST_SUBNET->myip, DGRAM_PORT); }
/**************************************************************************** start a message sequence ****************************************************************************/ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, int *grp) { return False; #if 0 char *p; /* send a SMBsendstrt command */ memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBsendstrt; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,username); unix_to_dos(p,True); p = skip_string(p,1); *p++ = 4; pstrcpy(p,host); unix_to_dos(p,True); p = skip_string(p,1); set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (cli_error(cli, NULL, NULL, NULL)) return False; *grp = SVAL(cli->inbuf,smb_vwv0); return True; #endif }
/**************************************************************************** return a SMB string from an SMB buffer ****************************************************************************/ char *smb_dos_errstr(char *inbuf) { char *result; int e_class = CVAL(inbuf,smb_rcls); int num = SVAL(inbuf,smb_err); int i,j; for (i=0;err_classes[i].e_class;i++) if (err_classes[i].code == e_class) { if (err_classes[i].err_msgs) { err_code_struct *err = err_classes[i].err_msgs; for (j=0;err[j].name;j++) if (num == err[j].code) { if (DEBUGLEVEL > 0) result = talloc_asprintf( talloc_tos(), "%s - %s (%s)", err_classes[i].e_class, err[j].name,err[j].message); else result = talloc_asprintf( talloc_tos(), "%s - %s", err_classes[i].e_class, err[j].name); goto done; } } result = talloc_asprintf(talloc_tos(), "%s - %d", err_classes[i].e_class, num); goto done; } result = talloc_asprintf(talloc_tos(), "Error: Unknown error (%d,%d)", e_class, num); done: SMB_ASSERT(result != NULL); return result; }
/** * @brief Decodes a ncacn_packet * * @param mem_ctx The memory context on which to allocate the packet * elements * @param blob The blob of data to decode * @param r An empty ncacn_packet, must not be NULL * @param bigendian Whether the packet is bignedian encoded * * @return a NTSTATUS error code */ NTSTATUS dcerpc_pull_ncacn_packet(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct ncacn_packet *r, bool bigendian) { enum ndr_err_code ndr_err; struct ndr_pull *ndr; ndr = ndr_pull_init_blob(blob, mem_ctx); if (!ndr) { return NT_STATUS_NO_MEMORY; } if (bigendian) { ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } if (CVAL(blob->data, DCERPC_PFC_OFFSET) & DCERPC_PFC_FLAG_OBJECT_UUID) { ndr->flags |= LIBNDR_FLAG_OBJECT_PRESENT; } ndr_err = ndr_pull_ncacn_packet(ndr, NDR_SCALARS|NDR_BUFFERS, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(ndr); return ndr_map_error2ntstatus(ndr_err); } talloc_free(ndr); if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(ncacn_packet, r); } if (r->frag_length != blob->length) { return NT_STATUS_RPC_PROTOCOL_ERROR; } return NT_STATUS_OK; }
NTSTATUS read_smb_length_return_keepalive(int fd, char *inbuf, unsigned int timeout, size_t *len) { int msg_type; NTSTATUS status; status = read_fd_with_timeout(fd, inbuf, 4, 4, timeout, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } *len = smb_len(inbuf); msg_type = CVAL(inbuf,0); if (msg_type == NBSSkeepalive) { DEBUG(5,("Got keepalive packet\n")); } DEBUG(10,("got smb length of %lu\n",(unsigned long)(*len))); return NT_STATUS_OK; }
/**************************************************************************** end a message ****************************************************************************/ BOOL cli_message_end(struct cli_state *cli, int grp) { return False; #if 0 memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,1,0,True); CVAL(cli->outbuf,smb_com) = SMBsendend; SSVAL(cli->outbuf,smb_tid,cli->cnum); SSVAL(cli->outbuf,smb_vwv0,grp); cli_setup_packet(cli); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (cli_error(cli, NULL, NULL, NULL)) return False; return True; #endif }
/**************************************************************************** raw write interface (async recv) ****************************************************************************/ NTSTATUS smb_raw_write_recv(struct smbcli_request *req, union smb_write *parms) { if (!smbcli_request_receive(req) || !NT_STATUS_IS_OK(req->status)) { goto failed; } switch (parms->generic.level) { case RAW_WRITE_WRITEUNLOCK: SMBCLI_CHECK_WCT(req, 1); parms->writeunlock.out.nwritten = SVAL(req->in.vwv, VWV(0)); break; case RAW_WRITE_WRITE: SMBCLI_CHECK_WCT(req, 1); parms->write.out.nwritten = SVAL(req->in.vwv, VWV(0)); break; case RAW_WRITE_WRITECLOSE: SMBCLI_CHECK_WCT(req, 1); parms->writeclose.out.nwritten = SVAL(req->in.vwv, VWV(0)); break; case RAW_WRITE_WRITEX: SMBCLI_CHECK_WCT(req, 6); parms->writex.out.nwritten = SVAL(req->in.vwv, VWV(2)); parms->writex.out.nwritten += (CVAL(req->in.vwv, VWV(4)) << 16); parms->writex.out.remaining = SVAL(req->in.vwv, VWV(3)); break; case RAW_WRITE_SPLWRITE: break; case RAW_WRITE_SMB2: req->status = NT_STATUS_INTERNAL_ERROR; break; } failed: return smbcli_request_destroy(req); }
/**************************************************************************** process an smb from the client - split out from the process() code so it can be used by the oplock break code. ****************************************************************************/ void process_smb(char *inbuf, char *outbuf, int ProcSockID, int threadid) { // extern int Client; #ifdef WITH_SSL #endif /* WITH_SSL */ int msg_type = CVAL(inbuf,0); int32 len = smb_len(inbuf); int nread = len + 4; #ifdef WITH_PROFILE profile_p->smb_count++; #endif #ifdef WITH_VTP if(trans_num == 1 && VT_Check(inbuf)) { VT_Process(); return; } #endif if(msg_type == 0x85) return; /* Keepalive packet. */ nread = construct_reply(inbuf,outbuf,nread,max_send[threadid], ProcSockID ,threadid ); if(nread > 0) { if (nread != smb_len(outbuf) + 4) { } else send_smb(ProcSockID,outbuf); } }
static void get_domain_master_name_node_status_success(struct subnet_record *subrec, struct userdata_struct *userdata, struct res_rec *answers, struct in_addr from_ip) { struct work_record *work; fstring server_name; server_name[0] = 0; if( DEBUGLVL( 3 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) ); } /* * Go through the list of names found at answers->rdata and look for * the first WORKGROUP<0x1b> name. */ if(answers->rdata != NULL) { char *p = answers->rdata; int numnames = CVAL(p, 0); p += 1; while (numnames--) { char qname[17]; uint16 nb_flags; int name_type; StrnCpy(qname,p,15); name_type = CVAL(p,15); nb_flags = get_nb_flags(&p[16]); trim_string(qname,NULL," "); p += 18; if(!(nb_flags & NB_GROUP) && (name_type == 0x00) && server_name[0] == 0) { /* this is almost certainly the server netbios name */ fstrcpy(server_name, qname); continue; } if(!(nb_flags & NB_GROUP) && (name_type == 0x1b)) { if( DEBUGLVL( 5 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) ); dbgtext( "is a domain master browser for workgroup " ); dbgtext( "%s. Adding this name.\n", qname ); } /* * If we don't already know about this workgroup, add it * to the workgroup list on the unicast_subnet. */ if((work = find_workgroup_on_subnet( subrec, qname)) == NULL) { struct nmb_name nmbname; /* * Add it - with an hour in the cache. */ if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60))) return; /* remember who the master is */ fstrcpy(work->local_master_browser_name, server_name); make_nmb_name(&nmbname, server_name, 0x20); work->dmb_name = nmbname; work->dmb_addr = from_ip; } break; } } } else if( DEBUGLVL( 0 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " ); dbgtext( "%s.\n", inet_ntoa(from_ip) ); } }
static void domain_master_node_status_success(struct subnet_record *subrec, struct userdata_struct *userdata, struct res_rec *answers, struct in_addr from_ip) { struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data); if( work == NULL ) { if( DEBUGLVL( 0 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Unable to find workgroup " ); dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name ); } return; } if( DEBUGLVL( 3 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Success in node status for workgroup " ); dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) ); } /* Go through the list of names found at answers->rdata and look for the first SERVER<0x20> name. */ if(answers->rdata != NULL) { char *p = answers->rdata; int numnames = CVAL(p, 0); p += 1; while (numnames--) { char qname[17]; uint16 nb_flags; int name_type; StrnCpy(qname,p,15); name_type = CVAL(p,15); nb_flags = get_nb_flags(&p[16]); trim_string(qname,NULL," "); p += 18; if(!(nb_flags & NB_GROUP) && (name_type == 0x20)) { struct nmb_name nmbname; make_nmb_name(&nmbname, qname, name_type); /* Copy the dmb name and IP address into the workgroup struct. */ work->dmb_name = nmbname; putip((char *)&work->dmb_addr, &from_ip); /* Do the local master browser announcement to the domain master browser name and IP. */ announce_local_master_browser_to_domain_master_browser( work ); /* Now synchronise lists with the domain master browser. */ sync_with_dmb(work); break; } } } else if( DEBUGLVL( 0 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " ); dbgtext( "%s.\n", inet_ntoa(from_ip) ); } }
NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req) { NTSTATUS status; const uint8_t *inbody; uint8_t in_info_type; uint8_t in_file_info_class; uint32_t in_output_buffer_length; uint16_t in_input_buffer_offset; uint32_t in_input_buffer_length; DATA_BLOB in_input_buffer; uint32_t in_additional_information; uint32_t in_flags; uint64_t in_file_id_persistent; uint64_t in_file_id_volatile; struct files_struct *in_fsp; struct tevent_req *subreq; status = smbd_smb2_request_verify_sizes(req, 0x29); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } inbody = SMBD_SMB2_IN_BODY_PTR(req); in_info_type = CVAL(inbody, 0x02); in_file_info_class = CVAL(inbody, 0x03); in_output_buffer_length = IVAL(inbody, 0x04); in_input_buffer_offset = SVAL(inbody, 0x08); /* 0x0A 2 bytes reserved */ in_input_buffer_length = IVAL(inbody, 0x0C); in_additional_information = IVAL(inbody, 0x10); in_flags = IVAL(inbody, 0x14); in_file_id_persistent = BVAL(inbody, 0x18); in_file_id_volatile = BVAL(inbody, 0x20); if (in_input_buffer_offset == 0 && in_input_buffer_length == 0) { /* This is ok */ } else if (in_input_buffer_offset != (SMB2_HDR_BODY + SMBD_SMB2_IN_BODY_LEN(req))) { return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } if (in_input_buffer_length > SMBD_SMB2_IN_DYN_LEN(req)) { return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } in_input_buffer.data = SMBD_SMB2_IN_DYN_PTR(req); in_input_buffer.length = in_input_buffer_length; if (in_input_buffer.length > req->sconn->smb2.max_trans) { DEBUG(2,("smbd_smb2_request_process_getinfo: " "client ignored max trans: %s: 0x%08X: 0x%08X\n", __location__, (unsigned)in_input_buffer.length, (unsigned)req->sconn->smb2.max_trans)); return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } if (in_output_buffer_length > req->sconn->smb2.max_trans) { DEBUG(2,("smbd_smb2_request_process_getinfo: " "client ignored max trans: %s: 0x%08X: 0x%08X\n", __location__, in_output_buffer_length, req->sconn->smb2.max_trans)); return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER); } status = smbd_smb2_request_verify_creditcharge(req, MAX(in_input_buffer.length,in_output_buffer_length)); if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } in_fsp = file_fsp_smb2(req, in_file_id_persistent, in_file_id_volatile); if (in_fsp == NULL) { return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); } subreq = smbd_smb2_getinfo_send(req, req->sconn->ev_ctx, req, in_fsp, in_info_type, in_file_info_class, in_output_buffer_length, in_input_buffer, in_additional_information, in_flags); if (subreq == NULL) { return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); } tevent_req_set_callback(subreq, smbd_smb2_request_getinfo_done, req); return smbd_smb2_request_pending_queue(req, subreq, 500); }
static NTSTATUS smb1cli_pull_trans(uint8_t *inhdr, uint8_t wct, uint16_t *vwv, uint32_t vwv_ofs, uint32_t num_bytes, uint8_t *bytes, uint32_t bytes_ofs, uint8_t smb_cmd, bool expect_first_reply, uint8_t *pnum_setup, uint16_t **psetup, uint32_t *ptotal_param, uint32_t *pnum_param, uint32_t *pparam_disp, uint8_t **pparam, uint32_t *ptotal_data, uint32_t *pnum_data, uint32_t *pdata_disp, uint8_t **pdata) { uint32_t param_ofs, data_ofs; uint8_t expected_num_setup; uint32_t max_bytes = UINT32_MAX - bytes_ofs; uint32_t bytes_end; if (num_bytes > max_bytes) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } bytes_end = bytes_ofs + num_bytes; if (expect_first_reply) { if ((wct != 0) || (num_bytes != 0)) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } return NT_STATUS_OK; } switch (smb_cmd) { case SMBtrans: case SMBtrans2: if (wct < 10) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } expected_num_setup = wct - 10; *ptotal_param = SVAL(vwv + 0, 0); *ptotal_data = SVAL(vwv + 1, 0); *pnum_param = SVAL(vwv + 3, 0); param_ofs = SVAL(vwv + 4, 0); *pparam_disp = SVAL(vwv + 5, 0); *pnum_data = SVAL(vwv + 6, 0); data_ofs = SVAL(vwv + 7, 0); *pdata_disp = SVAL(vwv + 8, 0); *pnum_setup = CVAL(vwv + 9, 0); if (expected_num_setup < (*pnum_setup)) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } *psetup = vwv + 10; break; case SMBnttrans: if (wct < 18) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } expected_num_setup = wct - 18; *ptotal_param = IVAL(vwv, 3); *ptotal_data = IVAL(vwv, 7); *pnum_param = IVAL(vwv, 11); param_ofs = IVAL(vwv, 15); *pparam_disp = IVAL(vwv, 19); *pnum_data = IVAL(vwv, 23); data_ofs = IVAL(vwv, 27); *pdata_disp = IVAL(vwv, 31); *pnum_setup = CVAL(vwv, 35); if (expected_num_setup < (*pnum_setup)) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } *psetup = vwv + 18; break; default: return NT_STATUS_INTERNAL_ERROR; } /* * Check for buffer overflows. data_ofs needs to be checked against * the incoming buffer length, data_disp against the total * length. Likewise for param_ofs/param_disp. */ if (smb_buffer_oob(bytes_end, param_ofs, *pnum_param) || smb_buffer_oob(*ptotal_param, *pparam_disp, *pnum_param) || smb_buffer_oob(bytes_end, data_ofs, *pnum_data) || smb_buffer_oob(*ptotal_data, *pdata_disp, *pnum_data)) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } *pparam = (uint8_t *)inhdr + param_ofs; *pdata = (uint8_t *)inhdr + data_ofs; return NT_STATUS_OK; }
static bool process_lockingX(struct blocking_lock_record *blr) { unsigned char locktype = CVAL(blr->req->vwv+3, 0); files_struct *fsp = blr->fsp; uint16 num_ulocks = SVAL(blr->req->vwv+6, 0); uint16 num_locks = SVAL(blr->req->vwv+7, 0); uint64_t count = (uint64_t)0, offset = (uint64_t)0; uint32 lock_pid; bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); uint8_t *data; NTSTATUS status = NT_STATUS_OK; data = (uint8_t *)blr->req->buf + ((large_file_format ? 20 : 10)*num_ulocks); /* * Data now points at the beginning of the list * of smb_lkrng structs. */ for(; blr->lock_num < num_locks; blr->lock_num++) { struct byte_range_lock *br_lck = NULL; bool err; lock_pid = get_lock_pid( data, blr->lock_num, large_file_format); count = get_lock_count( data, blr->lock_num, large_file_format); offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); /* * We know err cannot be set as if it was the lock * request would never have been queued. JRA. */ errno = 0; br_lck = do_lock(smbd_messaging_context(), fsp, lock_pid, count, offset, ((locktype & LOCKING_ANDX_SHARED_LOCK) ? READ_LOCK : WRITE_LOCK), WINDOWS_LOCK, True, &status, &blr->blocking_pid, blr); TALLOC_FREE(br_lck); if (NT_STATUS_IS_ERR(status)) { break; } } if(blr->lock_num == num_locks) { /* * Success - we got all the locks. */ DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n", fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) ); reply_lockingX_success(blr); return True; } if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { /* * We have other than a "can't get lock" * error. Free any locks we had and return an error. * Return True so we get dequeued. */ blocking_lock_reply_error(blr, status); return True; } /* * Still can't get all the locks - keep waiting. */ DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \ Waiting....\n", blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum)); return False; }
/* this is the underlying (unformatted) rsync debugging function. Call * it with FINFO, FERROR_*, FWARNING, FLOG, or FCLIENT. Note: recursion * can happen with certain fatal conditions. */ void rwrite(enum logcode code, const char *buf, int len, int is_utf8) { int trailing_CR_or_NL; FILE *f = msgs2stderr ? stderr : stdout; #ifdef ICONV_OPTION iconv_t ic = is_utf8 && ic_recv != (iconv_t)-1 ? ic_recv : ic_chck; #else #ifdef ICONV_CONST iconv_t ic = ic_chck; #endif #endif if (len < 0) exit_cleanup(RERR_MESSAGEIO); if (msgs2stderr) { if (!am_daemon) { if (code == FLOG) return; goto output_msg; } if (code == FCLIENT) return; code = FLOG; } else if (send_msgs_to_gen) { assert(!is_utf8); /* Pass the message to our sibling in native charset. */ send_msg((enum msgcode)code, buf, len, 0); return; } if (code == FERROR_SOCKET) /* This gets simplified for a non-sibling. */ code = FERROR; else if (code == FERROR_UTF8) { is_utf8 = 1; code = FERROR; } if (code == FCLIENT) code = FINFO; else if (am_daemon || logfile_name) { static int in_block; char msg[2048]; int priority = code == FINFO || code == FLOG ? LOG_INFO : LOG_WARNING; if (in_block) return; in_block = 1; if (!log_initialised) log_init(0); strlcpy(msg, buf, MIN((int)sizeof msg, len + 1)); logit(priority, msg); in_block = 0; if (code == FLOG || (am_daemon && !am_server)) return; } else if (code == FLOG) return; if (quiet && code == FINFO) return; if (am_server) { enum msgcode msg = (enum msgcode)code; if (protocol_version < 30) { if (msg == MSG_ERROR) msg = MSG_ERROR_XFER; else if (msg == MSG_WARNING) msg = MSG_INFO; } /* Pass the message to the non-server side. */ if (send_msg(msg, buf, len, !is_utf8)) return; if (am_daemon) { /* TODO: can we send the error to the user somehow? */ return; } f = stderr; } output_msg: switch (code) { case FERROR_XFER: got_xfer_error = 1; /* FALL THROUGH */ case FERROR: case FERROR_UTF8: case FERROR_SOCKET: case FWARNING: f = stderr; break; case FLOG: case FINFO: case FCLIENT: break; default: fprintf(stderr, "Unknown logcode in rwrite(): %d [%s]\n", (int)code, who_am_i()); exit_cleanup(RERR_MESSAGEIO); } if (output_needs_newline) { fputc('\n', f); output_needs_newline = 0; } trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r') ? buf[--len] : 0; if (len && buf[0] == '\r') { fputc('\r', f); buf++; len--; } #ifdef ICONV_CONST if (ic != (iconv_t)-1) { xbuf outbuf, inbuf; char convbuf[1024]; int ierrno; INIT_CONST_XBUF(outbuf, convbuf); INIT_XBUF(inbuf, (char*)buf, len, (size_t)-1); while (inbuf.len) { iconvbufs(ic, &inbuf, &outbuf, inbuf.pos ? 0 : ICB_INIT); ierrno = errno; if (outbuf.len) { filtered_fwrite(f, convbuf, outbuf.len, 0); outbuf.len = 0; } if (!ierrno || ierrno == E2BIG) continue; fprintf(f, "\\#%03o", CVAL(inbuf.buf, inbuf.pos++)); inbuf.len--; } } else #endif filtered_fwrite(f, buf, len, !allow_8bit_chars); if (trailing_CR_or_NL) { fputc(trailing_CR_or_NL, f); fflush(f); } }