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;

	}
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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;
}
Example #5
0
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));
}
Example #6
0
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);
	}
}
Example #7
0
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);
}
Example #8
0
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;
	}
}
Example #9
0
File: value.c Project: rgburke/wed
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;
}
Example #10
0
File: util2.c Project: JevonQ/rsync
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;
}
Example #11
0
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;
}
Example #12
0
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;
}
Example #13
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);
}
Example #14
0
/* 
   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;
}
Example #15
0
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;
}
Example #16
0
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);
}
Example #17
0
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);

}
Example #18
0
/****************************************************************************
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
}
Example #19
0
/****************************************************************************
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;
}
Example #20
0
/**
* @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;
}
Example #21
0
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;
}
Example #22
0
/****************************************************************************
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
}      
Example #23
0
/****************************************************************************
 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);
  }
}
Example #25
0
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) );
    }
}
Example #26
0
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) );
    }
}
Example #27
0
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);
}
Example #28
0
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;
}
Example #29
0
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;
}
Example #30
0
/* 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);
	}
}