Exemplo n.º 1
0
/**
  pull a string from a blob, returning a talloced char *

  Currently only used by the UNIX search info level.

  the string length is limited by 2 things:
   - the data size in the blob
   - the end of string (null termination)

  on failure zero is returned and dest->s is set to NULL, otherwise the number
  of bytes consumed in the blob is returned
*/
size_t smbcli_blob_pull_unix_string(struct smbcli_session *session,
			    TALLOC_CTX *mem_ctx,
			    DATA_BLOB *blob, 
			    const char **dest, 
			    uint16_t str_offset, 
			    unsigned int flags)
{
	int extra = 0;
	*dest = NULL;
	
	if (!(flags & STR_ASCII) && 
	    ((flags & STR_UNICODE) || 
	     (session->transport->negotiate.capabilities & CAP_UNICODE))) {
		int align = 0;
		if ((str_offset&1) && !(flags & STR_NOALIGN)) {
			align = 1;
		}
		if (flags & STR_LEN_NOTERM) {
			extra = 2;
		}
		return align + extra + smbcli_blob_pull_ucs2(mem_ctx, blob, dest, 
							  blob->data+str_offset+align, 
							  -1, flags);
	}

	if (flags & STR_LEN_NOTERM) {
		extra = 1;
	}

	return extra + smbcli_blob_pull_ascii(mem_ctx, blob, dest,
					   blob->data+str_offset, -1, flags);
}
Exemplo n.º 2
0
/**
  pull a string from a blob, returning a talloced struct smb_wire_string

  the string length is limited by the 3 things:
   - the data size in the blob
   - length field on the wire
   - the end of string (null termination)

   if STR_LEN8BIT is set in the flags then assume the length field is
   8 bits, instead of 32

  on failure zero is returned and dest->s is set to NULL, otherwise the number
  of bytes consumed in the blob is returned
*/
size_t smbcli_blob_pull_string(struct smbcli_session *session,
			       TALLOC_CTX *mem_ctx,
			       const DATA_BLOB *blob, 
			       struct smb_wire_string *dest, 
			       uint16_t len_offset, uint16_t str_offset, 
			       unsigned int flags)
{
	int extra;
	dest->s = NULL;

	if (!(flags & STR_ASCII)) {
		/* this is here to cope with SMB2 calls using the SMB
		   parsers. SMB2 will pass smbcli_session==NULL, which forces
		   unicode on (as used by SMB2) */
		if (session == NULL) {
			flags |= STR_UNICODE;
		} else if (session->transport->negotiate.capabilities & CAP_UNICODE) {
			flags |= STR_UNICODE;
		}
	}

	if (flags & STR_LEN8BIT) {
		if (len_offset > blob->length-1) {
			return 0;
		}
		dest->private_length = CVAL(blob->data, len_offset);
	} else {
		if (len_offset > blob->length-4) {
			return 0;
		}
		dest->private_length = IVAL(blob->data, len_offset);
	}
	extra = 0;
	dest->s = NULL;
	if (!(flags & STR_ASCII) && (flags & STR_UNICODE)) {
		int align = 0;
		if ((str_offset&1) && !(flags & STR_NOALIGN)) {
			align = 1;
		}
		if (flags & STR_LEN_NOTERM) {
			extra = 2;
		}
		return align + extra + smbcli_blob_pull_ucs2(mem_ctx, blob, &dest->s, 
							  blob->data+str_offset+align, 
							  dest->private_length, flags);
	}

	if (flags & STR_LEN_NOTERM) {
		extra = 1;
	}

	return extra + smbcli_blob_pull_ascii(mem_ctx, blob, &dest->s, 
					   blob->data+str_offset, dest->private_length, flags);
}
Exemplo n.º 3
0
/* 
   get shadow volume data
*/
_PUBLIC_ NTSTATUS smb_raw_shadow_data(struct smbcli_tree *tree, 
				      TALLOC_CTX *mem_ctx, struct smb_shadow_copy *info)
{
	union smb_ioctl nt;
	NTSTATUS status;
	DATA_BLOB blob;
	uint32_t dlength;
	int i;
	uint32_t ofs;

	nt.ntioctl.level        = RAW_IOCTL_NTIOCTL;
	nt.ntioctl.in.function  = FSCTL_GET_SHADOW_COPY_DATA;
	nt.ntioctl.in.file.fnum = info->in.file.fnum;
	nt.ntioctl.in.fsctl     = True;
	nt.ntioctl.in.filter    = 0;
	nt.ntioctl.in.max_data  = info->in.max_data;
	nt.ntioctl.in.blob      = data_blob(NULL, 0);

	status = smb_raw_ioctl(tree, mem_ctx, &nt);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}
	
	blob = nt.ntioctl.out.blob;

	if (blob.length < 12) {
		return NT_STATUS_INVALID_NETWORK_RESPONSE;
	}
	
	info->out.num_volumes = IVAL(blob.data, 0);
	info->out.num_names   = IVAL(blob.data, 4);
	dlength               = IVAL(blob.data, 8);
	if (dlength > blob.length - 12) {
		return NT_STATUS_INVALID_NETWORK_RESPONSE;
	}

	info->out.names = talloc_array(mem_ctx, const char *, info->out.num_names);
	NT_STATUS_HAVE_NO_MEMORY(info->out.names);

	ofs = 12;
	for (i=0;i<info->out.num_names;i++) {
		size_t len;
		len = smbcli_blob_pull_ucs2(info->out.names, 
				      &blob, &info->out.names[i],
				      blob.data+ofs, -1, STR_TERMINATE);
		if (len == 0) {
			return NT_STATUS_INVALID_NETWORK_RESPONSE;
		}
		ofs += len;
	}
	
	return status;
}