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 + -
显示快捷键?