r18793: Fix BE string handling in the auto-generated
[samba.git] / source3 / librpc / ndr / ndr_string.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    routines for marshalling/unmarshalling string types
5
6    Copyright (C) Andrew Tridgell 2003
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.
12    
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.
17    
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.
21 */
22
23 #include "includes.h"
24
25 /**
26   pull a general string from the wire
27 */
28 NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
29 {
30         char *as=NULL;
31         uint32_t len1, ofs, len2;
32         uint16_t len3;
33         int ret;
34         charset_t chset = CH_UTF16LE;
35         unsigned byte_mul = 2;
36         unsigned flags = ndr->flags;
37         unsigned c_len_term = 0;
38
39         if (!(ndr_flags & NDR_SCALARS)) {
40                 return NT_STATUS_OK;
41         }
42
43         if (NDR_BE(ndr)) {
44                 chset = CH_UTF16BE;
45         }
46
47         if (flags & LIBNDR_FLAG_STR_ASCII) {
48                 chset = CH_DOS;
49                 byte_mul = 1;
50                 flags &= ~LIBNDR_FLAG_STR_ASCII;
51         }
52
53         if (flags & LIBNDR_FLAG_STR_UTF8) {
54                 chset = CH_UTF8;
55                 byte_mul = 1;
56                 flags &= ~LIBNDR_FLAG_STR_UTF8;
57         }
58
59         flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
60         if (flags & LIBNDR_FLAG_STR_CHARLEN) {
61                 c_len_term = 1;
62                 flags &= ~LIBNDR_FLAG_STR_CHARLEN;
63         }
64
65         switch (flags & LIBNDR_STRING_FLAGS) {
66         case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
67         case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
68                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
69                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ofs));
70                 if (ofs != 0) {
71                         return ndr_pull_error(ndr, NDR_ERR_STRING, "non-zero array offset with string flags 0x%x\n",
72                                               ndr->flags & LIBNDR_STRING_FLAGS);
73                 }
74                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len2));
75                 if (len2 > len1) {
76                         return ndr_pull_error(ndr, NDR_ERR_STRING, 
77                                               "Bad string lengths len1=%u ofs=%u len2=%u\n", 
78                                               len1, ofs, len2);
79                 }
80                 NDR_PULL_NEED_BYTES(ndr, (len2 + c_len_term)*byte_mul);
81                 if (len2 == 0) {
82                         as = talloc_strdup(ndr->current_mem_ctx, "");
83                 } else {
84                         ret = convert_string_talloc(ndr->current_mem_ctx,
85                                                     chset, CH_UNIX, 
86                                                     ndr->data+ndr->offset, 
87                                                     (len2 + c_len_term)*byte_mul,
88                                                     &as, True);
89                         if (ret == -1) {
90                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
91                                                       "Bad character conversion");
92                         }
93                 }
94                 NDR_CHECK(ndr_pull_advance(ndr, (len2 + c_len_term)*byte_mul));
95
96                 if (len1 != len2) {
97                         DEBUG(6,("len1[%u] != len2[%u] '%s'\n", len1, len2, as));
98                 }
99
100                 /* this is a way of detecting if a string is sent with the wrong
101                    termination */
102                 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
103                         if (strlen(as) < (len2 + c_len_term)) {
104                                 DEBUG(6,("short string '%s'\n", as));
105                         }
106                 } else {
107                         if (strlen(as) == (len2 + c_len_term)) {
108                                 DEBUG(6,("long string '%s'\n", as));
109                         }
110                 }
111                 *s = as;
112                 break;
113
114         case LIBNDR_FLAG_STR_SIZE4:
115         case LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
116                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
117                 NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);
118                 if (len1 == 0) {
119                         as = talloc_strdup(ndr->current_mem_ctx, "");
120                 } else {
121                         ret = convert_string_talloc(ndr->current_mem_ctx,
122                                                     chset, CH_UNIX, 
123                                                     ndr->data+ndr->offset, 
124                                                     (len1 + c_len_term)*byte_mul,
125                                                     &as, False);
126                         if (ret == -1) {
127                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
128                                                       "Bad character conversion");
129                         }
130                 }
131                 NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));
132
133                 /* this is a way of detecting if a string is sent with the wrong
134                    termination */
135                 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
136                         if (strlen(as) < (len1 + c_len_term)) {
137                                 DEBUG(6,("short string '%s'\n", as));
138                         }
139                 } else {
140                         if (strlen(as) == (len1 + c_len_term)) {
141                                 DEBUG(6,("long string '%s'\n", as));
142                         }
143                 }
144                 *s = as;
145                 break;
146
147         case LIBNDR_FLAG_STR_LEN4:
148         case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_NOTERM:
149                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ofs));
150                 if (ofs != 0) {
151                         return ndr_pull_error(ndr, NDR_ERR_STRING, "non-zero array offset with string flags 0x%x\n",
152                                               ndr->flags & LIBNDR_STRING_FLAGS);
153                 }
154                 NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
155                 NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);
156                 if (len1 == 0) {
157                         as = talloc_strdup(ndr->current_mem_ctx, "");
158                 } else {
159                         ret = convert_string_talloc(ndr->current_mem_ctx,
160                                                     chset, CH_UNIX, 
161                                                     ndr->data+ndr->offset, 
162                                                     (len1 + c_len_term)*byte_mul,
163                                                     &as, False);
164                         if (ret == -1) {
165                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
166                                                       "Bad character conversion");
167                         }
168                 }
169                 NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));
170
171                 /* this is a way of detecting if a string is sent with the wrong
172                    termination */
173                 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
174                         if (strlen(as) < (len1 + c_len_term)) {
175                                 DEBUG(6,("short string '%s'\n", as));
176                         }
177                 } else {
178                         if (strlen(as) == (len1 + c_len_term)) {
179                                 DEBUG(6,("long string '%s'\n", as));
180                         }
181                 }
182                 *s = as;
183                 break;
184
185
186         case LIBNDR_FLAG_STR_SIZE2:
187         case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM:
188                 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));
189                 NDR_PULL_NEED_BYTES(ndr, (len3 + c_len_term)*byte_mul);
190                 if (len3 == 0) {
191                         as = talloc_strdup(ndr->current_mem_ctx, "");
192                 } else {
193                         ret = convert_string_talloc(ndr->current_mem_ctx,
194                                                     chset, CH_UNIX, 
195                                                     ndr->data+ndr->offset, 
196                                                     (len3 + c_len_term)*byte_mul,
197                                                     &as, False);
198                         if (ret == -1) {
199                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
200                                                       "Bad character conversion");
201                         }
202                 }
203                 NDR_CHECK(ndr_pull_advance(ndr, (len3 + c_len_term)*byte_mul));
204
205                 /* this is a way of detecting if a string is sent with the wrong
206                    termination */
207                 if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
208                         if (strlen(as) < (len3 + c_len_term)) {
209                                 DEBUG(6,("short string '%s'\n", as));
210                         }
211                 } else {
212                         if (strlen(as) == (len3 + c_len_term)) {
213                                 DEBUG(6,("long string '%s'\n", as));
214                         }
215                 }
216                 *s = as;
217                 break;
218
219         case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_BYTESIZE:
220                 NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));
221                 NDR_PULL_NEED_BYTES(ndr, len3);
222                 if (len3 == 0) {
223                         as = talloc_strdup(ndr->current_mem_ctx, "");
224                 } else {
225                         ret = convert_string_talloc(ndr->current_mem_ctx,
226                                                     chset, CH_UNIX, 
227                                                     ndr->data+ndr->offset, 
228                                                     len3, &as, False);
229                         if (ret == -1) {
230                                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
231                                                       "Bad character conversion");
232                         }
233                 }
234                 NDR_CHECK(ndr_pull_advance(ndr, len3));
235                 *s = as;
236                 break;
237
238         case LIBNDR_FLAG_STR_NULLTERM:
239                 if (byte_mul == 1) {
240                         len1 = ascii_len_n((const char *)(ndr->data+ndr->offset), ndr->data_size - ndr->offset);
241                 } else {
242                         len1 = utf16_len_n(ndr->data+ndr->offset, ndr->data_size - ndr->offset);
243                 }
244                 ret = convert_string_talloc(ndr->current_mem_ctx,
245                                             chset, CH_UNIX, 
246                                             ndr->data+ndr->offset, 
247                                             len1, &as, False);
248                 if (ret == -1) {
249                         return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
250                                               "Bad character conversion");
251                 }
252                 NDR_CHECK(ndr_pull_advance(ndr, len1));
253                 *s = as;
254                 break;
255
256         case LIBNDR_FLAG_STR_FIXLEN15:
257         case LIBNDR_FLAG_STR_FIXLEN32:
258                 len1 = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
259                 NDR_PULL_NEED_BYTES(ndr, len1*byte_mul);
260                 ret = convert_string_talloc(ndr->current_mem_ctx,
261                                             chset, CH_UNIX, 
262                                             ndr->data+ndr->offset, 
263                                             len1*byte_mul, &as, False);
264                 if (ret == -1) {
265                         return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
266                                               "Bad character conversion");
267                 }
268                 NDR_CHECK(ndr_pull_advance(ndr, len1*byte_mul));
269                 *s = as;
270                 break;
271
272         default:
273                 return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
274                                       ndr->flags & LIBNDR_STRING_FLAGS);
275         }
276
277         return NT_STATUS_OK;
278 }
279
280
281 /**
282   push a general string onto the wire
283 */
284 NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
285 {
286         ssize_t s_len, c_len, d_len;
287         charset_t chset = CH_UTF16LE;
288         unsigned flags = ndr->flags;
289         unsigned byte_mul = 2;
290         uint8_t *dest = NULL;
291
292         if (!(ndr_flags & NDR_SCALARS)) {
293                 return NT_STATUS_OK;
294         }
295
296         if (NDR_BE(ndr)) {
297                 chset = CH_UTF16BE;
298         }
299         
300         s_len = s?strlen(s):0;
301
302         if (flags & LIBNDR_FLAG_STR_ASCII) {
303                 chset = CH_DOS;
304                 byte_mul = 1;
305                 flags &= ~LIBNDR_FLAG_STR_ASCII;
306         }
307
308         if (flags & LIBNDR_FLAG_STR_UTF8) {
309                 chset = CH_UTF8;
310                 byte_mul = 1;
311                 flags &= ~LIBNDR_FLAG_STR_UTF8;
312         }
313
314         flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
315
316         if (!(flags & 
317               (LIBNDR_FLAG_STR_NOTERM |
318                LIBNDR_FLAG_STR_FIXLEN15 |
319                LIBNDR_FLAG_STR_FIXLEN32))) {
320                 s_len++;
321         }
322         d_len = convert_string_talloc(ndr, CH_UNIX, chset, s, s_len, &dest,
323                                       False);
324         if (d_len == -1) {
325                 return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
326                                       "Bad character conversion");
327         }
328
329         if (flags & LIBNDR_FLAG_STR_BYTESIZE) {
330                 c_len = d_len;
331                 flags &= ~LIBNDR_FLAG_STR_BYTESIZE;
332         } else if (flags & LIBNDR_FLAG_STR_CHARLEN) {
333                 c_len = (d_len / byte_mul)-1;
334                 flags &= ~LIBNDR_FLAG_STR_CHARLEN;
335         } else {
336                 c_len = d_len / byte_mul;
337         }
338
339         switch ((flags & LIBNDR_STRING_FLAGS) & ~LIBNDR_FLAG_STR_NOTERM) {
340         case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
341                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
342                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
343                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
344                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
345                 break;
346
347         case LIBNDR_FLAG_STR_LEN4:
348                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
349                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
350                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
351                 break;
352
353         case LIBNDR_FLAG_STR_SIZE4:
354                 NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
355                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
356                 break;
357
358         case LIBNDR_FLAG_STR_SIZE2:
359                 NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, c_len));
360                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
361                 break;
362
363         case LIBNDR_FLAG_STR_NULLTERM:
364                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
365                 break;
366
367         case LIBNDR_FLAG_STR_FIXLEN15:
368         case LIBNDR_FLAG_STR_FIXLEN32: {
369                 ssize_t fix_len = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
370                 uint32_t pad_len = fix_len - d_len;
371                 if (d_len > fix_len) {
372                         return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
373                                               "Bad character conversion");
374                 }
375                 NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
376                 if (pad_len != 0) {
377                         NDR_CHECK(ndr_push_zero(ndr, pad_len));
378                 }
379                 break;
380         }
381
382         default:
383                 return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
384                                       ndr->flags & LIBNDR_STRING_FLAGS);
385         }
386
387         talloc_free(dest);
388
389         return NT_STATUS_OK;
390 }
391
392 /**
393   push a general string onto the wire
394 */
395 size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
396 {
397         size_t c_len;
398         unsigned flags = ndr->flags;
399         unsigned byte_mul = 2;
400         unsigned c_len_term = 1;
401
402         if (flags & LIBNDR_FLAG_STR_FIXLEN32) {
403                 return 32;
404         }
405         if (flags & LIBNDR_FLAG_STR_FIXLEN15) {
406                 return 15;
407         }
408         
409         c_len = s?strlen(s):0;
410
411         if (flags & (LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_UTF8)) {
412                 byte_mul = 1;
413         }
414
415         if (flags & LIBNDR_FLAG_STR_NOTERM) {
416                 c_len_term = 0;
417         }
418
419         c_len = c_len + c_len_term;
420
421         if (flags & LIBNDR_FLAG_STR_BYTESIZE) {
422                 c_len = c_len * byte_mul;
423         }
424
425         return c_len;
426 }
427
428 void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
429 {
430         if (s) {
431                 ndr->print(ndr, "%-25s: '%s'", name, s);
432         } else {
433                 ndr->print(ndr, "%-25s: NULL", name);
434         }
435 }
436
437 uint32_t ndr_size_string(int ret, const char * const* string, int flags) 
438 {
439         /* FIXME: Is this correct for all strings ? */
440         if(!(*string)) return ret;
441         return ret+strlen(*string)+1;
442 }
443
444 /**
445   pull a general string array from the wire
446 */
447 NTSTATUS ndr_pull_string_array(struct ndr_pull *ndr, int ndr_flags, const char ***_a)
448 {
449         const char **a = *_a;
450         uint32_t count;
451
452         if (!(ndr_flags & NDR_SCALARS)) {
453                 return NT_STATUS_OK;
454         }
455
456         for (count = 0;; count++) {
457                 TALLOC_CTX *tmp_ctx;
458                 const char *s = NULL;
459                 a = talloc_realloc(ndr->current_mem_ctx, a, const char *, count + 2);
460                 NT_STATUS_HAVE_NO_MEMORY(a);
461                 a[count]   = NULL;
462                 a[count+1]   = NULL;
463
464                 tmp_ctx = ndr->current_mem_ctx;
465                 ndr->current_mem_ctx = a;
466                 NDR_CHECK(ndr_pull_string(ndr, ndr_flags, &s));
467                 ndr->current_mem_ctx = tmp_ctx;
468                 if (strcmp("", s)==0) {
469                         a[count] = NULL;
470                         break;
471                 } else {
472                         a[count] = s;
473                 }
474         }
475
476         *_a =a;
477         return NT_STATUS_OK;
478 }
479
480 /**
481   push a general string array onto the wire
482 */
483 NTSTATUS ndr_push_string_array(struct ndr_push *ndr, int ndr_flags, const char **a)
484 {
485         uint32_t count;
486
487         if (!(ndr_flags & NDR_SCALARS)) {
488                 return NT_STATUS_OK;
489         }
490
491         for (count = 0; a && a[count]; count++) {
492                 NDR_CHECK(ndr_push_string(ndr, ndr_flags, a[count]));
493         }
494
495         NDR_CHECK(ndr_push_string(ndr, ndr_flags, ""));
496
497         return NT_STATUS_OK;
498 }
499
500 void ndr_print_string_array(struct ndr_print *ndr, const char *name, const char **a)
501 {
502         uint32_t count;
503         uint32_t i;
504
505         for (count = 0; a && a[count]; count++) {}
506
507         ndr->print(ndr, "%s: ARRAY(%d)", name, count);
508         ndr->depth++;
509         for (i=0;i<count;i++) {
510                 char *idx=NULL;
511                 asprintf(&idx, "[%d]", i);
512                 if (idx) {
513                         ndr_print_string(ndr, idx, a[i]);
514                         free(idx);
515                 }
516         }
517         ndr->depth--;
518 }
519
520 /**
521  * Return number of elements in a string including the last (zeroed) element 
522  */
523 uint32_t ndr_string_length(const void *_var, uint32_t element_size)
524 {
525         uint32_t i;
526         uint8_t zero[4] = {0,0,0,0};
527         const char *var = (const char *)_var;
528
529         for (i = 0; memcmp(var+i*element_size,zero,element_size) != 0; i++);
530
531         return i+1;
532 }
533
534 NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size)
535 {
536         uint32_t i;
537         struct ndr_pull_save save_offset;
538
539         ndr_pull_save(ndr, &save_offset);
540         ndr_pull_advance(ndr, (count - 1) * element_size);
541         NDR_PULL_NEED_BYTES(ndr, element_size);
542
543         for (i = 0; i < element_size; i++) {
544                  if (ndr->data[ndr->offset+i] != 0) {
545                         ndr_pull_restore(ndr, &save_offset);
546
547                         return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "String terminator not present or outside string boundaries");
548                  }
549         }
550
551         ndr_pull_restore(ndr, &save_offset);
552
553         return NT_STATUS_OK;
554 }
555
556 NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var, uint32_t length, uint8_t byte_mul, charset_t chset)
557 {
558         int ret;
559         if (length == 0) {
560                 *var = talloc_strdup(ndr->current_mem_ctx, "");
561                 return NT_STATUS_OK;
562         }
563
564         if (NDR_BE(ndr) && chset == CH_UTF16) {
565                 chset = CH_UTF16BE;
566         }
567
568         NDR_PULL_NEED_BYTES(ndr, length*byte_mul);
569
570         ret = convert_string_talloc(ndr->current_mem_ctx,
571                                     chset, CH_UNIX, 
572                                     ndr->data+ndr->offset, 
573                                     length*byte_mul,
574                                     var, False);
575         if (ret == -1) {
576                 return ndr_pull_error(ndr, NDR_ERR_CHARCNV, 
577                                       "Bad character conversion");
578         }
579         NDR_CHECK(ndr_pull_advance(ndr, length*byte_mul));
580
581         return NT_STATUS_OK;
582 }
583
584 NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var,
585                           uint32_t length, uint8_t byte_mul, charset_t chset)
586 {
587         ssize_t ret, required;
588
589         if (NDR_BE(ndr) && chset == CH_UTF16) {
590                 chset = CH_UTF16BE;
591         }
592
593         required = byte_mul * length;
594         
595         NDR_PUSH_NEED_BYTES(ndr, required);
596         ret = convert_string(CH_UNIX, chset, 
597                              var, strlen(var),
598                              ndr->data+ndr->offset, required, False);
599         if (ret == -1) {
600                 return ndr_push_error(ndr, NDR_ERR_CHARCNV, 
601                                       "Bad character conversion");
602         }
603
604         /* Make sure the remaining part of the string is filled with zeroes */
605         if (ret < required) {
606                 memset(ndr->data+ndr->offset+ret, 0, required-ret);
607         }
608
609         ndr->offset += required;
610
611         return NT_STATUS_OK;
612 }
613
614 /* Return number of elements in a string in the specified charset */
615 uint32_t ndr_charset_length(const void *var, int chset)
616 {
617         /* FIXME: Treat special chars special here, taking chset into account */
618         /* Also include 0 byte */
619         return strlen((const char *)var)+1;
620 }