rawrequest.c

来自「samba最新软件」· C语言 代码 · 共 1,036 行 · 第 1/2 页

C
1,036
字号
	smbcli_req_grow_allocation(req, req->out.data_size + blob->length);	memcpy(req->out.data + req->out.data_size, blob->data, blob->length);	smbcli_req_grow_data(req, req->out.data_size + blob->length);	return blob->length;}/*  append raw bytes into the data portion of the request packet  return the number of bytes added*/size_t smbcli_req_append_bytes(struct smbcli_request *req, const uint8_t *bytes, size_t byte_len){	smbcli_req_grow_allocation(req, byte_len + req->out.data_size);	memcpy(req->out.data + req->out.data_size, bytes, byte_len);	smbcli_req_grow_data(req, byte_len + req->out.data_size);	return byte_len;}/*  append variable block (type 5 buffer) into the data portion of the request packet  return the number of bytes added*/size_t smbcli_req_append_var_block(struct smbcli_request *req, const uint8_t *bytes, uint16_t byte_len){	smbcli_req_grow_allocation(req, byte_len + 3 + req->out.data_size);	SCVAL(req->out.data + req->out.data_size, 0, 5);	SSVAL(req->out.data + req->out.data_size, 1, byte_len);		/* add field length */	if (byte_len > 0) {		memcpy(req->out.data + req->out.data_size + 3, bytes, byte_len);	}	smbcli_req_grow_data(req, byte_len + 3 + req->out.data_size);	return byte_len + 3;}/*  pull a UCS2 string from a request packet, returning a talloced unix string  the string length is limited by the 3 things:   - the data size in the request (end of packet)   - the passed 'byte_len' if it is not -1   - the end of string (null termination)  Note that 'byte_len' is the number of bytes in the packet  on failure zero is returned and *dest is set to NULL, otherwise the number  of bytes consumed in the packet is returned*/static size_t smbcli_req_pull_ucs2(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,				char **dest, const uint8_t *src, int byte_len, uint_t flags){	int src_len, src_len2, alignment=0;	ssize_t ret;	if (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {		src++;		alignment=1;		if (byte_len != -1) {			byte_len--;		}	}	src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);	if (src_len < 0) {		*dest = NULL;		return 0;	}	if (byte_len != -1 && src_len > byte_len) {		src_len = byte_len;	}	src_len2 = utf16_len_n(src, src_len);	/* ucs2 strings must be at least 2 bytes long */	if (src_len2 < 2) {		*dest = NULL;		return 0;	}	ret = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)dest);	if (ret == -1) {		*dest = NULL;		return 0;	}	return src_len2 + alignment;}/*  pull a ascii string from a request packet, returning a talloced string  the string length is limited by the 3 things:   - the data size in the request (end of packet)   - the passed 'byte_len' if it is not -1   - the end of string (null termination)  Note that 'byte_len' is the number of bytes in the packet  on failure zero is returned and *dest is set to NULL, otherwise the number  of bytes consumed in the packet is returned*/size_t smbcli_req_pull_ascii(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx,			     char **dest, const uint8_t *src, int byte_len, uint_t flags){	int src_len, src_len2;	ssize_t ret;	src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);	if (src_len < 0) {		*dest = NULL;		return 0;	}	if (byte_len != -1 && src_len > byte_len) {		src_len = byte_len;	}	src_len2 = strnlen((const char *)src, src_len);	if (src_len2 < src_len - 1) {		/* include the termination if we didn't reach the end of the packet */		src_len2++;	}	ret = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)dest);	if (ret == -1) {		*dest = NULL;		return 0;	}	return ret;}/**  pull a string from a request packet, returning a talloced string  the string length is limited by the 3 things:   - the data size in the request (end of packet)   - the passed 'byte_len' if it is not -1   - the end of string (null termination)  Note that 'byte_len' is the number of bytes in the packet  on failure zero is returned and *dest is set to NULL, otherwise the number  of bytes consumed in the packet is returned*/size_t smbcli_req_pull_string(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, 			   char **dest, const uint8_t *src, int byte_len, uint_t flags){	if (!(flags & STR_ASCII) && 	    (((flags & STR_UNICODE) || (bufinfo->flags & BUFINFO_FLAG_UNICODE)))) {		return smbcli_req_pull_ucs2(bufinfo, mem_ctx, dest, src, byte_len, flags);	}	return smbcli_req_pull_ascii(bufinfo, mem_ctx, dest, src, byte_len, flags);}/**  pull a DATA_BLOB from a reply packet, returning a talloced blob  make sure we don't go past end of packet  if byte_len is -1 then limit the blob only by packet size*/DATA_BLOB smbcli_req_pull_blob(struct request_bufinfo *bufinfo, TALLOC_CTX *mem_ctx, const uint8_t *src, int byte_len){	int src_len;	src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);	if (src_len < 0) {		return data_blob(NULL, 0);	}	if (byte_len != -1 && src_len > byte_len) {		src_len = byte_len;	}	return data_blob_talloc(mem_ctx, src, src_len);}/* check that a lump of data in a request is within the bounds of the data section of   the packet */static bool smbcli_req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count){	/* be careful with wraparound! */	if ((uintptr_t)ptr < (uintptr_t)bufinfo->data ||	    (uintptr_t)ptr >= (uintptr_t)bufinfo->data + bufinfo->data_size ||	    count > bufinfo->data_size ||	    (uintptr_t)ptr + count > (uintptr_t)bufinfo->data + bufinfo->data_size) {		return true;	}	return false;}/*  pull a lump of data from a request packet  return false if any part is outside the data portion of the packet*/bool smbcli_raw_pull_data(struct request_bufinfo *bufinfo, const uint8_t *src, int len, uint8_t *dest){	if (len == 0) return true;	if (smbcli_req_data_oob(bufinfo, src, len)) {		return false;	}	memcpy(dest, src, len);	return true;}/*  put a NTTIME into a packet*/void smbcli_push_nttime(void *base, uint16_t offset, NTTIME t){	SBVAL(base, offset, t);}/*  pull a NTTIME from a packet*/NTTIME smbcli_pull_nttime(void *base, uint16_t offset){	NTTIME ret = BVAL(base, offset);	return ret;}/**  pull a UCS2 string from a blob, returning a talloced unix string  the string length is limited by the 3 things:   - the data size in the blob   - the passed 'byte_len' if it is not -1   - the end of string (null termination)  Note that 'byte_len' is the number of bytes in the packet  on failure zero is returned and *dest is set to NULL, otherwise the number  of bytes consumed in the blob is returned*/size_t smbcli_blob_pull_ucs2(TALLOC_CTX* mem_ctx,			     const DATA_BLOB *blob, const char **dest, 			     const uint8_t *src, int byte_len, uint_t flags){	int src_len, src_len2, alignment=0;	ssize_t ret;	char *dest2;	if (src < blob->data ||	    src >= (blob->data + blob->length)) {		*dest = NULL;		return 0;	}	src_len = blob->length - PTR_DIFF(src, blob->data);	if (byte_len != -1 && src_len > byte_len) {		src_len = byte_len;	}	if (!(flags & STR_NOALIGN) && ucs2_align(blob->data, src, flags)) {		src++;		alignment=1;		src_len--;	}	if (src_len < 2) {		*dest = NULL;		return 0;	}	src_len2 = utf16_len_n(src, src_len);	ret = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_UTF16, CH_UNIX, src, src_len2, (void **)&dest2);	if (ret == -1) {		*dest = NULL;		return 0;	}	*dest = dest2;	return src_len2 + alignment;}/**  pull a ascii string from a blob, returning a talloced string  the string length is limited by the 3 things:   - the data size in the blob   - the passed 'byte_len' if it is not -1   - the end of string (null termination)  Note that 'byte_len' is the number of bytes in the blob  on failure zero is returned and *dest is set to NULL, otherwise the number  of bytes consumed in the blob is returned*/static size_t smbcli_blob_pull_ascii(TALLOC_CTX *mem_ctx,				     const DATA_BLOB *blob, const char **dest, 				     const uint8_t *src, int byte_len, uint_t flags){	int src_len, src_len2;	ssize_t ret;	char *dest2;	src_len = blob->length - PTR_DIFF(src, blob->data);	if (src_len < 0) {		*dest = NULL;		return 0;	}	if (byte_len != -1 && src_len > byte_len) {		src_len = byte_len;	}	src_len2 = strnlen((const char *)src, src_len);	if (src_len2 < src_len - 1) {		/* include the termination if we didn't reach the end of the packet */		src_len2++;	}	ret = convert_string_talloc(mem_ctx, lp_iconv_convenience(global_loadparm), CH_DOS, CH_UNIX, src, src_len2, (void **)&dest2);	if (ret == -1) {		*dest = NULL;		return 0;	}	*dest = dest2;	return ret;}/**  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, 			       uint_t 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);}/**  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, 			    uint_t 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);}/*  append a string into a blob*/size_t smbcli_blob_append_string(struct smbcli_session *session,			      TALLOC_CTX *mem_ctx, DATA_BLOB *blob, 			      const char *str, uint_t flags){	size_t max_len;	int len;	if (!str) return 0;	/* determine string type to use */	if (!(flags & (STR_ASCII|STR_UNICODE))) {		flags |= (session->transport->negotiate.capabilities & CAP_UNICODE) ? STR_UNICODE : STR_ASCII;	}	max_len = (strlen(str)+2) * MAX_BYTES_PER_CHAR;			blob->data = talloc_realloc(mem_ctx, blob->data, uint8_t, blob->length + max_len);	if (!blob->data) {		return 0;	}	len = push_string(lp_iconv_convenience(global_loadparm), blob->data + blob->length, str, max_len, flags);	blob->length += len;	return len;}/*  pull a GUID structure from the wire. The buffer must be at least 16  bytes long */enum ndr_err_code smbcli_pull_guid(void *base, uint16_t offset, 				   struct GUID *guid){	DATA_BLOB blob;	TALLOC_CTX *tmp_ctx = talloc_new(NULL);	enum ndr_err_code ndr_err;	ZERO_STRUCTP(guid);	blob.data       = offset + (uint8_t *)base;	blob.length     = 16;	ndr_err = ndr_pull_struct_blob(&blob, tmp_ctx, NULL, guid, 				       (ndr_pull_flags_fn_t)ndr_pull_GUID);	talloc_free(tmp_ctx);	return ndr_err;}/*  push a guid onto the wire. The buffer must hold 16 bytes */enum ndr_err_code smbcli_push_guid(void *base, uint16_t offset, 				   const struct GUID *guid){	TALLOC_CTX *tmp_ctx = talloc_new(NULL);	enum ndr_err_code ndr_err;	DATA_BLOB blob;	ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, NULL,				       guid, (ndr_push_flags_fn_t)ndr_push_GUID);	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err) || blob.length != 16) {		talloc_free(tmp_ctx);		return ndr_err;	}	memcpy(offset + (uint8_t *)base, blob.data, blob.length);	talloc_free(tmp_ctx);	return ndr_err;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?