At the prompting, start to add infrastructure to detect the presence of
[Samba/gebeck_regimport.git] / source3 / rpc_parse / parse_misc.c
blob9d3bd6f28a2823e1eabe4c3e5d743d6ba2c43ca8
1 /*
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 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_RPC_PARSE
28 /****************************************************************************
29 A temporary TALLOC context for things like unistrs, that is valid for
30 the life of a complete RPC call.
31 ****************************************************************************/
33 static TALLOC_CTX *current_rpc_talloc = NULL;
35 TALLOC_CTX *get_current_rpc_talloc(void)
37 return current_rpc_talloc;
40 void set_current_rpc_talloc( TALLOC_CTX *ctx)
42 current_rpc_talloc = ctx;
45 static TALLOC_CTX *main_loop_talloc = NULL;
47 /*******************************************************************
48 free up temporary memory - called from the main loop
49 ********************************************************************/
51 void main_loop_talloc_free(void)
53 if (!main_loop_talloc)
54 return;
55 talloc_destroy(main_loop_talloc);
56 main_loop_talloc = NULL;
59 /*******************************************************************
60 Get a talloc context that is freed in the main loop...
61 ********************************************************************/
63 TALLOC_CTX *main_loop_talloc_get(void)
65 if (!main_loop_talloc) {
66 main_loop_talloc = talloc_init("main loop talloc (mainly parse_misc)");
67 if (!main_loop_talloc)
68 smb_panic("main_loop_talloc: malloc fail\n");
71 return main_loop_talloc;
74 /*******************************************************************
75 Try and get a talloc context. Get the rpc one if possible, else
76 get the main loop one. The main loop one is more dangerous as it
77 goes away between packets, the rpc one will stay around for as long
78 as a current RPC lasts.
79 ********************************************************************/
81 TALLOC_CTX *get_talloc_ctx(void)
83 TALLOC_CTX *tc = get_current_rpc_talloc();
85 if (tc)
86 return tc;
87 return main_loop_talloc_get();
90 /*******************************************************************
91 Reads or writes a UTIME type.
92 ********************************************************************/
94 static BOOL smb_io_utime(const char *desc, UTIME *t, prs_struct *ps, int depth)
96 if (t == NULL)
97 return False;
99 prs_debug(ps, depth, desc, "smb_io_utime");
100 depth++;
102 if(!prs_align(ps))
103 return False;
105 if(!prs_uint32 ("time", ps, depth, &t->time))
106 return False;
108 return True;
111 /*******************************************************************
112 Reads or writes an NTTIME structure.
113 ********************************************************************/
115 BOOL smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth)
117 if (nttime == NULL)
118 return False;
120 prs_debug(ps, depth, desc, "smb_io_time");
121 depth++;
123 if(!prs_align(ps))
124 return False;
126 if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */
127 return False;
128 if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */
129 return False;
131 return True;
134 /*******************************************************************
135 Reads or writes a LOOKUP_LEVEL structure.
136 ********************************************************************/
138 BOOL smb_io_lookup_level(const char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth)
140 if (level == NULL)
141 return False;
143 prs_debug(ps, depth, desc, "smb_io_lookup_level");
144 depth++;
146 if(!prs_align(ps))
147 return False;
148 if(!prs_uint16("value", ps, depth, &level->value))
149 return False;
150 if(!prs_align(ps))
151 return False;
153 return True;
156 /*******************************************************************
157 Gets an enumeration handle from an ENUM_HND structure.
158 ********************************************************************/
160 uint32 get_enum_hnd(ENUM_HND *enh)
162 return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
165 /*******************************************************************
166 Inits an ENUM_HND structure.
167 ********************************************************************/
169 void init_enum_hnd(ENUM_HND *enh, uint32 hnd)
171 DEBUG(5,("smb_io_enum_hnd\n"));
173 enh->ptr_hnd = (hnd != 0) ? 1 : 0;
174 enh->handle = hnd;
177 /*******************************************************************
178 Reads or writes an ENUM_HND structure.
179 ********************************************************************/
181 BOOL smb_io_enum_hnd(const char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
183 if (hnd == NULL)
184 return False;
186 prs_debug(ps, depth, desc, "smb_io_enum_hnd");
187 depth++;
189 if(!prs_align(ps))
190 return False;
192 if(!prs_uint32("ptr_hnd", ps, depth, &hnd->ptr_hnd)) /* pointer */
193 return False;
195 if (hnd->ptr_hnd != 0) {
196 if(!prs_uint32("handle ", ps, depth, &hnd->handle )) /* enum handle */
197 return False;
200 return True;
203 /*******************************************************************
204 Reads or writes a DOM_SID structure.
205 ********************************************************************/
207 BOOL smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth)
209 int i;
211 if (sid == NULL)
212 return False;
214 prs_debug(ps, depth, desc, "smb_io_dom_sid");
215 depth++;
217 if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
218 return False;
219 if(!prs_uint8 ("num_auths ", ps, depth, &sid->num_auths))
220 return False;
222 for (i = 0; i < 6; i++)
224 fstring tmp;
225 slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
226 if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
227 return False;
230 /* oops! XXXX should really issue a warning here... */
231 if (sid->num_auths > MAXSUBAUTHS)
232 sid->num_auths = MAXSUBAUTHS;
234 if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
235 return False;
237 return True;
240 /*******************************************************************
241 Inits a DOM_SID structure.
243 BIG NOTE: this function only does SIDS where the identauth is not >= 2^32
244 identauth >= 2^32 can be detected because it will be specified in hex
245 ********************************************************************/
247 void init_dom_sid(DOM_SID *sid, const char *str_sid)
249 pstring domsid;
250 int identauth;
251 char *p;
253 if (str_sid == NULL) {
254 DEBUG(4,("netlogon domain SID: none\n"));
255 sid->sid_rev_num = 0;
256 sid->num_auths = 0;
257 return;
260 pstrcpy(domsid, str_sid);
262 DEBUG(4,("init_dom_sid %d SID: %s\n", __LINE__, domsid));
264 /* assume, but should check, that domsid starts "S-" */
265 p = strtok(domsid+2,"-");
266 sid->sid_rev_num = atoi(p);
268 /* identauth in decimal should be < 2^32 */
269 /* identauth in hex should be >= 2^32 */
270 identauth = atoi(strtok(0,"-"));
272 DEBUG(4,("netlogon rev %d\n", sid->sid_rev_num));
273 DEBUG(4,("netlogon %s ia %d\n", p, identauth));
275 sid->id_auth[0] = 0;
276 sid->id_auth[1] = 0;
277 sid->id_auth[2] = (identauth & 0xff000000) >> 24;
278 sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
279 sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
280 sid->id_auth[5] = (identauth & 0x000000ff);
282 sid->num_auths = 0;
284 while ((p = strtok(0, "-")) != NULL && sid->num_auths < MAXSUBAUTHS)
285 sid->sub_auths[sid->num_auths++] = atoi(p);
287 DEBUG(4,("init_dom_sid: %d SID: %s\n", __LINE__, domsid));
290 /*******************************************************************
291 Inits a DOM_SID2 structure.
292 ********************************************************************/
294 void init_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
296 sid2->sid = *sid;
297 sid2->num_auths = sid2->sid.num_auths;
300 /*******************************************************************
301 Reads or writes a DOM_SID2 structure.
302 ********************************************************************/
304 BOOL smb_io_dom_sid2(const char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
306 if (sid == NULL)
307 return False;
309 prs_debug(ps, depth, desc, "smb_io_dom_sid2");
310 depth++;
312 if(!prs_align(ps))
313 return False;
315 if(!prs_uint32("num_auths", ps, depth, &sid->num_auths))
316 return False;
318 if(!smb_io_dom_sid("sid", &sid->sid, ps, depth))
319 return False;
321 return True;
324 /*******************************************************************
325 creates a STRHDR structure.
326 ********************************************************************/
328 void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
330 hdr->str_max_len = max_len;
331 hdr->str_str_len = len;
332 hdr->buffer = buffer;
335 /*******************************************************************
336 Reads or writes a STRHDR structure.
337 ********************************************************************/
339 BOOL smb_io_strhdr(const char *desc, STRHDR *hdr, prs_struct *ps, int depth)
341 if (hdr == NULL)
342 return False;
344 prs_debug(ps, depth, desc, "smb_io_strhdr");
345 depth++;
347 prs_align(ps);
349 if(!prs_uint16("str_str_len", ps, depth, &hdr->str_str_len))
350 return False;
351 if(!prs_uint16("str_max_len", ps, depth, &hdr->str_max_len))
352 return False;
353 if(!prs_uint32("buffer ", ps, depth, &hdr->buffer))
354 return False;
356 return True;
359 /*******************************************************************
360 Inits a UNIHDR structure.
361 ********************************************************************/
363 void init_uni_hdr(UNIHDR *hdr, int len)
365 hdr->uni_str_len = 2 * len;
366 hdr->uni_max_len = 2 * len;
367 hdr->buffer = len != 0 ? 1 : 0;
370 /*******************************************************************
371 Reads or writes a UNIHDR structure.
372 ********************************************************************/
374 BOOL smb_io_unihdr(const char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
376 if (hdr == NULL)
377 return False;
379 prs_debug(ps, depth, desc, "smb_io_unihdr");
380 depth++;
382 if(!prs_align(ps))
383 return False;
385 if(!prs_uint16("uni_str_len", ps, depth, &hdr->uni_str_len))
386 return False;
387 if(!prs_uint16("uni_max_len", ps, depth, &hdr->uni_max_len))
388 return False;
389 if(!prs_uint32("buffer ", ps, depth, &hdr->buffer))
390 return False;
392 return True;
395 /*******************************************************************
396 Inits a BUFHDR structure.
397 ********************************************************************/
399 void init_buf_hdr(BUFHDR *hdr, int max_len, int len)
401 hdr->buf_max_len = max_len;
402 hdr->buf_len = len;
405 /*******************************************************************
406 prs_uint16 wrapper. Call this and it sets up a pointer to where the
407 uint16 should be stored, or gets the size if reading.
408 ********************************************************************/
410 BOOL smb_io_hdrbuf_pre(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
412 (*offset) = prs_offset(ps);
413 if (ps->io) {
415 /* reading. */
417 if(!smb_io_hdrbuf(desc, hdr, ps, depth))
418 return False;
420 } else {
422 /* writing. */
424 if(!prs_set_offset(ps, prs_offset(ps) + (sizeof(uint32) * 2)))
425 return False;
428 return True;
431 /*******************************************************************
432 smb_io_hdrbuf wrapper. Call this and it retrospectively stores the size.
433 Does nothing on reading, as that is already handled by ...._pre()
434 ********************************************************************/
436 BOOL smb_io_hdrbuf_post(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
437 uint32 ptr_hdrbuf, uint32 max_len, uint32 len)
439 if (!ps->io) {
440 /* writing: go back and do a retrospective job. i hate this */
442 uint32 old_offset = prs_offset(ps);
444 init_buf_hdr(hdr, max_len, len);
445 if(!prs_set_offset(ps, ptr_hdrbuf))
446 return False;
447 if(!smb_io_hdrbuf(desc, hdr, ps, depth))
448 return False;
450 if(!prs_set_offset(ps, old_offset))
451 return False;
454 return True;
457 /*******************************************************************
458 Reads or writes a BUFHDR structure.
459 ********************************************************************/
461 BOOL smb_io_hdrbuf(const char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
463 if (hdr == NULL)
464 return False;
466 prs_debug(ps, depth, desc, "smb_io_hdrbuf");
467 depth++;
469 if(!prs_align(ps))
470 return False;
472 if(!prs_uint32("buf_max_len", ps, depth, &hdr->buf_max_len))
473 return False;
474 if(!prs_uint32("buf_len ", ps, depth, &hdr->buf_len))
475 return False;
477 return True;
480 /*******************************************************************
481 creates a UNIHDR2 structure.
482 ********************************************************************/
484 void init_uni_hdr2(UNIHDR2 *hdr, int len)
486 init_uni_hdr(&hdr->unihdr, len);
487 hdr->buffer = (len > 0) ? 1 : 0;
490 /*******************************************************************
491 Reads or writes a UNIHDR2 structure.
492 ********************************************************************/
494 BOOL smb_io_unihdr2(const char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth)
496 if (hdr2 == NULL)
497 return False;
499 prs_debug(ps, depth, desc, "smb_io_unihdr2");
500 depth++;
502 if(!prs_align(ps))
503 return False;
505 if(!smb_io_unihdr("hdr", &hdr2->unihdr, ps, depth))
506 return False;
507 if(!prs_uint32("buffer", ps, depth, &hdr2->buffer))
508 return False;
510 return True;
513 /*******************************************************************
514 Inits a UNISTR structure.
515 ********************************************************************/
517 void init_unistr(UNISTR *str, const char *buf)
519 size_t len;
521 if (buf == NULL) {
522 str->buffer = NULL;
523 return;
527 len = strlen(buf) + 1;
529 if (len < MAX_UNISTRLEN)
530 len = MAX_UNISTRLEN;
531 len *= sizeof(uint16);
533 str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
534 if (str->buffer == NULL)
535 smb_panic("init_unistr: malloc fail\n");
537 rpcstr_push(str->buffer, buf, len, STR_TERMINATE);
540 /*******************************************************************
541 reads or writes a UNISTR structure.
542 XXXX NOTE: UNISTR structures NEED to be null-terminated.
543 ********************************************************************/
545 BOOL smb_io_unistr(const char *desc, UNISTR *uni, prs_struct *ps, int depth)
547 if (uni == NULL)
548 return False;
550 prs_debug(ps, depth, desc, "smb_io_unistr");
551 depth++;
553 if(!prs_unistr("unistr", ps, depth, uni))
554 return False;
556 return True;
559 /*******************************************************************
560 Allocate the BUFFER3 memory.
561 ********************************************************************/
563 static void create_buffer3(BUFFER3 *str, size_t len)
565 if (len < MAX_BUFFERLEN)
566 len = MAX_BUFFERLEN;
568 str->buffer = talloc_zero(get_talloc_ctx(), len);
569 if (str->buffer == NULL)
570 smb_panic("create_buffer3: talloc fail\n");
574 /*******************************************************************
575 Inits a BUFFER3 structure from a uint32
576 ********************************************************************/
578 void init_buffer3_uint32(BUFFER3 *str, uint32 val)
580 ZERO_STRUCTP(str);
582 /* set up string lengths. */
583 str->buf_max_len = sizeof(uint32);
584 str->buf_len = sizeof(uint32);
586 create_buffer3(str, sizeof(uint32));
587 SIVAL(str->buffer, 0, val);
590 /*******************************************************************
591 Inits a BUFFER3 structure.
592 ********************************************************************/
594 void init_buffer3_str(BUFFER3 *str, const char *buf, int len)
596 ZERO_STRUCTP(str);
598 /* set up string lengths. */
599 str->buf_max_len = len * 2;
600 str->buf_len = len * 2;
602 create_buffer3(str, str->buf_max_len);
604 rpcstr_push(str->buffer, buf, str->buf_max_len, STR_TERMINATE);
608 /*******************************************************************
609 Inits a BUFFER3 structure from a hex string.
610 ********************************************************************/
612 void init_buffer3_hex(BUFFER3 *str, const char *buf)
614 ZERO_STRUCTP(str);
615 create_buffer3(str, strlen(buf));
616 str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, sizeof(str->buffer), buf);
619 /*******************************************************************
620 Inits a BUFFER3 structure.
621 ********************************************************************/
623 void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
625 ZERO_STRUCTP(str);
627 /* max buffer size (allocated size) */
628 str->buf_max_len = len;
629 if (buf != NULL) {
630 create_buffer3(str, len);
631 memcpy(str->buffer, buf, len);
633 str->buf_len = buf != NULL ? len : 0;
636 /*******************************************************************
637 Reads or writes a BUFFER3 structure.
638 the uni_max_len member tells you how large the buffer is.
639 the uni_str_len member tells you how much of the buffer is really used.
640 ********************************************************************/
642 BOOL smb_io_buffer3(const char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
644 if (buf3 == NULL)
645 return False;
647 prs_debug(ps, depth, desc, "smb_io_buffer3");
648 depth++;
650 if(!prs_align(ps))
651 return False;
653 if(!prs_uint32("uni_max_len", ps, depth, &buf3->buf_max_len))
654 return False;
656 if (UNMARSHALLING(ps)) {
657 buf3->buffer = (unsigned char *)prs_alloc_mem(ps, buf3->buf_max_len);
658 if (buf3->buffer == NULL)
659 return False;
662 if(!prs_uint8s(True, "buffer ", ps, depth, buf3->buffer, buf3->buf_max_len))
663 return False;
665 if(!prs_uint32("buf_len ", ps, depth, &buf3->buf_len))
666 return False;
668 return True;
671 /*******************************************************************
672 reads or writes a BUFFER5 structure.
673 the buf_len member tells you how large the buffer is.
674 ********************************************************************/
675 BOOL smb_io_buffer5(const char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
677 prs_debug(ps, depth, desc, "smb_io_buffer5");
678 depth++;
680 if (buf5 == NULL) return False;
682 if(!prs_align(ps))
683 return False;
684 if(!prs_uint32("buf_len", ps, depth, &buf5->buf_len))
685 return False;
687 if(buf5->buf_len) {
688 if(!prs_buffer5(True, "buffer" , ps, depth, buf5))
689 return False;
692 return True;
695 /*******************************************************************
696 Inits a BUFFER2 structure.
697 ********************************************************************/
699 void init_buffer2(BUFFER2 *str, const uint8 *buf, int len)
701 ZERO_STRUCTP(str);
703 /* max buffer size (allocated size) */
704 str->buf_max_len = len;
705 str->undoc = 0;
706 str->buf_len = buf != NULL ? len : 0;
708 if (buf != NULL) {
709 if (len < MAX_BUFFERLEN)
710 len = MAX_BUFFERLEN;
711 str->buffer = talloc_zero(get_talloc_ctx(), len);
712 if (str->buffer == NULL)
713 smb_panic("init_buffer2: talloc fail\n");
714 memcpy(str->buffer, buf, MIN(str->buf_len, len));
718 /*******************************************************************
719 Reads or writes a BUFFER2 structure.
720 the uni_max_len member tells you how large the buffer is.
721 the uni_str_len member tells you how much of the buffer is really used.
722 ********************************************************************/
724 BOOL smb_io_buffer2(const char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
726 if (buf2 == NULL)
727 return False;
729 if (buffer) {
731 prs_debug(ps, depth, desc, "smb_io_buffer2");
732 depth++;
734 if(!prs_align(ps))
735 return False;
737 if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
738 return False;
739 if(!prs_uint32("undoc ", ps, depth, &buf2->undoc))
740 return False;
741 if(!prs_uint32("buf_len ", ps, depth, &buf2->buf_len))
742 return False;
744 /* buffer advanced by indicated length of string
745 NOT by searching for null-termination */
747 if(!prs_buffer2(True, "buffer ", ps, depth, buf2))
748 return False;
750 } else {
752 prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
753 depth++;
754 memset((char *)buf2, '\0', sizeof(*buf2));
757 return True;
760 /*******************************************************************
761 creates a UNISTR2 structure: sets up the buffer, too
762 ********************************************************************/
764 void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
766 if (buf != NULL) {
768 *ptr = 1;
769 init_unistr2(str, buf, strlen(buf)+1);
771 } else {
773 *ptr = 0;
774 init_unistr2(str, "", 0);
779 /*******************************************************************
780 Copies a UNISTR2 structure.
781 ********************************************************************/
783 void copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
786 /* set up string lengths. add one if string is not null-terminated */
787 str->uni_max_len = from->uni_max_len;
788 str->undoc = from->undoc;
789 str->uni_str_len = from->uni_str_len;
791 if (from->buffer == NULL)
792 return;
794 /* the string buffer is allocated to the maximum size
795 (the the length of the source string) to prevent
796 reallocation of memory. */
797 if (str->buffer == NULL) {
798 size_t len = from->uni_max_len * sizeof(uint16);
800 if (len < MAX_UNISTRLEN)
801 len = MAX_UNISTRLEN;
802 len *= sizeof(uint16);
804 str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
805 if ((str->buffer == NULL) && (len > 0 ))
807 smb_panic("copy_unistr2: talloc fail\n");
808 return;
812 /* copy the string */
813 memcpy(str->buffer, from->buffer, from->uni_max_len*sizeof(uint16));
816 /*******************************************************************
817 Creates a STRING2 structure.
818 ********************************************************************/
820 void init_string2(STRING2 *str, const char *buf, int max_len, int str_len)
822 int alloc_len = 0;
824 /* set up string lengths. */
825 str->str_max_len = max_len;
826 str->undoc = 0;
827 str->str_str_len = str_len;
829 /* store the string */
830 if(str_len != 0) {
831 if (str_len < MAX_STRINGLEN)
832 alloc_len = MAX_STRINGLEN;
833 str->buffer = talloc_zero(get_talloc_ctx(), alloc_len);
834 if (str->buffer == NULL)
835 smb_panic("init_string2: malloc fail\n");
836 memcpy(str->buffer, buf, str_len);
840 /*******************************************************************
841 Reads or writes a STRING2 structure.
842 XXXX NOTE: STRING2 structures need NOT be null-terminated.
843 the str_str_len member tells you how long the string is;
844 the str_max_len member tells you how large the buffer is.
845 ********************************************************************/
847 BOOL smb_io_string2(const char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
849 if (str2 == NULL)
850 return False;
852 if (buffer) {
854 prs_debug(ps, depth, desc, "smb_io_string2");
855 depth++;
857 if(!prs_align(ps))
858 return False;
860 if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
861 return False;
862 if(!prs_uint32("undoc ", ps, depth, &str2->undoc))
863 return False;
864 if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
865 return False;
867 /* buffer advanced by indicated length of string
868 NOT by searching for null-termination */
869 if(!prs_string2(True, "buffer ", ps, depth, str2))
870 return False;
872 } else {
874 prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
875 depth++;
876 memset((char *)str2, '\0', sizeof(*str2));
880 return True;
883 /*******************************************************************
884 Inits a UNISTR2 structure.
885 ********************************************************************/
887 void init_unistr2(UNISTR2 *str, const char *buf, size_t len)
889 ZERO_STRUCTP(str);
891 /* set up string lengths. */
892 str->uni_max_len = (uint32)len;
893 str->undoc = 0;
894 str->uni_str_len = (uint32)len;
896 if (len < MAX_UNISTRLEN)
897 len = MAX_UNISTRLEN;
898 len *= sizeof(uint16);
900 str->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
901 if ((str->buffer == NULL) && (len > 0))
903 smb_panic("init_unistr2: malloc fail\n");
904 return;
908 * don't move this test above ! The UNISTR2 must be initialized !!!
909 * jfm, 7/7/2001.
911 if (buf==NULL)
912 return;
914 rpcstr_push((char *)str->buffer, buf, len, STR_TERMINATE);
917 /**
918 * Inits a UNISTR2 structure.
919 * @param ctx talloc context to allocate string on
920 * @param str pointer to string to create
921 * @param buf UCS2 null-terminated buffer to init from
924 void init_unistr2_w(TALLOC_CTX *ctx, UNISTR2 *str, const smb_ucs2_t *buf)
926 uint32 len = strlen_w(buf);
927 uint32 max_len = len;
928 uint32 alloc_len;
930 ZERO_STRUCTP(str);
932 /* set up string lengths. */
933 str->uni_max_len = len;
934 str->undoc = 0;
935 str->uni_str_len = len;
937 if (max_len < MAX_UNISTRLEN)
938 max_len = MAX_UNISTRLEN;
940 alloc_len = (max_len + 1) * sizeof(uint16);
942 str->buffer = (uint16 *)talloc_zero(ctx, alloc_len);
943 if ((str->buffer == NULL) && (alloc_len > 0))
945 smb_panic("init_unistr2_w: malloc fail\n");
946 return;
950 * don't move this test above ! The UNISTR2 must be initialized !!!
951 * jfm, 7/7/2001.
953 if (buf==NULL)
954 return;
956 /* Yes, this is a strncpy( foo, bar, strlen(bar)) - but as
957 long as the buffer above is talloc()ed correctly then this
958 is the correct thing to do */
959 strncpy_w(str->buffer, buf, len + 1);
962 /*******************************************************************
963 Inits a UNISTR2 structure from a UNISTR
964 ********************************************************************/
965 void init_unistr2_from_unistr (UNISTR2 *to, const UNISTR *from)
968 uint32 i;
970 /* the destination UNISTR2 should never be NULL.
971 if it is it is a programming error */
973 /* if the source UNISTR is NULL, then zero out
974 the destination string and return */
975 ZERO_STRUCTP (to);
976 if ((from == NULL) || (from->buffer == NULL))
977 return;
979 /* get the length; UNISTR must be NULL terminated */
980 i = 0;
981 while ((from->buffer)[i]!='\0')
982 i++;
983 i++; /* one more to catch the terminating NULL */
984 /* is this necessary -- jerry? I need to think */
986 /* set up string lengths; uni_max_len is set to i+1
987 because we need to account for the final NULL termination */
988 to->uni_max_len = i;
989 to->undoc = 0;
990 to->uni_str_len = i;
992 /* allocate the space and copy the string buffer */
993 to->buffer = (uint16 *)talloc_zero(get_talloc_ctx(), sizeof(uint16)*(to->uni_str_len));
994 if (to->buffer == NULL)
995 smb_panic("init_unistr2_from_unistr: malloc fail\n");
996 memcpy(to->buffer, from->buffer, to->uni_max_len*sizeof(uint16));
998 return;
1002 /*******************************************************************
1003 Reads or writes a UNISTR2 structure.
1004 XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
1005 the uni_str_len member tells you how long the string is;
1006 the uni_max_len member tells you how large the buffer is.
1007 ********************************************************************/
1009 BOOL smb_io_unistr2(const char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
1011 if (uni2 == NULL)
1012 return False;
1014 if (buffer) {
1016 prs_debug(ps, depth, desc, "smb_io_unistr2");
1017 depth++;
1019 if(!prs_align(ps))
1020 return False;
1022 if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
1023 return False;
1024 if(!prs_uint32("undoc ", ps, depth, &uni2->undoc))
1025 return False;
1026 if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
1027 return False;
1029 /* buffer advanced by indicated length of string
1030 NOT by searching for null-termination */
1031 if(!prs_unistr2(True, "buffer ", ps, depth, uni2))
1032 return False;
1034 } else {
1036 prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
1037 depth++;
1038 memset((char *)uni2, '\0', sizeof(*uni2));
1042 return True;
1046 /*******************************************************************
1047 Reads or writes a UNISTR_ARRAY structure.
1048 ********************************************************************/
1049 BOOL smb_io_unistr_array(const char *desc, UNISTR_ARRAY *array, prs_struct *ps, int depth)
1051 int i;
1053 depth++;
1055 array->count = 0;
1057 if(!prs_uint32("ref_id", ps, depth, &array->ref_id))
1058 return False;
1060 if (! array->ref_id) {
1061 return True;
1064 if(!prs_uint32("count", ps, depth, &array->count))
1065 return False;
1067 if (array->count == 0) {
1068 return True;
1071 array->strings = talloc_zero(get_talloc_ctx(), array->count * sizeof(array->strings[0]));
1072 if (! array->strings) {
1073 return False;
1076 for (i=0;i<array->count;i++) {
1077 if(!prs_uint16("length", ps, depth, &array->strings[i].length))
1078 return False;
1079 if(!prs_uint16("size", ps, depth, &array->strings[i].size))
1080 return False;
1081 if(!prs_uint32("ref_id", ps, depth, &array->strings[i].ref_id))
1082 return False;
1085 for (i=0;i<array->count;i++) {
1086 if (! smb_io_unistr2("string", &array->strings[i].string, array->strings[i].ref_id, ps, depth))
1087 return False;
1090 return True;
1094 /*******************************************************************
1095 Inits a DOM_RID2 structure.
1096 ********************************************************************/
1098 void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
1100 rid2->type = type;
1101 rid2->rid = rid;
1102 rid2->rid_idx = idx;
1105 /*******************************************************************
1106 Reads or writes a DOM_RID2 structure.
1107 ********************************************************************/
1109 BOOL smb_io_dom_rid2(const char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
1111 if (rid2 == NULL)
1112 return False;
1114 prs_debug(ps, depth, desc, "smb_io_dom_rid2");
1115 depth++;
1117 if(!prs_align(ps))
1118 return False;
1120 if(!prs_uint8("type ", ps, depth, &rid2->type))
1121 return False;
1122 if(!prs_align(ps))
1123 return False;
1124 if(!prs_uint32("rid ", ps, depth, &rid2->rid))
1125 return False;
1126 if(!prs_uint32("rid_idx", ps, depth, &rid2->rid_idx))
1127 return False;
1129 return True;
1132 /*******************************************************************
1133 creates a DOM_RID3 structure.
1134 ********************************************************************/
1136 void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
1138 rid3->rid = rid;
1139 rid3->type1 = type;
1140 rid3->ptr_type = 0x1; /* non-zero, basically. */
1141 rid3->type2 = 0x1;
1142 rid3->unk = type;
1145 /*******************************************************************
1146 reads or writes a DOM_RID3 structure.
1147 ********************************************************************/
1149 BOOL smb_io_dom_rid3(const char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
1151 if (rid3 == NULL)
1152 return False;
1154 prs_debug(ps, depth, desc, "smb_io_dom_rid3");
1155 depth++;
1157 if(!prs_align(ps))
1158 return False;
1160 if(!prs_uint32("rid ", ps, depth, &rid3->rid))
1161 return False;
1162 if(!prs_uint32("type1 ", ps, depth, &rid3->type1))
1163 return False;
1164 if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
1165 return False;
1166 if(!prs_uint32("type2 ", ps, depth, &rid3->type2))
1167 return False;
1168 if(!prs_uint32("unk ", ps, depth, &rid3->unk))
1169 return False;
1171 return True;
1174 /*******************************************************************
1175 Inits a DOM_RID4 structure.
1176 ********************************************************************/
1178 void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
1180 rid4->unknown = unknown;
1181 rid4->attr = attr;
1182 rid4->rid = rid;
1185 /*******************************************************************
1186 Inits a DOM_CLNT_SRV structure.
1187 ********************************************************************/
1189 static void init_clnt_srv(DOM_CLNT_SRV *log, const char *logon_srv, const char *comp_name)
1191 DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
1193 if (logon_srv != NULL) {
1194 log->undoc_buffer = 1;
1195 init_unistr2(&log->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
1196 } else {
1197 log->undoc_buffer = 0;
1200 if (comp_name != NULL) {
1201 log->undoc_buffer2 = 1;
1202 init_unistr2(&log->uni_comp_name, comp_name, strlen(comp_name)+1);
1203 } else {
1204 log->undoc_buffer2 = 0;
1208 /*******************************************************************
1209 Inits or writes a DOM_CLNT_SRV structure.
1210 ********************************************************************/
1212 static BOOL smb_io_clnt_srv(const char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth)
1214 if (log == NULL)
1215 return False;
1217 prs_debug(ps, depth, desc, "smb_io_clnt_srv");
1218 depth++;
1220 if(!prs_align(ps))
1221 return False;
1223 if(!prs_uint32("undoc_buffer ", ps, depth, &log->undoc_buffer))
1224 return False;
1226 if (log->undoc_buffer != 0) {
1227 if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, log->undoc_buffer, ps, depth))
1228 return False;
1231 if(!prs_align(ps))
1232 return False;
1234 if(!prs_uint32("undoc_buffer2", ps, depth, &log->undoc_buffer2))
1235 return False;
1237 if (log->undoc_buffer2 != 0) {
1238 if(!smb_io_unistr2("unistr2", &log->uni_comp_name, log->undoc_buffer2, ps, depth))
1239 return False;
1242 return True;
1245 /*******************************************************************
1246 Inits a DOM_LOG_INFO structure.
1247 ********************************************************************/
1249 void init_log_info(DOM_LOG_INFO *log, const char *logon_srv, const char *acct_name,
1250 uint16 sec_chan, const char *comp_name)
1252 DEBUG(5,("make_log_info %d\n", __LINE__));
1254 log->undoc_buffer = 1;
1256 init_unistr2(&log->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
1257 init_unistr2(&log->uni_acct_name, acct_name, strlen(acct_name)+1);
1259 log->sec_chan = sec_chan;
1261 init_unistr2(&log->uni_comp_name, comp_name, strlen(comp_name)+1);
1264 /*******************************************************************
1265 Reads or writes a DOM_LOG_INFO structure.
1266 ********************************************************************/
1268 BOOL smb_io_log_info(const char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth)
1270 if (log == NULL)
1271 return False;
1273 prs_debug(ps, depth, desc, "smb_io_log_info");
1274 depth++;
1276 if(!prs_align(ps))
1277 return False;
1279 if(!prs_uint32("undoc_buffer", ps, depth, &log->undoc_buffer))
1280 return False;
1282 if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, True, ps, depth))
1283 return False;
1284 if(!smb_io_unistr2("unistr2", &log->uni_acct_name, True, ps, depth))
1285 return False;
1287 if(!prs_uint16("sec_chan", ps, depth, &log->sec_chan))
1288 return False;
1290 if(!smb_io_unistr2("unistr2", &log->uni_comp_name, True, ps, depth))
1291 return False;
1293 return True;
1296 /*******************************************************************
1297 Reads or writes a DOM_CHAL structure.
1298 ********************************************************************/
1300 BOOL smb_io_chal(const char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
1302 if (chal == NULL)
1303 return False;
1305 prs_debug(ps, depth, desc, "smb_io_chal");
1306 depth++;
1308 if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
1309 return False;
1311 return True;
1314 /*******************************************************************
1315 Reads or writes a DOM_CRED structure.
1316 ********************************************************************/
1318 BOOL smb_io_cred(const char *desc, DOM_CRED *cred, prs_struct *ps, int depth)
1320 if (cred == NULL)
1321 return False;
1323 prs_debug(ps, depth, desc, "smb_io_cred");
1324 depth++;
1326 if(!prs_align(ps))
1327 return False;
1329 if(!smb_io_chal ("", &cred->challenge, ps, depth))
1330 return False;
1332 if(!smb_io_utime("", &cred->timestamp, ps, depth))
1333 return False;
1335 return True;
1338 /*******************************************************************
1339 Inits a DOM_CLNT_INFO2 structure.
1340 ********************************************************************/
1342 void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
1343 const char *logon_srv, const char *comp_name,
1344 const DOM_CRED *clnt_cred)
1346 DEBUG(5,("make_clnt_info: %d\n", __LINE__));
1348 init_clnt_srv(&clnt->login, logon_srv, comp_name);
1350 if (clnt_cred != NULL) {
1351 clnt->ptr_cred = 1;
1352 memcpy(&clnt->cred, clnt_cred, sizeof(clnt->cred));
1353 } else {
1354 clnt->ptr_cred = 0;
1358 /*******************************************************************
1359 Reads or writes a DOM_CLNT_INFO2 structure.
1360 ********************************************************************/
1362 BOOL smb_io_clnt_info2(const char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
1364 if (clnt == NULL)
1365 return False;
1367 prs_debug(ps, depth, desc, "smb_io_clnt_info2");
1368 depth++;
1370 if(!prs_align(ps))
1371 return False;
1373 if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
1374 return False;
1376 if(!prs_align(ps))
1377 return False;
1379 if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
1380 return False;
1381 if(!smb_io_cred("", &clnt->cred, ps, depth))
1382 return False;
1384 return True;
1387 /*******************************************************************
1388 Inits a DOM_CLNT_INFO structure.
1389 ********************************************************************/
1391 void init_clnt_info(DOM_CLNT_INFO *clnt,
1392 const char *logon_srv, const char *acct_name,
1393 uint16 sec_chan, const char *comp_name,
1394 const DOM_CRED *cred)
1396 DEBUG(5,("make_clnt_info\n"));
1398 init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
1399 memcpy(&clnt->cred, cred, sizeof(clnt->cred));
1402 /*******************************************************************
1403 Reads or writes a DOM_CLNT_INFO structure.
1404 ********************************************************************/
1406 BOOL smb_io_clnt_info(const char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
1408 if (clnt == NULL)
1409 return False;
1411 prs_debug(ps, depth, desc, "smb_io_clnt_info");
1412 depth++;
1414 if(!prs_align(ps))
1415 return False;
1417 if(!smb_io_log_info("", &clnt->login, ps, depth))
1418 return False;
1419 if(!smb_io_cred("", &clnt->cred, ps, depth))
1420 return False;
1422 return True;
1425 /*******************************************************************
1426 Inits a DOM_LOGON_ID structure.
1427 ********************************************************************/
1429 void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high)
1431 DEBUG(5,("make_logon_id: %d\n", __LINE__));
1433 log->low = log_id_low;
1434 log->high = log_id_high;
1437 /*******************************************************************
1438 Reads or writes a DOM_LOGON_ID structure.
1439 ********************************************************************/
1441 BOOL smb_io_logon_id(const char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth)
1443 if (log == NULL)
1444 return False;
1446 prs_debug(ps, depth, desc, "smb_io_logon_id");
1447 depth++;
1449 if(!prs_align(ps))
1450 return False;
1452 if(!prs_uint32("low ", ps, depth, &log->low ))
1453 return False;
1454 if(!prs_uint32("high", ps, depth, &log->high))
1455 return False;
1457 return True;
1460 /*******************************************************************
1461 Inits an OWF_INFO structure.
1462 ********************************************************************/
1464 void init_owf_info(OWF_INFO *hash, const uint8 data[16])
1466 DEBUG(5,("init_owf_info: %d\n", __LINE__));
1468 if (data != NULL)
1469 memcpy(hash->data, data, sizeof(hash->data));
1470 else
1471 memset((char *)hash->data, '\0', sizeof(hash->data));
1474 /*******************************************************************
1475 Reads or writes an OWF_INFO structure.
1476 ********************************************************************/
1478 BOOL smb_io_owf_info(const char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
1480 if (hash == NULL)
1481 return False;
1483 prs_debug(ps, depth, desc, "smb_io_owf_info");
1484 depth++;
1486 if(!prs_align(ps))
1487 return False;
1489 if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
1490 return False;
1492 return True;
1495 /*******************************************************************
1496 Reads or writes a DOM_GID structure.
1497 ********************************************************************/
1499 BOOL smb_io_gid(const char *desc, DOM_GID *gid, prs_struct *ps, int depth)
1501 if (gid == NULL)
1502 return False;
1504 prs_debug(ps, depth, desc, "smb_io_gid");
1505 depth++;
1507 if(!prs_align(ps))
1508 return False;
1510 if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
1511 return False;
1512 if(!prs_uint32("attr ", ps, depth, &gid->attr))
1513 return False;
1515 return True;
1518 /*******************************************************************
1519 Reads or writes an POLICY_HND structure.
1520 ********************************************************************/
1522 BOOL smb_io_pol_hnd(const char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
1524 if (pol == NULL)
1525 return False;
1527 prs_debug(ps, depth, desc, "smb_io_pol_hnd");
1528 depth++;
1530 if(!prs_align(ps))
1531 return False;
1533 if(UNMARSHALLING(ps))
1534 ZERO_STRUCTP(pol);
1536 if (!prs_uint32("data1", ps, depth, &pol->data1))
1537 return False;
1538 if (!prs_uint32("data2", ps, depth, &pol->data2))
1539 return False;
1540 if (!prs_uint16("data3", ps, depth, &pol->data3))
1541 return False;
1542 if (!prs_uint16("data4", ps, depth, &pol->data4))
1543 return False;
1544 if(!prs_uint8s (False, "data5", ps, depth, pol->data5, sizeof(pol->data5)))
1545 return False;
1547 return True;
1550 /*******************************************************************
1551 Create a UNISTR3.
1552 ********************************************************************/
1554 void init_unistr3(UNISTR3 *str, const char *buf)
1556 size_t len;
1558 if (buf == NULL) {
1559 str->uni_str_len=0;
1560 str->str.buffer = NULL;
1561 return;
1564 len = strlen(buf) + 1;
1566 str->uni_str_len=len;
1568 if (len < MAX_UNISTRLEN)
1569 len = MAX_UNISTRLEN;
1571 len *= sizeof(uint16);
1573 str->str.buffer = (uint16 *)talloc_zero(get_talloc_ctx(), len);
1574 if (str->str.buffer == NULL)
1575 smb_panic("init_unistr3: malloc fail\n");
1577 rpcstr_push((char *)str->str.buffer, buf, len, STR_TERMINATE);
1580 /*******************************************************************
1581 Reads or writes a UNISTR3 structure.
1582 ********************************************************************/
1584 BOOL smb_io_unistr3(const char *desc, UNISTR3 *name, prs_struct *ps, int depth)
1586 if (name == NULL)
1587 return False;
1589 prs_debug(ps, depth, desc, "smb_io_unistr3");
1590 depth++;
1592 if(!prs_align(ps))
1593 return False;
1595 if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
1596 return False;
1598 /* don't know if len is specified by uni_str_len member... */
1599 /* assume unicode string is unicode-null-terminated, instead */
1601 if(!prs_unistr3(True, "unistr", name, ps, depth))
1602 return False;
1604 return True;
1608 /*******************************************************************
1609 Stream a uint64_struct
1610 ********************************************************************/
1611 BOOL prs_uint64(const char *name, prs_struct *ps, int depth, UINT64_S *data64)
1613 return prs_uint32(name, ps, depth+1, &data64->low) &&
1614 prs_uint32(name, ps, depth+1, &data64->high);
1617 /*******************************************************************
1618 reads or writes a BUFHDR2 structure.
1619 ********************************************************************/
1620 BOOL smb_io_bufhdr2(const char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
1622 prs_debug(ps, depth, desc, "smb_io_bufhdr2");
1623 depth++;
1625 prs_align(ps);
1626 prs_uint32("info_level", ps, depth, &(hdr->info_level));
1627 prs_uint32("length ", ps, depth, &(hdr->length ));
1628 prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
1630 return True;
1633 /*******************************************************************
1634 reads or writes a BUFFER4 structure.
1635 ********************************************************************/
1636 BOOL smb_io_buffer4(const char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
1638 prs_debug(ps, depth, desc, "smb_io_buffer4");
1639 depth++;
1641 prs_align(ps);
1642 prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
1644 if (buf4->buf_len > MAX_BUFFERLEN)
1646 buf4->buf_len = MAX_BUFFERLEN;
1649 prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
1651 return True;
1654 /*******************************************************************
1655 creates a UNIHDR structure.
1656 ********************************************************************/
1658 BOOL make_uni_hdr(UNIHDR *hdr, int len)
1660 if (hdr == NULL)
1662 return False;
1664 hdr->uni_str_len = 2 * len;
1665 hdr->uni_max_len = 2 * len;
1666 hdr->buffer = len != 0 ? 1 : 0;
1668 return True;
1671 /*******************************************************************
1672 creates a BUFHDR2 structure.
1673 ********************************************************************/
1674 BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
1676 hdr->info_level = info_level;
1677 hdr->length = length;
1678 hdr->buffer = buffer;
1680 return True;