2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 2003
5 Copyright (C) James Myers 2003 <myersjj@samba.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 this file implements functions for manipulating the 'struct smbcli_request' structure in libsmb
28 /* we over allocate the data buffer to prevent too many realloc calls */
29 #define REQ_OVER_ALLOCATION 256
31 /* assume that a character will not consume more than 3 bytes per char */
32 #define MAX_BYTES_PER_CHAR 3
34 /* destroy a request structure and return final status */
35 NTSTATUS
smbcli_request_destroy(struct smbcli_request
*req
)
39 /* this is the error code we give the application for when a
40 _send() call fails completely */
41 if (!req
) return NT_STATUS_UNSUCCESSFUL
;
44 /* remove it from the list of pending requests (a null op if
45 its not in the list) */
46 DLIST_REMOVE(req
->transport
->pending_recv
, req
);
49 /* ahh, its so nice to destroy a complex structure in such a
58 low-level function to setup a request buffer for a non-SMB packet
59 at the transport level
61 struct smbcli_request
*smbcli_request_setup_nonsmb(struct smbcli_transport
*transport
, uint_t size
)
63 struct smbcli_request
*req
;
65 req
= talloc_named(NULL
, sizeof(struct smbcli_request
), "smcli_request");
71 /* setup the request context */
72 req
->state
= SMBCLI_REQUEST_INIT
;
73 req
->transport
= transport
;
78 /* over allocate by a small amount */
79 req
->out
.allocated
= req
->out
.size
+ REQ_OVER_ALLOCATION
;
81 req
->out
.buffer
= talloc(req
, req
->out
.allocated
);
82 if (!req
->out
.buffer
) {
86 SIVAL(req
->out
.buffer
, 0, 0);
93 setup a SMB packet at transport level
95 struct smbcli_request
*smbcli_request_setup_transport(struct smbcli_transport
*transport
,
96 uint8_t command
, uint_t wct
, uint_t buflen
)
98 struct smbcli_request
*req
;
100 req
= smbcli_request_setup_nonsmb(transport
, NBT_HDR_SIZE
+ MIN_SMB_SIZE
+ wct
*2 + buflen
);
102 if (!req
) return NULL
;
104 req
->out
.hdr
= req
->out
.buffer
+ NBT_HDR_SIZE
;
105 req
->out
.vwv
= req
->out
.hdr
+ HDR_VWV
;
107 req
->out
.data
= req
->out
.vwv
+ VWV(wct
) + 2;
108 req
->out
.data_size
= buflen
;
109 req
->out
.ptr
= req
->out
.data
;
111 SCVAL(req
->out
.hdr
, HDR_WCT
, wct
);
112 SSVAL(req
->out
.vwv
, VWV(wct
), buflen
);
114 memcpy(req
->out
.hdr
, "\377SMB", 4);
115 SCVAL(req
->out
.hdr
,HDR_COM
,command
);
117 SCVAL(req
->out
.hdr
,HDR_FLG
, FLAG_CASELESS_PATHNAMES
);
118 SSVAL(req
->out
.hdr
,HDR_FLG2
, 0);
121 req
->mid
= smbcli_transport_next_mid(transport
);
123 /* copy the pid, uid and mid to the request */
124 SSVAL(req
->out
.hdr
, HDR_PID
, 0);
125 SSVAL(req
->out
.hdr
, HDR_UID
, 0);
126 SSVAL(req
->out
.hdr
, HDR_MID
, req
->mid
);
127 SSVAL(req
->out
.hdr
, HDR_TID
,0);
128 SSVAL(req
->out
.hdr
, HDR_PIDHIGH
,0);
129 SIVAL(req
->out
.hdr
, HDR_RCLS
, 0);
130 memset(req
->out
.hdr
+HDR_SS_FIELD
, 0, 10);
136 setup a reply in req->out with the given word count and initial data
137 buffer size. the caller will then fill in the command words and
138 data before calling smbcli_request_send() to send the reply on its
139 way. This interface is used before a session is setup.
141 struct smbcli_request
*smbcli_request_setup_session(struct smbcli_session
*session
,
142 uint8_t command
, uint_t wct
, uint_t buflen
)
144 struct smbcli_request
*req
;
146 uint32_t capabilities
;
148 req
= smbcli_request_setup_transport(session
->transport
, command
, wct
, buflen
);
150 if (!req
) return NULL
;
152 req
->session
= session
;
154 flags2
= FLAGS2_LONG_PATH_COMPONENTS
;
155 capabilities
= session
->transport
->negotiate
.capabilities
;
157 if (capabilities
& CAP_UNICODE
) {
158 flags2
|= FLAGS2_UNICODE_STRINGS
;
160 if (capabilities
& CAP_STATUS32
) {
161 flags2
|= FLAGS2_32_BIT_ERROR_CODES
;
163 if (capabilities
& CAP_EXTENDED_SECURITY
) {
164 flags2
|= FLAGS2_EXTENDED_SECURITY
;
166 if (session
->transport
->negotiate
.sign_info
.doing_signing
) {
167 flags2
|= FLAGS2_SMB_SECURITY_SIGNATURES
;
170 SSVAL(req
->out
.hdr
, HDR_FLG2
, flags2
);
171 SSVAL(req
->out
.hdr
, HDR_PID
, session
->pid
& 0xFFFF);
172 SSVAL(req
->out
.hdr
, HDR_PIDHIGH
, session
->pid
>> 16);
173 SSVAL(req
->out
.hdr
, HDR_UID
, session
->vuid
);
179 setup a request for tree based commands
181 struct smbcli_request
*smbcli_request_setup(struct smbcli_tree
*tree
,
183 uint_t wct
, uint_t buflen
)
185 struct smbcli_request
*req
;
187 req
= smbcli_request_setup_session(tree
->session
, command
, wct
, buflen
);
190 SSVAL(req
->out
.hdr
,HDR_TID
,tree
->tid
);
196 grow the allocation of the data buffer portion of a reply
197 packet. Note that as this can reallocate the packet buffer this
198 invalidates any local pointers into the packet.
200 To cope with this req->out.ptr is supplied. This will be updated to
201 point at the same offset into the packet as before this call
203 static void smbcli_req_grow_allocation(struct smbcli_request
*req
, uint_t new_size
)
208 delta
= new_size
- req
->out
.data_size
;
209 if (delta
+ req
->out
.size
<= req
->out
.allocated
) {
210 /* it fits in the preallocation */
214 /* we need to realloc */
215 req
->out
.allocated
= req
->out
.size
+ delta
+ REQ_OVER_ALLOCATION
;
216 buf2
= talloc_realloc(req
->out
.buffer
, req
->out
.allocated
);
218 smb_panic("out of memory in req_grow_allocation");
221 if (buf2
== req
->out
.buffer
) {
222 /* the malloc library gave us the same pointer */
226 /* update the pointers into the packet */
227 req
->out
.data
= buf2
+ PTR_DIFF(req
->out
.data
, req
->out
.buffer
);
228 req
->out
.ptr
= buf2
+ PTR_DIFF(req
->out
.ptr
, req
->out
.buffer
);
229 req
->out
.vwv
= buf2
+ PTR_DIFF(req
->out
.vwv
, req
->out
.buffer
);
230 req
->out
.hdr
= buf2
+ PTR_DIFF(req
->out
.hdr
, req
->out
.buffer
);
232 req
->out
.buffer
= buf2
;
237 grow the data buffer portion of a reply packet. Note that as this
238 can reallocate the packet buffer this invalidates any local pointers
241 To cope with this req->out.ptr is supplied. This will be updated to
242 point at the same offset into the packet as before this call
244 void smbcli_req_grow_data(struct smbcli_request
*req
, uint_t new_size
)
248 smbcli_req_grow_allocation(req
, new_size
);
250 delta
= new_size
- req
->out
.data_size
;
252 req
->out
.size
+= delta
;
253 req
->out
.data_size
+= delta
;
255 /* set the BCC to the new data size */
256 SSVAL(req
->out
.vwv
, VWV(req
->out
.wct
), new_size
);
263 BOOL
smbcli_request_send(struct smbcli_request
*req
)
265 if (IVAL(req
->out
.buffer
, 0) == 0) {
266 _smb_setlen(req
->out
.buffer
, req
->out
.size
- NBT_HDR_SIZE
);
269 smbcli_request_calculate_sign_mac(req
);
271 smbcli_transport_send(req
);
278 receive a response to a packet
280 BOOL
smbcli_request_receive(struct smbcli_request
*req
)
282 /* req can be NULL when a send has failed. This eliminates lots of NULL
283 checks in each module */
284 if (!req
) return False
;
286 /* keep receiving packets until this one is replied to */
287 while (req
->state
<= SMBCLI_REQUEST_RECV
) {
288 if (event_loop_once(req
->transport
->event
.ctx
) != 0) {
293 return req
->state
== SMBCLI_REQUEST_DONE
;
298 receive another reply to a request - this is used for requests that
299 have multi-part replies (such as SMBtrans2)
301 BOOL
smbcli_request_receive_more(struct smbcli_request
*req
)
303 req
->state
= SMBCLI_REQUEST_RECV
;
304 DLIST_ADD(req
->transport
->pending_recv
, req
);
306 return smbcli_request_receive(req
);
311 handle oplock break requests from the server - return True if the request was
314 BOOL
handle_oplock_break(struct smbcli_transport
*transport
, uint_t len
, const char *hdr
, const char *vwv
)
316 /* we must be very fussy about what we consider an oplock break to avoid
317 matching readbraw replies */
318 if (len
!= MIN_SMB_SIZE
+ VWV(8) + NBT_HDR_SIZE
||
319 (CVAL(hdr
, HDR_FLG
) & FLAG_REPLY
) ||
320 CVAL(hdr
,HDR_COM
) != SMBlockingX
||
321 SVAL(hdr
, HDR_MID
) != 0xFFFF ||
322 SVAL(vwv
,VWV(6)) != 0 ||
323 SVAL(vwv
,VWV(7)) != 0) {
327 if (transport
->oplock
.handler
) {
328 uint16_t tid
= SVAL(hdr
, HDR_TID
);
329 uint16_t fnum
= SVAL(vwv
,VWV(2));
330 uint8_t level
= CVAL(vwv
,VWV(3)+1);
331 transport
->oplock
.handler(transport
, tid
, fnum
, level
, transport
->oplock
.private);
338 wait for a reply to be received for a packet that just returns an error
339 code and nothing more
341 NTSTATUS
smbcli_request_simple_recv(struct smbcli_request
*req
)
343 smbcli_request_receive(req
);
344 return smbcli_request_destroy(req
);
348 /* Return true if the last packet was in error */
349 BOOL
smbcli_request_is_error(struct smbcli_request
*req
)
351 return NT_STATUS_IS_ERR(req
->status
);
355 append a string into the data portion of the request packet
357 return the number of bytes added to the packet
359 size_t smbcli_req_append_string(struct smbcli_request
*req
, const char *str
, uint_t flags
)
363 /* determine string type to use */
364 if (!(flags
& (STR_ASCII
|STR_UNICODE
))) {
365 flags
|= (req
->transport
->negotiate
.capabilities
& CAP_UNICODE
) ? STR_UNICODE
: STR_ASCII
;
368 len
= (strlen(str
)+2) * MAX_BYTES_PER_CHAR
;
370 smbcli_req_grow_allocation(req
, len
+ req
->out
.data_size
);
372 len
= push_string(req
->out
.data
+ req
->out
.data_size
, str
, len
, flags
);
374 smbcli_req_grow_data(req
, len
+ req
->out
.data_size
);
381 this is like smbcli_req_append_string but it also return the
382 non-terminated string byte length, which can be less than the number
383 of bytes consumed in the packet for 2 reasons:
385 1) the string in the packet may be null terminated
386 2) the string in the packet may need a 1 byte UCS2 alignment
388 this is used in places where the non-terminated string byte length is
389 placed in the packet as a separate field
391 size_t smbcli_req_append_string_len(struct smbcli_request
*req
, const char *str
, uint_t flags
, int *len
)
396 /* determine string type to use */
397 if (!(flags
& (STR_ASCII
|STR_UNICODE
))) {
398 flags
|= (req
->transport
->negotiate
.capabilities
& CAP_UNICODE
) ? STR_UNICODE
: STR_ASCII
;
401 /* see if an alignment byte will be used */
402 if ((flags
& STR_UNICODE
) && !(flags
& STR_NOALIGN
)) {
403 diff
= ucs2_align(NULL
, req
->out
.data
+ req
->out
.data_size
, flags
);
406 /* do the hard work */
407 ret
= smbcli_req_append_string(req
, str
, flags
);
409 /* see if we need to subtract the termination */
410 if (flags
& STR_TERMINATE
) {
411 diff
+= (flags
& STR_UNICODE
) ? 2 : 1;
425 push a string into the data portion of the request packet, growing it if necessary
426 this gets quite tricky - please be very careful to cover all cases when modifying this
428 if dest is NULL, then put the string at the end of the data portion of the packet
430 if dest_len is -1 then no limit applies
432 size_t smbcli_req_append_ascii4(struct smbcli_request
*req
, const char *str
, uint_t flags
)
435 smbcli_req_append_bytes(req
, (const uint8_t *)"\4", 1);
436 size
= smbcli_req_append_string(req
, str
, flags
);
442 push a blob into the data portion of the request packet, growing it if necessary
443 this gets quite tricky - please be very careful to cover all cases when modifying this
445 if dest is NULL, then put the blob at the end of the data portion of the packet
447 size_t smbcli_req_append_blob(struct smbcli_request
*req
, const DATA_BLOB
*blob
)
449 smbcli_req_grow_allocation(req
, req
->out
.data_size
+ blob
->length
);
450 memcpy(req
->out
.data
+ req
->out
.data_size
, blob
->data
, blob
->length
);
451 smbcli_req_grow_data(req
, req
->out
.data_size
+ blob
->length
);
456 append raw bytes into the data portion of the request packet
457 return the number of bytes added
459 size_t smbcli_req_append_bytes(struct smbcli_request
*req
, const uint8_t *bytes
, size_t byte_len
)
461 smbcli_req_grow_allocation(req
, byte_len
+ req
->out
.data_size
);
462 memcpy(req
->out
.data
+ req
->out
.data_size
, bytes
, byte_len
);
463 smbcli_req_grow_data(req
, byte_len
+ req
->out
.data_size
);
468 append variable block (type 5 buffer) into the data portion of the request packet
469 return the number of bytes added
471 size_t smbcli_req_append_var_block(struct smbcli_request
*req
, const uint8_t *bytes
, uint16_t byte_len
)
473 smbcli_req_grow_allocation(req
, byte_len
+ 3 + req
->out
.data_size
);
474 SCVAL(req
->out
.data
+ req
->out
.data_size
, 0, 5);
475 SSVAL(req
->out
.data
+ req
->out
.data_size
, 1, byte_len
); /* add field length */
477 memcpy(req
->out
.data
+ req
->out
.data_size
+ 3, bytes
, byte_len
);
479 smbcli_req_grow_data(req
, byte_len
+ 3 + req
->out
.data_size
);
485 pull a UCS2 string from a request packet, returning a talloced unix string
487 the string length is limited by the 3 things:
488 - the data size in the request (end of packet)
489 - the passed 'byte_len' if it is not -1
490 - the end of string (null termination)
492 Note that 'byte_len' is the number of bytes in the packet
494 on failure zero is returned and *dest is set to NULL, otherwise the number
495 of bytes consumed in the packet is returned
497 static size_t smbcli_req_pull_ucs2(struct smbcli_request
*req
, TALLOC_CTX
*mem_ctx
,
498 char **dest
, const char *src
, int byte_len
, uint_t flags
)
500 int src_len
, src_len2
, alignment
=0;
503 if (!(flags
& STR_NOALIGN
) && ucs2_align(req
->in
.buffer
, src
, flags
)) {
506 if (byte_len
!= -1) {
511 src_len
= req
->in
.data_size
- PTR_DIFF(src
, req
->in
.data
);
516 if (byte_len
!= -1 && src_len
> byte_len
) {
520 src_len2
= strnlen_w((const smb_ucs2_t
*)src
, src_len
/2) * 2;
521 if (src_len2
< src_len
- 2) {
522 /* include the termination if we didn't reach the end of the packet */
526 /* ucs2 strings must be at least 2 bytes long */
532 ret
= convert_string_talloc(mem_ctx
, CH_UTF16
, CH_UNIX
, src
, src_len2
, (void **)dest
);
538 return src_len2
+ alignment
;
542 pull a ascii string from a request packet, returning a talloced string
544 the string length is limited by the 3 things:
545 - the data size in the request (end of packet)
546 - the passed 'byte_len' if it is not -1
547 - the end of string (null termination)
549 Note that 'byte_len' is the number of bytes in the packet
551 on failure zero is returned and *dest is set to NULL, otherwise the number
552 of bytes consumed in the packet is returned
554 size_t smbcli_req_pull_ascii(struct smbcli_request
*req
, TALLOC_CTX
*mem_ctx
,
555 char **dest
, const char *src
, int byte_len
, uint_t flags
)
557 int src_len
, src_len2
;
560 src_len
= req
->in
.data_size
- PTR_DIFF(src
, req
->in
.data
);
565 if (byte_len
!= -1 && src_len
> byte_len
) {
568 src_len2
= strnlen(src
, src_len
);
569 if (src_len2
< src_len
- 1) {
570 /* include the termination if we didn't reach the end of the packet */
574 ret
= convert_string_talloc(mem_ctx
, CH_DOS
, CH_UNIX
, src
, src_len2
, (void **)dest
);
585 pull a string from a request packet, returning a talloced string
587 the string length is limited by the 3 things:
588 - the data size in the request (end of packet)
589 - the passed 'byte_len' if it is not -1
590 - the end of string (null termination)
592 Note that 'byte_len' is the number of bytes in the packet
594 on failure zero is returned and *dest is set to NULL, otherwise the number
595 of bytes consumed in the packet is returned
597 size_t smbcli_req_pull_string(struct smbcli_request
*req
, TALLOC_CTX
*mem_ctx
,
598 char **dest
, const char *src
, int byte_len
, uint_t flags
)
600 if (!(flags
& STR_ASCII
) &&
601 (((flags
& STR_UNICODE
) || (req
->flags2
& FLAGS2_UNICODE_STRINGS
)))) {
602 return smbcli_req_pull_ucs2(req
, mem_ctx
, dest
, src
, byte_len
, flags
);
605 return smbcli_req_pull_ascii(req
, mem_ctx
, dest
, src
, byte_len
, flags
);
610 pull a DATA_BLOB from a reply packet, returning a talloced blob
611 make sure we don't go past end of packet
613 if byte_len is -1 then limit the blob only by packet size
615 DATA_BLOB
smbcli_req_pull_blob(struct smbcli_request
*req
, TALLOC_CTX
*mem_ctx
, const char *src
, int byte_len
)
619 src_len
= req
->in
.data_size
- PTR_DIFF(src
, req
->in
.data
);
622 return data_blob(NULL
, 0);
625 if (byte_len
!= -1 && src_len
> byte_len
) {
629 return data_blob_talloc(mem_ctx
, src
, src_len
);
632 /* check that a lump of data in a request is within the bounds of the data section of
634 static BOOL
smbcli_req_data_oob(struct smbcli_request
*req
, const char *ptr
, uint32_t count
)
636 /* be careful with wraparound! */
637 if (ptr
< req
->in
.data
||
638 ptr
>= req
->in
.data
+ req
->in
.data_size
||
639 count
> req
->in
.data_size
||
640 ptr
+ count
> req
->in
.data
+ req
->in
.data_size
) {
647 pull a lump of data from a request packet
649 return False if any part is outside the data portion of the packet
651 BOOL
smbcli_raw_pull_data(struct smbcli_request
*req
, const char *src
, int len
, char *dest
)
653 if (len
== 0) return True
;
655 if (smbcli_req_data_oob(req
, src
, len
)) {
659 memcpy(dest
, src
, len
);
665 put a NTTIME into a packet
667 void smbcli_push_nttime(void *base
, uint16_t offset
, NTTIME t
)
669 SBVAL(base
, offset
, t
);
673 pull a NTTIME from a packet
675 NTTIME
smbcli_pull_nttime(void *base
, uint16_t offset
)
677 NTTIME ret
= BVAL(base
, offset
);
682 pull a UCS2 string from a blob, returning a talloced unix string
684 the string length is limited by the 3 things:
685 - the data size in the blob
686 - the passed 'byte_len' if it is not -1
687 - the end of string (null termination)
689 Note that 'byte_len' is the number of bytes in the packet
691 on failure zero is returned and *dest is set to NULL, otherwise the number
692 of bytes consumed in the blob is returned
694 static size_t smbcli_blob_pull_ucs2(TALLOC_CTX
* mem_ctx
,
695 DATA_BLOB
*blob
, const char **dest
,
696 const char *src
, int byte_len
, uint_t flags
)
698 int src_len
, src_len2
, alignment
=0;
702 if (src
< (const char *)blob
->data
||
703 src
>= (const char *)(blob
->data
+ blob
->length
)) {
708 src_len
= blob
->length
- PTR_DIFF(src
, blob
->data
);
710 if (byte_len
!= -1 && src_len
> byte_len
) {
714 if (!(flags
& STR_NOALIGN
) && ucs2_align(blob
->data
, src
, flags
)) {
725 src_len2
= strnlen_w((const smb_ucs2_t
*)src
, src_len
/2) * 2;
727 if (src_len2
< src_len
- 2) {
728 /* include the termination if we didn't reach the end of the packet */
732 ret
= convert_string_talloc(mem_ctx
, CH_UTF16
, CH_UNIX
, src
, src_len2
, (void **)&dest2
);
739 return src_len2
+ alignment
;
743 pull a ascii string from a blob, returning a talloced string
745 the string length is limited by the 3 things:
746 - the data size in the blob
747 - the passed 'byte_len' if it is not -1
748 - the end of string (null termination)
750 Note that 'byte_len' is the number of bytes in the blob
752 on failure zero is returned and *dest is set to NULL, otherwise the number
753 of bytes consumed in the blob is returned
755 static size_t smbcli_blob_pull_ascii(TALLOC_CTX
*mem_ctx
,
756 DATA_BLOB
*blob
, const char **dest
,
757 const char *src
, int byte_len
, uint_t flags
)
759 int src_len
, src_len2
;
763 src_len
= blob
->length
- PTR_DIFF(src
, blob
->data
);
768 if (byte_len
!= -1 && src_len
> byte_len
) {
771 src_len2
= strnlen(src
, src_len
);
773 if (src_len2
< src_len
- 1) {
774 /* include the termination if we didn't reach the end of the packet */
778 ret
= convert_string_talloc(mem_ctx
, CH_DOS
, CH_UNIX
, src
, src_len2
, (void **)&dest2
);
790 pull a string from a blob, returning a talloced WIRE_STRING
792 the string length is limited by the 3 things:
793 - the data size in the blob
794 - length field on the wire
795 - the end of string (null termination)
797 if STR_LEN8BIT is set in the flags then assume the length field is
798 8 bits, instead of 32
800 on failure zero is returned and dest->s is set to NULL, otherwise the number
801 of bytes consumed in the blob is returned
803 size_t smbcli_blob_pull_string(struct smbcli_session
*session
,
807 uint16_t len_offset
, uint16_t str_offset
,
813 if (flags
& STR_LEN8BIT
) {
814 if (len_offset
> blob
->length
-1) {
817 dest
->private_length
= CVAL(blob
->data
, len_offset
);
819 if (len_offset
> blob
->length
-4) {
822 dest
->private_length
= IVAL(blob
->data
, len_offset
);
826 if (!(flags
& STR_ASCII
) &&
827 ((flags
& STR_UNICODE
) ||
828 (session
->transport
->negotiate
.capabilities
& CAP_UNICODE
))) {
830 if ((str_offset
&1) && !(flags
& STR_NOALIGN
)) {
833 if (flags
& STR_LEN_NOTERM
) {
836 return align
+ extra
+ smbcli_blob_pull_ucs2(mem_ctx
, blob
, &dest
->s
,
837 blob
->data
+str_offset
+align
,
838 dest
->private_length
, flags
);
841 if (flags
& STR_LEN_NOTERM
) {
845 return extra
+ smbcli_blob_pull_ascii(mem_ctx
, blob
, &dest
->s
,
846 blob
->data
+str_offset
, dest
->private_length
, flags
);
850 pull a string from a blob, returning a talloced char *
852 Currently only used by the UNIX search info level.
854 the string length is limited by 2 things:
855 - the data size in the blob
856 - the end of string (null termination)
858 on failure zero is returned and dest->s is set to NULL, otherwise the number
859 of bytes consumed in the blob is returned
861 size_t smbcli_blob_pull_unix_string(struct smbcli_session
*session
,
871 if (!(flags
& STR_ASCII
) &&
872 ((flags
& STR_UNICODE
) ||
873 (session
->transport
->negotiate
.capabilities
& CAP_UNICODE
))) {
875 if ((str_offset
&1) && !(flags
& STR_NOALIGN
)) {
878 if (flags
& STR_LEN_NOTERM
) {
881 return align
+ extra
+ smbcli_blob_pull_ucs2(mem_ctx
, blob
, dest
,
882 blob
->data
+str_offset
+align
,
886 if (flags
& STR_LEN_NOTERM
) {
890 return extra
+ smbcli_blob_pull_ascii(mem_ctx
, blob
, dest
,
891 blob
->data
+str_offset
, -1, flags
);
896 append a string into a blob
898 size_t smbcli_blob_append_string(struct smbcli_session
*session
,
899 TALLOC_CTX
*mem_ctx
, DATA_BLOB
*blob
,
900 const char *str
, uint_t flags
)
907 /* determine string type to use */
908 if (!(flags
& (STR_ASCII
|STR_UNICODE
))) {
909 flags
|= (session
->transport
->negotiate
.capabilities
& CAP_UNICODE
) ? STR_UNICODE
: STR_ASCII
;
912 max_len
= (strlen(str
)+2) * MAX_BYTES_PER_CHAR
;
914 blob
->data
= talloc_realloc(blob
->data
, blob
->length
+ max_len
);
919 len
= push_string(blob
->data
+ blob
->length
, str
, max_len
, flags
);