⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 request.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
  push a string into the data portion of the request packet, growing it if necessary  this gets quite tricky - please be very careful to cover all cases when modifying this  if dest is NULL, then put the string at the end of the data portion of the packet  if dest_len is -1 then no limit applies*/size_t req_push_str(struct smbsrv_request *req, uint8_t *dest, const char *str, int dest_len, size_t flags){	size_t len;	uint_t grow_size;	uint8_t *buf0;	const int max_bytes_per_char = 3;	if (!(flags & (STR_ASCII|STR_UNICODE))) {		flags |= (req->flags2 & FLAGS2_UNICODE_STRINGS) ? STR_UNICODE : STR_ASCII;	}	if (dest == NULL) {		dest = req->out.data + req->out.data_size;	}	if (dest_len != -1) {		len = dest_len;	} else {		len = (strlen(str)+2) * max_bytes_per_char;	}	grow_size = len + PTR_DIFF(dest, req->out.data);	buf0 = req->out.buffer;	req_grow_allocation(req, grow_size);	if (buf0 != req->out.buffer) {		dest = req->out.buffer + PTR_DIFF(dest, buf0);	}	len = push_string(lp_iconv_convenience(req->smb_conn->lp_ctx), dest, str, len, flags);	grow_size = len + PTR_DIFF(dest, req->out.data);	if (grow_size > req->out.data_size) {		req_grow_data(req, grow_size);	}	return len;}/*  append raw bytes into the data portion of the request packet  return the number of bytes added*/size_t req_append_bytes(struct smbsrv_request *req, 			const uint8_t *bytes, size_t byte_len){	req_grow_allocation(req, byte_len + req->out.data_size);	memcpy(req->out.data + req->out.data_size, bytes, byte_len);	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 req_append_var_block(struct smbsrv_request *req, 		const uint8_t *bytes, uint16_t byte_len){	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);	}	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 req_pull_ucs2(struct request_bufinfo *bufinfo, 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 (!(flags & STR_NOALIGN) && ucs2_align(bufinfo->align_base, src, flags)) {		src++;		alignment=1;		if (byte_len != -1) {			byte_len--;		}	}	if (flags & STR_NO_RANGE_CHECK) {		src_len = byte_len;	} else {		src_len = bufinfo->data_size - PTR_DIFF(src, bufinfo->data);		if (byte_len != -1 && src_len > byte_len) {			src_len = byte_len;		}	}	if (src_len < 0) {		*dest = NULL;		return 0;	}		src_len2 = utf16_len_n(src, src_len);	if (src_len2 == 0) {		*dest = talloc_strdup(bufinfo->mem_ctx, "");		return src_len2 + alignment;	}	ret = convert_string_talloc(bufinfo->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 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*/static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags){	int src_len, src_len2;	ssize_t ret;	char *dest2;	if (flags & STR_NO_RANGE_CHECK) {		src_len = byte_len;	} else {		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(bufinfo->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 src_len2;}/**  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 req_pull_string(struct request_bufinfo *bufinfo, const 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 req_pull_ucs2(bufinfo, dest, src, byte_len, flags);	}	return req_pull_ascii(bufinfo, dest, src, byte_len, flags);}/**  pull a ASCII4 string buffer from a request packet, returning a talloced string    an ASCII4 buffer is a null terminated string that has a prefix  of the character 0x4. It tends to be used in older parts of the protocol.  on failure *dest is set to the zero length string. This seems to  match win2000 behaviour*/size_t req_pull_ascii4(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, uint_t flags){	ssize_t ret;	if (PTR_DIFF(src, bufinfo->data) + 1 > bufinfo->data_size) {		/* win2000 treats this as the empty string! */		(*dest) = talloc_strdup(bufinfo->mem_ctx, "");		return 0;	}	/* this consumes the 0x4 byte. We don't check whether the byte	   is actually 0x4 or not. This matches win2000 server	   behaviour */	src++;	ret = req_pull_string(bufinfo, dest, src, -1, flags);	if (ret == -1) {		(*dest) = talloc_strdup(bufinfo->mem_ctx, "");		return 1;	}		return ret + 1;}/**  pull a DATA_BLOB from a request packet, returning a talloced blob  return false if any part is outside the data portion of the packet*/bool req_pull_blob(struct request_bufinfo *bufinfo, const uint8_t *src, int len, DATA_BLOB *blob){	if (len != 0 && req_data_oob(bufinfo, src, len)) {		return false;	}	(*blob) = data_blob_talloc(bufinfo->mem_ctx, src, len);	return true;}/* check that a lump of data in a request is within the bounds of the data section of   the packet */bool req_data_oob(struct request_bufinfo *bufinfo, const uint8_t *ptr, uint32_t count){	if (count == 0) {		return false;	}		/* 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 an open file handle from a packet, taking account of the chained_fnum*/static uint16_t req_fnum(struct smbsrv_request *req, const uint8_t *base, uint_t offset){	if (req->chained_fnum != -1) {		return req->chained_fnum;	}	return SVAL(base, offset);}struct ntvfs_handle *smbsrv_pull_fnum(struct smbsrv_request *req, const uint8_t *base, uint_t offset){	struct smbsrv_handle *handle;	uint16_t fnum = req_fnum(req, base, offset);	handle = smbsrv_smb_handle_find(req->tcon, fnum, req->request_time);	if (!handle) {		return NULL;	}	/*	 * For SMB tcons and sessions can be mixed!	 * But we need to make sure that file handles	 * are only accessed by the opening session!	 *	 * So check if the handle is valid for the given session!	 */	if (handle->session != req->session) {		return NULL;	}	return handle->ntvfs;}void smbsrv_push_fnum(uint8_t *base, uint_t offset, struct ntvfs_handle *ntvfs){	struct smbsrv_handle *handle = talloc_get_type(ntvfs->frontend_data.private_data,				       struct smbsrv_handle);	SSVAL(base, offset, handle->hid);}NTSTATUS smbsrv_handle_create_new(void *private_data, struct ntvfs_request *ntvfs, struct ntvfs_handle **_h){	struct smbsrv_request *req = talloc_get_type(ntvfs->frontend_data.private_data,				     struct smbsrv_request);	struct smbsrv_handle *handle;	struct ntvfs_handle *h;	handle = smbsrv_handle_new(req->session, req->tcon, req, req->request_time);	if (!handle) return NT_STATUS_INSUFFICIENT_RESOURCES;	h = talloc_zero(handle, struct ntvfs_handle);	if (!h) goto nomem;	/* 	 * note: we don't set handle->ntvfs yet,	 *       this will be done by smbsrv_handle_make_valid()	 *       this makes sure the handle is invalid for clients	 *       until the ntvfs subsystem has made it valid	 */	h->ctx		= ntvfs->ctx;	h->session_info	= ntvfs->session_info;	h->smbpid	= ntvfs->smbpid;	h->frontend_data.private_data = handle;	*_h = h;	return NT_STATUS_OK;nomem:	talloc_free(handle);	return NT_STATUS_NO_MEMORY;}NTSTATUS smbsrv_handle_make_valid(void *private_data, struct ntvfs_handle *h){	struct smbsrv_tcon *tcon = talloc_get_type(private_data, struct smbsrv_tcon);	struct smbsrv_handle *handle = talloc_get_type(h->frontend_data.private_data,						       struct smbsrv_handle);	/* this tells the frontend that the handle is valid */	handle->ntvfs = h;	/* this moves the smbsrv_request to the smbsrv_tcon memory context */	talloc_steal(tcon, handle);	return NT_STATUS_OK;}void smbsrv_handle_destroy(void *private_data, struct ntvfs_handle *h){	struct smbsrv_handle *handle = talloc_get_type(h->frontend_data.private_data,						       struct smbsrv_handle);	talloc_free(handle);}struct ntvfs_handle *smbsrv_handle_search_by_wire_key(void *private_data, struct ntvfs_request *ntvfs, const DATA_BLOB *key){	struct smbsrv_request *req = talloc_get_type(ntvfs->frontend_data.private_data,				     struct smbsrv_request);	if (key->length != 2) return NULL;	return smbsrv_pull_fnum(req, key->data, 0);}DATA_BLOB smbsrv_handle_get_wire_key(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx){	uint8_t key[2];	smbsrv_push_fnum(key, 0, handle);	return data_blob_talloc(mem_ctx, key, sizeof(key));}

⌨️ 快捷键说明

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