2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-1997,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
6 * Copyright (C) Paul Ashton 1997.
7 * Copyright (C) Gerald (Jerry) Carter 2005
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define DBGC_CLASS DBGC_RPC_PARSE
29 /****************************************************************************
30 A temporary TALLOC context for things like unistrs, that is valid for
31 the life of a complete RPC call.
32 ****************************************************************************/
34 static TALLOC_CTX *current_rpc_talloc = NULL;
36 static TALLOC_CTX *get_current_rpc_talloc(void)
38 return current_rpc_talloc;
41 void set_current_rpc_talloc( TALLOC_CTX *ctx)
43 current_rpc_talloc = ctx;
46 static TALLOC_CTX *main_loop_talloc = NULL;
48 /*******************************************************************
49 free up temporary memory - called from the main loop
50 ********************************************************************/
52 void main_loop_talloc_free(void)
54 if (!main_loop_talloc)
56 talloc_destroy(main_loop_talloc);
57 main_loop_talloc = NULL;
60 /*******************************************************************
61 Get a talloc context that is freed in the main loop...
62 ********************************************************************/
64 TALLOC_CTX *main_loop_talloc_get(void)
66 if (!main_loop_talloc) {
67 main_loop_talloc = talloc_init("main loop talloc (mainly parse_misc)");
68 if (!main_loop_talloc)
69 smb_panic("main_loop_talloc: malloc fail\n");
72 return main_loop_talloc;
75 /*******************************************************************
76 Try and get a talloc context. Get the rpc one if possible, else
77 get the main loop one. The main loop one is more dangerous as it
78 goes away between packets, the rpc one will stay around for as long
79 as a current RPC lasts.
80 ********************************************************************/
82 TALLOC_CTX *get_talloc_ctx(void)
84 TALLOC_CTX *tc = get_current_rpc_talloc();
88 return main_loop_talloc_get();
91 /*******************************************************************
92 Reads or writes a UTIME type.
93 ********************************************************************/
95 static BOOL smb_io_utime(const char *desc, UTIME *t, prs_struct *ps, int depth)
100 prs_debug(ps, depth, desc, "smb_io_utime");
106 if(!prs_uint32 ("time", ps, depth, &t->time))
112 /*******************************************************************
113 Reads or writes an NTTIME structure.
114 ********************************************************************/
116 BOOL smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
121 prs_debug(ps, depth, desc, "smb_io_time");
127 if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */
129 if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */
135 /*******************************************************************
136 Gets an enumeration handle from an ENUM_HND structure.
137 ********************************************************************/
139 uint32 get_enum_hnd(ENUM_HND *enh)
141 return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
144 /*******************************************************************
145 Inits an ENUM_HND structure.
146 ********************************************************************/
148 void init_enum_hnd(ENUM_HND *enh, uint32 hnd)
150 DEBUG(5,("smb_io_enum_hnd\n"));
152 enh->ptr_hnd = (hnd != 0) ? 1 : 0;
156 /*******************************************************************
157 Reads or writes an ENUM_HND structure.
158 ********************************************************************/
160 BOOL smb_io_enum_hnd(const char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
165 prs_debug(ps, depth, desc, "smb_io_enum_hnd");
171 if(!prs_uint32("ptr_hnd", ps, depth, &hnd->ptr_hnd)) /* pointer */
174 if (hnd->ptr_hnd != 0) {
175 if(!prs_uint32("handle ", ps, depth, &hnd->handle )) /* enum handle */
182 /*******************************************************************
183 Reads or writes a DOM_SID structure.
184 ********************************************************************/
186 BOOL smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
193 prs_debug(ps, depth, desc, "smb_io_dom_sid");
196 if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
199 if(!prs_uint8 ("num_auths ", ps, depth, &sid->num_auths))
202 for (i = 0; i < 6; i++)
205 slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
206 if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
210 /* oops! XXXX should really issue a warning here... */
211 if (sid->num_auths > MAXSUBAUTHS)
212 sid->num_auths = MAXSUBAUTHS;
214 if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
220 /*******************************************************************
221 Inits a DOM_SID structure.
223 BIG NOTE: this function only does SIDS where the identauth is not >= 2^32
224 identauth >= 2^32 can be detected because it will be specified in hex
225 ********************************************************************/
227 void init_dom_sid(DOM_SID *sid, const char *str_sid)
233 if (str_sid == NULL) {
234 DEBUG(4,("netlogon domain SID: none\n"));
235 sid->sid_rev_num = 0;
240 pstrcpy(domsid, str_sid);
242 DEBUG(4,("init_dom_sid %d SID: %s\n", __LINE__, domsid));
244 /* assume, but should check, that domsid starts "S-" */
245 p = strtok(domsid+2,"-");
246 sid->sid_rev_num = atoi(p);
248 /* identauth in decimal should be < 2^32 */
249 /* identauth in hex should be >= 2^32 */
250 identauth = atoi(strtok(0,"-"));
252 DEBUG(4,("netlogon rev %d\n", sid->sid_rev_num));
253 DEBUG(4,("netlogon %s ia %d\n", p, identauth));
257 sid->id_auth[2] = (identauth & 0xff000000) >> 24;
258 sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
259 sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
260 sid->id_auth[5] = (identauth & 0x000000ff);
264 while ((p = strtok(0, "-")) != NULL && sid->num_auths < MAXSUBAUTHS)
265 sid->sub_auths[sid->num_auths++] = atoi(p);
267 DEBUG(4,("init_dom_sid: %d SID: %s\n", __LINE__, domsid));
270 /*******************************************************************
271 Inits a DOM_SID2 structure.
272 ********************************************************************/
274 void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
277 sid2->num_auths = sid2->sid.num_auths;
280 /*******************************************************************
281 Reads or writes a DOM_SID2 structure.
282 ********************************************************************/
284 BOOL smb_io_dom_sid2_p(const char *desc, prs_struct *ps, int depth, DOM_SID2 **sid2)
288 /* caputure the pointer value to stream */
290 data_p = (uint32) *sid2;
292 if ( !prs_uint32("dom_sid2_p", ps, depth, &data_p ))
295 /* we're done if there is no data */
300 if (UNMARSHALLING(ps)) {
301 if ( !(*sid2 = PRS_ALLOC_MEM(ps, DOM_SID2, 1)) )
307 /*******************************************************************
308 Reads or writes a DOM_SID2 structure.
309 ********************************************************************/
311 BOOL smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
316 prs_debug(ps, depth, desc, "smb_io_dom_sid2");
322 if(!prs_uint32("num_auths", ps, depth, &sid->num_auths))
325 if(!smb_io_dom_sid("sid", &sid->sid, ps, depth))
331 /*******************************************************************
332 Reads or writes a struct uuid
333 ********************************************************************/
335 BOOL smb_io_uuid(const char *desc, struct uuid *uuid,
336 prs_struct *ps, int depth)
341 prs_debug(ps, depth, desc, "smb_io_uuid");
344 if(!prs_uint32 ("data ", ps, depth, &uuid->time_low))
346 if(!prs_uint16 ("data ", ps, depth, &uuid->time_mid))
348 if(!prs_uint16 ("data ", ps, depth, &uuid->time_hi_and_version))
351 if(!prs_uint8s (False, "data ", ps, depth, uuid->clock_seq, sizeof(uuid->clock_seq)))
353 if(!prs_uint8s (False, "data ", ps, depth, uuid->node, sizeof(uuid->node)))
359 /*******************************************************************
360 creates a STRHDR structure.
361 ********************************************************************/
363 void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
365 hdr->str_max_len = max_len;
366 hdr->str_str_len = len;
367 hdr->buffer = buffer;
370 /*******************************************************************
371 Reads or writes a STRHDR structure.
372 ********************************************************************/
374 BOOL smb_io_strhdr(const char *desc, STRHDR *hdr, prs_struct *ps, int depth)
379 prs_debug(ps, depth, desc, "smb_io_strhdr");
384 if(!prs_uint16("str_str_len", ps, depth, &hdr->str_str_len))
386 if(!prs_uint16("str_max_len", ps, depth, &hdr->str_max_len))
388 if(!prs_uint32("buffer ", ps, depth, &hdr->buffer))
394 /*******************************************************************
395 Inits a UNIHDR structure.
396 ********************************************************************/
398 void init_uni_hdr(UNIHDR *hdr, UNISTR2 *str2)
400 hdr->uni_str_len = 2 * (str2->uni_str_len);
401 hdr->uni_max_len = 2 * (str2->uni_max_len);
402 hdr->buffer = (str2->uni_str_len != 0) ? 1 : 0;
405 /*******************************************************************
406 Reads or writes a UNIHDR structure.
407 ********************************************************************/
409 BOOL smb_io_unihdr(const char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
414 prs_debug(ps, depth, desc, "smb_io_unihdr");
420 if(!prs_uint16("uni_str_len", ps, depth, &hdr->uni_str_len))
422 if(!prs_uint16("uni_max_len", ps, depth, &hdr->uni_max_len))
424 if(!prs_uint32("buffer ", ps, depth, &hdr->buffer))
430 /*******************************************************************
431 Inits a BUFHDR structure.
432 ********************************************************************/
434 void init_buf_hdr(BUFHDR *hdr, int max_len, int len)
436 hdr->buf_max_len = max_len;
440 /*******************************************************************
441 prs_uint16 wrapper. Call this and it sets up a pointer to where the
442 uint16 should be stored, or gets the size if reading.
443 ********************************************************************/
445 BOOL smb_io_hdrbuf_pre(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
447 (*offset) = prs_offset(ps);
452 if(!smb_io_hdrbuf(desc, hdr, ps, depth))
459 if(!prs_set_offset(ps, prs_offset(ps) + (sizeof(uint32) * 2)))
466 /*******************************************************************
467 smb_io_hdrbuf wrapper. Call this and it retrospectively stores the size.
468 Does nothing on reading, as that is already handled by ...._pre()
469 ********************************************************************/
471 BOOL smb_io_hdrbuf_post(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
472 uint32 ptr_hdrbuf, uint32 max_len, uint32 len)
475 /* writing: go back and do a retrospective job. i hate this */
477 uint32 old_offset = prs_offset(ps);
479 init_buf_hdr(hdr, max_len, len);
480 if(!prs_set_offset(ps, ptr_hdrbuf))
482 if(!smb_io_hdrbuf(desc, hdr, ps, depth))
485 if(!prs_set_offset(ps, old_offset))
492 /*******************************************************************
493 Reads or writes a BUFHDR structure.
494 ********************************************************************/
496 BOOL smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
501 prs_debug(ps, depth, desc, "smb_io_hdrbuf");
507 if(!prs_uint32("buf_max_len", ps, depth, &hdr->buf_max_len))
509 if(!prs_uint32("buf_len ", ps, depth, &hdr->buf_len))
515 /*******************************************************************
516 Inits a UNISTR structure.
517 ********************************************************************/
519 void init_unistr(UNISTR *str, const char *buf)
528 len = strlen(buf) + 1;
530 str->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, len);
531 if (str->buffer == NULL)
532 smb_panic("init_unistr: malloc fail\n");
534 rpcstr_push(str->buffer, buf, len*sizeof(uint16), STR_TERMINATE);
537 /*******************************************************************
538 reads or writes a UNISTR structure.
539 XXXX NOTE: UNISTR structures NEED to be null-terminated.
540 ********************************************************************/
542 BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
547 prs_debug(ps, depth, desc, "smb_io_unistr");
550 if(!prs_unistr("unistr", ps, depth, uni))
556 /*******************************************************************
557 Allocate the BUFFER3 memory.
558 ********************************************************************/
560 static size_t create_buffer3(BUFFER3 *str, size_t len)
562 str->buffer = TALLOC_ZERO(get_talloc_ctx(), len);
563 if (str->buffer == NULL)
564 smb_panic("create_buffer3: talloc fail\n");
568 /*******************************************************************
569 Inits a BUFFER3 structure from a uint32
570 ********************************************************************/
572 void init_buffer3_uint32(BUFFER3 *str, uint32 val)
576 /* set up string lengths. */
577 str->buf_max_len = str->buf_len = create_buffer3(str, sizeof(uint32));
578 SIVAL(str->buffer, 0, val);
581 /*******************************************************************
582 Inits a BUFFER3 structure.
583 ********************************************************************/
585 void init_buffer3_str(BUFFER3 *str, const char *buf, int len)
589 /* set up string lengths. */
590 str->buf_max_len = str->buf_len = create_buffer3(str, len*2);
591 rpcstr_push(str->buffer, buf, str->buf_max_len, STR_TERMINATE);
595 /*******************************************************************
596 Inits a BUFFER3 structure from a hex string.
597 ********************************************************************/
599 void init_buffer3_hex(BUFFER3 *str, const char *buf)
602 str->buf_max_len = str->buf_len = create_buffer3(str, strlen(buf));
603 str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, str->buf_len, buf);
606 /*******************************************************************
607 Inits a BUFFER3 structure.
608 ********************************************************************/
610 void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, size_t len)
614 /* max buffer size (allocated size) */
616 len = create_buffer3(str, len);
617 memcpy(str->buffer, buf, len);
619 str->buf_max_len = len;
620 str->buf_len = buf != NULL ? len : 0;
623 /*******************************************************************
624 Reads or writes a BUFFER3 structure.
625 the uni_max_len member tells you how large the buffer is.
626 the uni_str_len member tells you how much of the buffer is really used.
627 ********************************************************************/
629 BOOL smb_io_buffer3(const char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
634 prs_debug(ps, depth, desc, "smb_io_buffer3");
640 if(!prs_uint32("uni_max_len", ps, depth, &buf3->buf_max_len))
643 if (UNMARSHALLING(ps)) {
644 buf3->buffer = PRS_ALLOC_MEM(ps, unsigned char, buf3->buf_max_len);
645 if (buf3->buffer == NULL)
649 if(!prs_uint8s(True, "buffer ", ps, depth, buf3->buffer, buf3->buf_max_len))
652 if(!prs_uint32("buf_len ", ps, depth, &buf3->buf_len))
658 /*******************************************************************
659 reads or writes a BUFFER5 structure.
660 the buf_len member tells you how large the buffer is.
661 ********************************************************************/
662 BOOL smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
664 prs_debug(ps, depth, desc, "smb_io_buffer5");
667 if (buf5 == NULL) return False;
671 if(!prs_uint32("buf_len", ps, depth, &buf5->buf_len))
675 if(!prs_buffer5(True, "buffer" , ps, depth, buf5))
682 /*******************************************************************
683 Inits a REGVAL_BUFFER structure.
684 ********************************************************************/
686 void init_regval_buffer(REGVAL_BUFFER *str, const uint8 *buf, size_t len)
690 /* max buffer size (allocated size) */
691 str->buf_max_len = len;
693 str->buf_len = buf != NULL ? len : 0;
696 SMB_ASSERT(str->buf_max_len >= str->buf_len);
697 str->buffer = TALLOC_ZERO(get_talloc_ctx(), str->buf_max_len);
698 if (str->buffer == NULL)
699 smb_panic("init_regval_buffer: talloc fail\n");
700 memcpy(str->buffer, buf, str->buf_len);
704 /*******************************************************************
705 Reads or writes a REGVAL_BUFFER structure.
706 the uni_max_len member tells you how large the buffer is.
707 the uni_str_len member tells you how much of the buffer is really used.
708 ********************************************************************/
710 BOOL smb_io_regval_buffer(const char *desc, prs_struct *ps, int depth, REGVAL_BUFFER *buf2)
713 prs_debug(ps, depth, desc, "smb_io_regval_buffer");
719 if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
721 if(!prs_uint32("offset ", ps, depth, &buf2->offset))
723 if(!prs_uint32("buf_len ", ps, depth, &buf2->buf_len))
726 /* buffer advanced by indicated length of string
727 NOT by searching for null-termination */
729 if(!prs_regval_buffer(True, "buffer ", ps, depth, buf2))
735 /*******************************************************************
736 creates a UNISTR2 structure: sets up the buffer, too
737 ********************************************************************/
739 void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
743 init_unistr2(str, buf, UNI_STR_TERMINATE);
746 init_unistr2(str, NULL, UNI_FLAGS_NONE);
751 /*******************************************************************
752 Copies a UNISTR2 structure.
753 ********************************************************************/
755 void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
757 if (from->buffer == NULL) {
762 SMB_ASSERT(from->uni_max_len >= from->uni_str_len);
764 str->uni_max_len = from->uni_max_len;
765 str->offset = from->offset;
766 str->uni_str_len = from->uni_str_len;
768 /* the string buffer is allocated to the maximum size
769 (the the length of the source string) to prevent
770 reallocation of memory. */
771 if (str->buffer == NULL) {
772 str->buffer = (uint16 *)TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, str->uni_max_len);
773 if ((str->buffer == NULL)) {
774 smb_panic("copy_unistr2: talloc fail\n");
779 /* copy the string */
780 memcpy(str->buffer, from->buffer, str->uni_max_len*sizeof(uint16));
783 /*******************************************************************
784 Creates a STRING2 structure.
785 ********************************************************************/
787 void init_string2(STRING2 *str, const char *buf, size_t max_len, size_t str_len)
789 /* set up string lengths. */
790 SMB_ASSERT(max_len >= str_len);
792 str->str_max_len = max_len;
794 str->str_str_len = str_len;
796 /* store the string */
798 str->buffer = TALLOC_ZERO(get_talloc_ctx(), str->str_max_len);
799 if (str->buffer == NULL)
800 smb_panic("init_string2: malloc fail\n");
801 memcpy(str->buffer, buf, str_len);
805 /*******************************************************************
806 Reads or writes a STRING2 structure.
807 XXXX NOTE: STRING2 structures need NOT be null-terminated.
808 the str_str_len member tells you how long the string is;
809 the str_max_len member tells you how large the buffer is.
810 ********************************************************************/
812 BOOL smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
819 prs_debug(ps, depth, desc, "smb_io_string2");
825 if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
827 if(!prs_uint32("offset ", ps, depth, &str2->offset))
829 if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
832 /* buffer advanced by indicated length of string
833 NOT by searching for null-termination */
834 if(!prs_string2(True, "buffer ", ps, depth, str2))
839 prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
841 memset((char *)str2, '\0', sizeof(*str2));
848 /*******************************************************************
849 Inits a UNISTR2 structure.
850 ********************************************************************/
852 void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags)
855 uint32 num_chars = 0;
858 /* We always null terminate the copy. */
859 len = strlen(buf) + 1;
861 /* no buffer -- nothing to do */
862 str->uni_max_len = 0;
864 str->uni_str_len = 0;
870 str->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, len);
871 if (str->buffer == NULL) {
872 smb_panic("init_unistr2: malloc fail\n");
876 /* Ensure len is the length in *bytes* */
877 len *= sizeof(uint16);
880 * The UNISTR2 must be initialized !!!
884 rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE);
885 num_chars = strlen_w(str->buffer);
886 if (flags == UNI_STR_TERMINATE || flags == UNI_MAXLEN_TERMINATE) {
891 str->uni_max_len = num_chars;
893 str->uni_str_len = num_chars;
894 if ( num_chars && ((flags == UNI_MAXLEN_TERMINATE) || (flags == UNI_BROKEN_NON_NULL)) )
898 /*******************************************************************
899 Inits a UNISTR4 structure.
900 ********************************************************************/
902 void init_unistr4(UNISTR4 *uni4, const char *buf, enum unistr2_term_codes flags)
904 uni4->string = TALLOC_P( get_talloc_ctx(), UNISTR2 );
905 init_unistr2( uni4->string, buf, flags );
907 uni4->length = 2 * (uni4->string->uni_str_len);
908 uni4->size = 2 * (uni4->string->uni_max_len);
911 void init_unistr4_w( TALLOC_CTX *ctx, UNISTR4 *uni4, const smb_ucs2_t *buf )
913 uni4->string = TALLOC_P( ctx, UNISTR2 );
914 init_unistr2_w( ctx, uni4->string, buf );
916 uni4->length = 2 * (uni4->string->uni_str_len);
917 uni4->size = 2 * (uni4->string->uni_max_len);
921 * Inits a UNISTR2 structure.
922 * @param ctx talloc context to allocate string on
923 * @param str pointer to string to create
924 * @param buf UCS2 null-terminated buffer to init from
927 void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
929 uint32 len = strlen_w(buf);
933 /* set up string lengths. */
934 str->uni_max_len = len;
936 str->uni_str_len = len;
938 str->buffer = TALLOC_ZERO_ARRAY(ctx, uint16, len + 1);
939 if (str->buffer == NULL) {
940 smb_panic("init_unistr2_w: malloc fail\n");
945 * don't move this test above ! The UNISTR2 must be initialized !!!
951 /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as
952 long as the buffer above is talloc()ed correctly then this
953 is the correct thing to do */
954 strncpy_w(str->buffer, buf, len + 1);
957 /*******************************************************************
958 Inits a UNISTR2 structure from a UNISTR
959 ********************************************************************/
961 void init_unistr2_from_unistr(UNISTR2 *to, const UNISTR *from)
965 /* the destination UNISTR2 should never be NULL.
966 if it is it is a programming error */
968 /* if the source UNISTR is NULL, then zero out
969 the destination string and return */
971 if ((from == NULL) || (from->buffer == NULL))
974 /* get the length; UNISTR must be NULL terminated */
976 while ((from->buffer)[i]!='\0')
978 i++; /* one more to catch the terminating NULL */
979 /* is this necessary -- jerry? I need to think */
981 /* set up string lengths; uni_max_len is set to i+1
982 because we need to account for the final NULL termination */
987 /* allocate the space and copy the string buffer */
988 to->buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, i);
989 if (to->buffer == NULL)
990 smb_panic("init_unistr2_from_unistr: malloc fail\n");
991 memcpy(to->buffer, from->buffer, i*sizeof(uint16));
995 /*******************************************************************
996 Inits a UNISTR2 structure from a DATA_BLOB.
997 The length of the data_blob must count the bytes of the buffer.
998 Copies the blob data.
999 ********************************************************************/
1001 void init_unistr2_from_datablob(UNISTR2 *str, DATA_BLOB *blob)
1003 /* Allocs the unistring */
1004 init_unistr2(str, NULL, UNI_FLAGS_NONE);
1006 /* Sets the values */
1007 str->uni_str_len = blob->length / sizeof(uint16);
1008 str->uni_max_len = str->uni_str_len;
1011 str->buffer = (uint16 *) memdup(blob->data, blob->length);
1015 if ((str->buffer == NULL) && (blob->length > 0)) {
1016 smb_panic("init_unistr2_from_datablob: malloc fail\n");
1020 /*******************************************************************
1021 UNISTR2* are a little different in that the pointer and the UNISTR2
1022 are not necessarily read/written back to back. So we break it up
1023 into 2 separate functions.
1024 See SPOOL_USER_1 in include/rpc_spoolss.h for an example.
1025 ********************************************************************/
1027 BOOL prs_io_unistr2_p(const char *desc, prs_struct *ps, int depth, UNISTR2 **uni2)
1031 /* caputure the pointer value to stream */
1033 data_p = (uint32) *uni2;
1035 if ( !prs_uint32("ptr", ps, depth, &data_p ))
1038 /* we're done if there is no data */
1043 if (UNMARSHALLING(ps)) {
1044 if ( !(*uni2 = PRS_ALLOC_MEM(ps, UNISTR2, 1)) )
1051 /*******************************************************************
1052 now read/write the actual UNISTR2. Memory for the UNISTR2 (but
1053 not UNISTR2.buffer) has been allocated previously by prs_unistr2_p()
1054 ********************************************************************/
1056 BOOL prs_io_unistr2(const char *desc, prs_struct *ps, int depth, UNISTR2 *uni2 )
1058 /* just return true if there is no pointer to deal with.
1059 the memory must have been previously allocated on unmarshalling
1060 by prs_unistr2_p() */
1065 /* just pass off to smb_io_unstr2() passing the uni2 address as
1066 the pointer (like you would expect) */
1068 return smb_io_unistr2( desc, uni2, (uint32)uni2, ps, depth );
1071 /*******************************************************************
1072 Reads or writes a UNISTR2 structure.
1073 XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
1074 the uni_str_len member tells you how long the string is;
1075 the uni_max_len member tells you how large the buffer is.
1076 ********************************************************************/
1078 BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
1085 prs_debug(ps, depth, desc, "smb_io_unistr2");
1091 if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
1093 if(!prs_uint32("offset ", ps, depth, &uni2->offset))
1095 if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
1098 /* buffer advanced by indicated length of string
1099 NOT by searching for null-termination */
1100 if(!prs_unistr2(True, "buffer ", ps, depth, uni2))
1105 prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
1107 memset((char *)uni2, '\0', sizeof(*uni2));
1114 /*******************************************************************
1115 now read/write UNISTR4
1116 ********************************************************************/
1118 BOOL prs_unistr4(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1120 if ( !prs_uint16("length", ps, depth, &uni4->length ))
1122 if ( !prs_uint16("size", ps, depth, &uni4->size ))
1125 if ( !prs_pointer( desc, ps, depth, (void**)&uni4->string, sizeof(UNISTR2), (PRS_POINTER_CAST)prs_io_unistr2 ) )
1131 /*******************************************************************
1132 now read/write UNISTR4 header
1133 ********************************************************************/
1135 BOOL prs_unistr4_hdr(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1137 prs_debug(ps, depth, desc, "prs_unistr4_hdr");
1140 if ( !prs_uint16("length", ps, depth, &uni4->length) )
1142 if ( !prs_uint16("size", ps, depth, &uni4->size) )
1144 if ( !prs_io_unistr2_p(desc, ps, depth, &uni4->string) )
1150 /*******************************************************************
1151 now read/write UNISTR4 string
1152 ********************************************************************/
1154 BOOL prs_unistr4_str(const char *desc, prs_struct *ps, int depth, UNISTR4 *uni4)
1156 prs_debug(ps, depth, desc, "prs_unistr4_str");
1159 if ( !prs_io_unistr2(desc, ps, depth, uni4->string) )
1165 /*******************************************************************
1166 Reads or writes a UNISTR2_ARRAY structure.
1167 ********************************************************************/
1169 BOOL prs_unistr4_array(const char *desc, prs_struct *ps, int depth, UNISTR4_ARRAY *array )
1173 prs_debug(ps, depth, desc, "prs_unistr4_array");
1176 if(!prs_uint32("count", ps, depth, &array->count))
1179 if ( array->count == 0 )
1182 if (UNMARSHALLING(ps)) {
1183 if ( !(array->strings = TALLOC_ZERO_ARRAY( get_talloc_ctx(), UNISTR4, array->count)) )
1187 /* write the headers and then the actual string buffer */
1189 for ( i=0; i<array->count; i++ ) {
1190 if ( !prs_unistr4_hdr( "string", ps, depth, &array->strings[i]) )
1194 for (i=0;i<array->count;i++) {
1195 if ( !prs_unistr4_str("string", ps, depth, &array->strings[i]) )
1202 /********************************************************************
1203 initialise a UNISTR_ARRAY from a char**
1204 ********************************************************************/
1206 BOOL init_unistr4_array( UNISTR4_ARRAY *array, uint32 count, const char **strings )
1210 array->count = count;
1212 if ( array->count == 0 )
1215 /* allocate memory for the array of UNISTR4 objects */
1217 if ( !(array->strings = TALLOC_ZERO_ARRAY(get_talloc_ctx(), UNISTR4, count )) )
1220 for ( i=0; i<count; i++ )
1221 init_unistr4( &array->strings[i], strings[i], STR_TERMINATE );
1226 BOOL smb_io_lockout_string_hdr(const char *desc, HDR_LOCKOUT_STRING *hdr_account_lockout, prs_struct *ps, int depth)
1228 prs_debug(ps, depth, desc, "smb_io_lockout_string_hdr");
1234 if(!prs_uint16("size", ps, depth, &hdr_account_lockout->size))
1236 if(!prs_uint16("length", ps, depth, &hdr_account_lockout->length))
1238 if(!prs_uint32("buffer", ps, depth, &hdr_account_lockout->buffer))
1244 BOOL smb_io_account_lockout_str(const char *desc, LOCKOUT_STRING *account_lockout, uint32 buffer, prs_struct *ps, int depth)
1246 prs_debug(ps, depth, desc, "smb_io_account_lockout_string");
1249 if(!prs_uint32("array_size", ps, depth, &account_lockout->array_size))
1252 if(!prs_uint32("offset", ps, depth, &account_lockout->offset))
1254 if(!prs_uint32("length", ps, depth, &account_lockout->length))
1257 if (!prs_uint64("lockout_duration", ps, depth, &account_lockout->lockout_duration))
1259 if (!prs_uint64("reset_count", ps, depth, &account_lockout->reset_count))
1261 if (!prs_uint32("bad_attempt_lockout", ps, depth, &account_lockout->bad_attempt_lockout))
1263 if (!prs_uint32("dummy", ps, depth, &account_lockout->dummy))
1266 if(!prs_uint16s (False, "bindata", ps, depth, &account_lockout->bindata, length))
1273 /*******************************************************************
1274 Inits a DOM_RID2 structure.
1275 ********************************************************************/
1277 void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
1281 rid2->rid_idx = idx;
1284 /*******************************************************************
1285 Reads or writes a DOM_RID2 structure.
1286 ********************************************************************/
1288 BOOL smb_io_dom_rid2(const char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
1293 prs_debug(ps, depth, desc, "smb_io_dom_rid2");
1299 if(!prs_uint8("type ", ps, depth, &rid2->type))
1303 if(!prs_uint32("rid ", ps, depth, &rid2->rid))
1305 if(!prs_uint32("rid_idx", ps, depth, &rid2->rid_idx))
1311 /*******************************************************************
1312 creates a DOM_RID3 structure.
1313 ********************************************************************/
1315 void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
1319 rid3->ptr_type = 0x1; /* non-zero, basically. */
1324 /*******************************************************************
1325 reads or writes a DOM_RID3 structure.
1326 ********************************************************************/
1328 BOOL smb_io_dom_rid3(const char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
1333 prs_debug(ps, depth, desc, "smb_io_dom_rid3");
1339 if(!prs_uint32("rid ", ps, depth, &rid3->rid))
1341 if(!prs_uint32("type1 ", ps, depth, &rid3->type1))
1343 if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
1345 if(!prs_uint32("type2 ", ps, depth, &rid3->type2))
1347 if(!prs_uint32("unk ", ps, depth, &rid3->unk))
1353 /*******************************************************************
1354 Inits a DOM_RID4 structure.
1355 ********************************************************************/
1357 void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
1359 rid4->unknown = unknown;
1364 /*******************************************************************
1365 Inits a DOM_CLNT_SRV structure.
1366 ********************************************************************/
1368 static void init_clnt_srv(DOM_CLNT_SRV *logcln, const char *logon_srv, const char *comp_name)
1370 DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
1372 if (logon_srv != NULL) {
1373 logcln->undoc_buffer = 1;
1374 init_unistr2(&logcln->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
1376 logcln->undoc_buffer = 0;
1379 if (comp_name != NULL) {
1380 logcln->undoc_buffer2 = 1;
1381 init_unistr2(&logcln->uni_comp_name, comp_name, UNI_STR_TERMINATE);
1383 logcln->undoc_buffer2 = 0;
1387 /*******************************************************************
1388 Inits or writes a DOM_CLNT_SRV structure.
1389 ********************************************************************/
1391 static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *logcln, prs_struct *ps, int depth)
1396 prs_debug(ps, depth, desc, "smb_io_clnt_srv");
1402 if(!prs_uint32("undoc_buffer ", ps, depth, &logcln->undoc_buffer))
1405 if (logcln->undoc_buffer != 0) {
1406 if(!smb_io_unistr2("unistr2", &logcln->uni_logon_srv, logcln->undoc_buffer, ps, depth))
1413 if(!prs_uint32("undoc_buffer2", ps, depth, &logcln->undoc_buffer2))
1416 if (logcln->undoc_buffer2 != 0) {
1417 if(!smb_io_unistr2("unistr2", &logcln->uni_comp_name, logcln->undoc_buffer2, ps, depth))
1424 /*******************************************************************
1425 Inits a DOM_LOG_INFO structure.
1426 ********************************************************************/
1428 void init_log_info(DOM_LOG_INFO *loginfo, const char *logon_srv, const char *acct_name,
1429 uint16 sec_chan, const char *comp_name)
1431 DEBUG(5,("make_log_info %d\n", __LINE__));
1433 loginfo->undoc_buffer = 1;
1435 init_unistr2(&loginfo->uni_logon_srv, logon_srv, UNI_STR_TERMINATE);
1436 init_unistr2(&loginfo->uni_acct_name, acct_name, UNI_STR_TERMINATE);
1438 loginfo->sec_chan = sec_chan;
1440 init_unistr2(&loginfo->uni_comp_name, comp_name, UNI_STR_TERMINATE);
1443 /*******************************************************************
1444 Reads or writes a DOM_LOG_INFO structure.
1445 ********************************************************************/
1447 BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *loginfo, prs_struct *ps, int depth)
1449 if (loginfo == NULL)
1452 prs_debug(ps, depth, desc, "smb_io_log_info");
1458 if(!prs_uint32("undoc_buffer", ps, depth, &loginfo->undoc_buffer))
1461 if(!smb_io_unistr2("unistr2", &loginfo->uni_logon_srv, True, ps, depth))
1463 if(!smb_io_unistr2("unistr2", &loginfo->uni_acct_name, True, ps, depth))
1466 if(!prs_uint16("sec_chan", ps, depth, &loginfo->sec_chan))
1469 if(!smb_io_unistr2("unistr2", &loginfo->uni_comp_name, True, ps, depth))
1475 /*******************************************************************
1476 Reads or writes a DOM_CHAL structure.
1477 ********************************************************************/
1479 BOOL smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
1484 prs_debug(ps, depth, desc, "smb_io_chal");
1487 if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
1493 /*******************************************************************
1494 Reads or writes a DOM_CRED structure.
1495 ********************************************************************/
1497 BOOL smb_io_cred(const char *desc, DOM_CRED *cred, prs_struct *ps, int depth)
1502 prs_debug(ps, depth, desc, "smb_io_cred");
1508 if(!smb_io_chal ("", &cred->challenge, ps, depth))
1511 if(!smb_io_utime("", &cred->timestamp, ps, depth))
1517 /*******************************************************************
1518 Inits a DOM_CLNT_INFO2 structure.
1519 ********************************************************************/
1521 void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
1522 const char *logon_srv, const char *comp_name,
1523 const DOM_CRED *clnt_cred)
1525 DEBUG(5,("make_clnt_info: %d\n", __LINE__));
1527 init_clnt_srv(&clnt->login, logon_srv, comp_name);
1529 if (clnt_cred != NULL) {
1531 memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
1537 /*******************************************************************
1538 Reads or writes a DOM_CLNT_INFO2 structure.
1539 ********************************************************************/
1541 BOOL smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
1546 prs_debug(ps, depth, desc, "smb_io_clnt_info2");
1552 if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
1558 if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
1560 if(!smb_io_cred("", &clnt->cred, ps, depth))
1566 /*******************************************************************
1567 Inits a DOM_CLNT_INFO structure.
1568 ********************************************************************/
1570 void init_clnt_info(DOM_CLNT_INFO *clnt,
1571 const char *logon_srv, const char *acct_name,
1572 uint16 sec_chan, const char *comp_name,
1573 const DOM_CRED *cred)
1575 DEBUG(5,("make_clnt_info\n"));
1577 init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
1578 memcpy(&clnt->cred, cred, sizeof(clnt->cred));
1581 /*******************************************************************
1582 Reads or writes a DOM_CLNT_INFO structure.
1583 ********************************************************************/
1585 BOOL smb_io_clnt_info(const char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
1590 prs_debug(ps, depth, desc, "smb_io_clnt_info");
1596 if(!smb_io_log_info("", &clnt->login, ps, depth))
1598 if(!smb_io_cred("", &clnt->cred, ps, depth))
1604 /*******************************************************************
1605 Inits a DOM_LOGON_ID structure.
1606 ********************************************************************/
1608 void init_logon_id(DOM_LOGON_ID *logonid, uint32 log_id_low, uint32 log_id_high)
1610 DEBUG(5,("make_logon_id: %d\n", __LINE__));
1612 logonid->low = log_id_low;
1613 logonid->high = log_id_high;
1616 /*******************************************************************
1617 Reads or writes a DOM_LOGON_ID structure.
1618 ********************************************************************/
1620 BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *logonid, prs_struct *ps, int depth)
1622 if (logonid == NULL)
1625 prs_debug(ps, depth, desc, "smb_io_logon_id");
1631 if(!prs_uint32("low ", ps, depth, &logonid->low ))
1633 if(!prs_uint32("high", ps, depth, &logonid->high))
1639 /*******************************************************************
1640 Inits an OWF_INFO structure.
1641 ********************************************************************/
1643 void init_owf_info(OWF_INFO *hash, const uint8 data[16])
1645 DEBUG(5,("init_owf_info: %d\n", __LINE__));
1648 memcpy(hash->data, data, sizeof(hash->data));
1650 memset((char *)hash->data, '\0', sizeof(hash->data));
1653 /*******************************************************************
1654 Reads or writes an OWF_INFO structure.
1655 ********************************************************************/
1657 BOOL smb_io_owf_info(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
1662 prs_debug(ps, depth, desc, "smb_io_owf_info");
1668 if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
1674 /*******************************************************************
1675 Reads or writes a DOM_GID structure.
1676 ********************************************************************/
1678 BOOL smb_io_gid(const char *desc, DOM_GID *gid, prs_struct *ps, int depth)
1683 prs_debug(ps, depth, desc, "smb_io_gid");
1689 if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
1691 if(!prs_uint32("attr ", ps, depth, &gid->attr))
1697 /*******************************************************************
1698 Reads or writes an POLICY_HND structure.
1699 ********************************************************************/
1701 BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
1706 prs_debug(ps, depth, desc, "smb_io_pol_hnd");
1712 if(UNMARSHALLING(ps))
1715 if (!prs_uint32("data1", ps, depth, &pol->data1))
1717 if (!prs_uint32("data2", ps, depth, &pol->data2))
1719 if (!prs_uint16("data3", ps, depth, &pol->data3))
1721 if (!prs_uint16("data4", ps, depth, &pol->data4))
1723 if(!prs_uint8s (False, "data5", ps, depth, pol->data5, sizeof(pol->data5)))
1729 /*******************************************************************
1731 ********************************************************************/
1733 void init_unistr3(UNISTR3 *str, const char *buf)
1737 str->str.buffer = NULL;
1741 str->uni_str_len = strlen(buf) + 1;
1743 str->str.buffer = TALLOC_ZERO_ARRAY(get_talloc_ctx(), uint16, str->uni_str_len);
1744 if (str->str.buffer == NULL)
1745 smb_panic("init_unistr3: malloc fail\n");
1747 rpcstr_push((char *)str->str.buffer, buf, str->uni_str_len * sizeof(uint16), STR_TERMINATE);
1750 /*******************************************************************
1751 Reads or writes a UNISTR3 structure.
1752 ********************************************************************/
1754 BOOL smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth)
1759 prs_debug(ps, depth, desc, "smb_io_unistr3");
1765 if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
1768 /* don't know if len is specified by uni_str_len member... */
1769 /* assume unicode string is unicode-null-terminated, instead */
1771 if(!prs_unistr3(True, "unistr", name, ps, depth))
1778 /*******************************************************************
1779 Stream a uint64_struct
1780 ********************************************************************/
1781 BOOL prs_uint64(const char *name, prs_struct *ps, int depth, UINT64_S *data64)
1783 return prs_uint32(name, ps, depth+1, &data64->low) &&
1784 prs_uint32(name, ps, depth+1, &data64->high);
1787 /*******************************************************************
1788 reads or writes a BUFHDR2 structure.
1789 ********************************************************************/
1790 BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
1792 prs_debug(ps, depth, desc, "smb_io_bufhdr2");
1796 prs_uint32("info_level", ps, depth, &(hdr->info_level));
1797 prs_uint32("length ", ps, depth, &(hdr->length ));
1798 prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
1803 /*******************************************************************
1804 reads or writes a BUFHDR4 structure.
1805 ********************************************************************/
1806 BOOL smb_io_bufhdr4(const char *desc, BUFHDR4 *hdr, prs_struct *ps, int depth)
1808 prs_debug(ps, depth, desc, "smb_io_bufhdr4");
1812 prs_uint32("size", ps, depth, &hdr->size);
1813 prs_uint32("buffer", ps, depth, &hdr->buffer);
1818 /*******************************************************************
1819 reads or writes a BUFFER4 structure.
1820 ********************************************************************/
1822 BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
1824 prs_debug(ps, depth, desc, "smb_io_buffer4");
1828 prs_uint32("buf_len", ps, depth, &buf4->buf_len);
1829 if (UNMARSHALLING(ps)) {
1830 buf4->buffer = PRS_ALLOC_MEM(ps, uint8, buf4->buf_len);
1831 if (!buf4->buffer) {
1835 prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
1840 /*******************************************************************
1841 creates a UNIHDR structure.
1842 ********************************************************************/
1844 BOOL make_uni_hdr(UNIHDR *hdr, int len)
1850 hdr->uni_str_len = 2 * len;
1851 hdr->uni_max_len = 2 * len;
1852 hdr->buffer = len != 0 ? 1 : 0;
1857 /*******************************************************************
1858 creates a BUFHDR2 structure.
1859 ********************************************************************/
1860 BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
1862 hdr->info_level = info_level;
1863 hdr->length = length;
1864 hdr->buffer = buffer;
1869 /*******************************************************************
1870 return the length of a UNISTR string.
1871 ********************************************************************/
1873 uint32 str_len_uni(UNISTR *source)
1877 if (!source->buffer)
1880 while (source->buffer[i])