root/libcli/nbt/nbtname.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ndr_print_nbt_string
  2. ndr_pull_component
  3. ndr_pull_nbt_string
  4. ndr_push_nbt_string
  5. decompress_name
  6. compress_name
  7. ndr_pull_nbt_name
  8. ndr_push_nbt_name
  9. nbt_name_dup
  10. nbt_name_to_blob
  11. nbt_name_from_blob
  12. nbt_choose_called_name
  13. nbt_hex_encode
  14. nbt_name_string
  15. ndr_pull_wrepl_nbt_name
  16. ndr_push_wrepl_nbt_name
  17. ndr_print_wrepl_nbt_name
  18. ndr_push_nbt_res_rec

   1 /*
   2    Unix SMB/CIFS implementation.
   3 
   4    manipulate nbt name structures
   5 
   6    Copyright (C) Andrew Tridgell 2005
   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 3 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, see <http://www.gnu.org/licenses/>.
  20 */
  21 
  22 /*
  23   see rfc1002 for the detailed format of compressed names
  24 */
  25 
  26 #include "includes.h"
  27 #include "librpc/gen_ndr/ndr_nbt.h"
  28 #include "librpc/gen_ndr/ndr_misc.h"
  29 #include "system/locale.h"
  30 
  31 /* don't allow an unlimited number of name components */
  32 #define MAX_COMPONENTS 10
  33 
  34 /**
  35   print a nbt string
  36 */
  37 _PUBLIC_ void ndr_print_nbt_string(struct ndr_print *ndr, const char *name, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
  38 {
  39         ndr_print_string(ndr, name, s);
  40 }
  41 
  42 /*
  43   pull one component of a nbt_string
  44 */
  45 static enum ndr_err_code ndr_pull_component(struct ndr_pull *ndr,
     /* [<][>][^][v][top][bottom][index][help] */
  46                                             uint8_t **component,
  47                                             uint32_t *offset,
  48                                             uint32_t *max_offset)
  49 {
  50         uint8_t len;
  51         uint_t loops = 0;
  52         while (loops < 5) {
  53                 if (*offset >= ndr->data_size) {
  54                         return ndr_pull_error(ndr, NDR_ERR_STRING,
  55                                               "BAD NBT NAME component");
  56                 }
  57                 len = ndr->data[*offset];
  58                 if (len == 0) {
  59                         *offset += 1;
  60                         *max_offset = MAX(*max_offset, *offset);
  61                         *component = NULL;
  62                         return NDR_ERR_SUCCESS;
  63                 }
  64                 if ((len & 0xC0) == 0xC0) {
  65                         /* its a label pointer */
  66                         if (1 + *offset >= ndr->data_size) {
  67                                 return ndr_pull_error(ndr, NDR_ERR_STRING,
  68                                                       "BAD NBT NAME component");
  69                         }
  70                         *max_offset = MAX(*max_offset, *offset + 2);
  71                         *offset = ((len&0x3F)<<8) | ndr->data[1 + *offset];
  72                         *max_offset = MAX(*max_offset, *offset);
  73                         loops++;
  74                         continue;
  75                 }
  76                 if ((len & 0xC0) != 0) {
  77                         /* its a reserved length field */
  78                         return ndr_pull_error(ndr, NDR_ERR_STRING,
  79                                               "BAD NBT NAME component");
  80                 }
  81                 if (*offset + len + 2 > ndr->data_size) {
  82                         return ndr_pull_error(ndr, NDR_ERR_STRING,
  83                                               "BAD NBT NAME component");
  84                 }
  85                 *component = (uint8_t*)talloc_strndup(ndr, (const char *)&ndr->data[1 + *offset], len);
  86                 NDR_ERR_HAVE_NO_MEMORY(*component);
  87                 *offset += len + 1;
  88                 *max_offset = MAX(*max_offset, *offset);
  89                 return NDR_ERR_SUCCESS;
  90         }
  91 
  92         /* too many pointers */
  93         return ndr_pull_error(ndr, NDR_ERR_STRING, "BAD NBT NAME component");
  94 }
  95 
  96 /**
  97   pull a nbt_string from the wire
  98 */
  99 _PUBLIC_ enum ndr_err_code ndr_pull_nbt_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
     /* [<][>][^][v][top][bottom][index][help] */
 100 {
 101         uint32_t offset = ndr->offset;
 102         uint32_t max_offset = offset;
 103         unsigned num_components;
 104         char *name;
 105 
 106         if (!(ndr_flags & NDR_SCALARS)) {
 107                 return NDR_ERR_SUCCESS;
 108         }
 109 
 110         name = NULL;
 111 
 112         /* break up name into a list of components */
 113         for (num_components=0;num_components<MAX_COMPONENTS;num_components++) {
 114                 uint8_t *component = NULL;
 115                 NDR_CHECK(ndr_pull_component(ndr, &component, &offset, &max_offset));
 116                 if (component == NULL) break;
 117                 if (name) {
 118                         name = talloc_asprintf_append_buffer(name, ".%s", component);
 119                         NDR_ERR_HAVE_NO_MEMORY(name);
 120                 } else {
 121                         name = (char *)component;
 122                 }
 123         }
 124         if (num_components == MAX_COMPONENTS) {
 125                 return ndr_pull_error(ndr, NDR_ERR_STRING,
 126                                       "BAD NBT NAME too many components");
 127         }
 128         if (num_components == 0) {
 129                 name = talloc_strdup(ndr, "");
 130                 NDR_ERR_HAVE_NO_MEMORY(name);
 131         }
 132 
 133         (*s) = name;
 134         ndr->offset = max_offset;
 135 
 136         return NDR_ERR_SUCCESS;
 137 }
 138 
 139 /**
 140   push a nbt string to the wire
 141 */
 142 _PUBLIC_ enum ndr_err_code ndr_push_nbt_string(struct ndr_push *ndr, int ndr_flags, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 143 {
 144         if (!(ndr_flags & NDR_SCALARS)) {
 145                 return NDR_ERR_SUCCESS;
 146         }
 147 
 148         while (s && *s) {
 149                 enum ndr_err_code ndr_err;
 150                 char *compname;
 151                 size_t complen;
 152                 uint32_t offset;
 153 
 154                 /* see if we have pushed the remaing string allready,
 155                  * if so we use a label pointer to this string
 156                  */
 157                 ndr_err = ndr_token_retrieve_cmp_fn(&ndr->nbt_string_list, s, &offset, (comparison_fn_t)strcmp, false);
 158                 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 159                         uint8_t b[2];
 160 
 161                         if (offset > 0x3FFF) {
 162                                 return ndr_push_error(ndr, NDR_ERR_STRING,
 163                                                       "offset for nbt string label pointer %u[%08X] > 0x00003FFF",
 164                                                       offset, offset);
 165                         }
 166 
 167                         b[0] = 0xC0 | (offset>>8);
 168                         b[1] = (offset & 0xFF);
 169 
 170                         return ndr_push_bytes(ndr, b, 2);
 171                 }
 172 
 173                 complen = strcspn(s, ".");
 174 
 175                 /* we need to make sure the length fits into 6 bytes */
 176                 if (complen >= 0x3F) {
 177                         return ndr_push_error(ndr, NDR_ERR_STRING,
 178                                               "component length %u[%08X] > 0x00003F",
 179                                               (unsigned)complen, (unsigned)complen);
 180                 }
 181 
 182                 compname = talloc_asprintf(ndr, "%c%*.*s",
 183                                                 (unsigned char)complen,
 184                                                 (unsigned char)complen,
 185                                                 (unsigned char)complen, s);
 186                 NDR_ERR_HAVE_NO_MEMORY(compname);
 187 
 188                 /* remember the current componemt + the rest of the string
 189                  * so it can be reused later
 190                  */
 191                 NDR_CHECK(ndr_token_store(ndr, &ndr->nbt_string_list, s, ndr->offset));
 192 
 193                 /* push just this component into the blob */
 194                 NDR_CHECK(ndr_push_bytes(ndr, (const uint8_t *)compname, complen+1));
 195                 talloc_free(compname);
 196 
 197                 s += complen;
 198                 if (*s == '.') s++;
 199         }
 200 
 201         /* if we reach the end of the string and have pushed the last component
 202          * without using a label pointer, we need to terminate the string
 203          */
 204         return ndr_push_bytes(ndr, (const uint8_t *)"", 1);
 205 }
 206 
 207 
 208 /*
 209   decompress a 'compressed' name component
 210  */
 211 static bool decompress_name(char *name, enum nbt_name_type *type)
     /* [<][>][^][v][top][bottom][index][help] */
 212 {
 213         int i;
 214         for (i=0;name[2*i];i++) {
 215                 uint8_t c1 = name[2*i];
 216                 uint8_t c2 = name[1+(2*i)];
 217                 if (c1 < 'A' || c1 > 'P' ||
 218                     c2 < 'A' || c2 > 'P') {
 219                         return false;
 220                 }
 221                 name[i] = ((c1-'A')<<4) | (c2-'A');
 222         }
 223         name[i] = 0;
 224         if (i == 16) {
 225                 *type = (enum nbt_name_type)(name[15]);
 226                 name[15] = 0;
 227                 i--;
 228         } else {
 229                 *type = NBT_NAME_CLIENT;
 230         }
 231 
 232         /* trim trailing spaces */
 233         for (;i>0 && name[i-1]==' ';i--) {
 234                 name[i-1] = 0;
 235         }
 236 
 237         return true;
 238 }
 239 
 240 
 241 /*
 242   compress a name component
 243  */
 244 static uint8_t *compress_name(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 245                               const uint8_t *name, enum nbt_name_type type)
 246 {
 247         uint8_t *cname;
 248         int i;
 249         uint8_t pad_char;
 250 
 251         if (strlen((const char *)name) > 15) {
 252                 return NULL;
 253         }
 254 
 255         cname = talloc_array(mem_ctx, uint8_t, 33);
 256         if (cname == NULL) return NULL;
 257 
 258         for (i=0;name[i];i++) {
 259                 cname[2*i]   = 'A' + (name[i]>>4);
 260                 cname[1+2*i] = 'A' + (name[i]&0xF);
 261         }
 262         if (strcmp((const char *)name, "*") == 0) {
 263                 pad_char = 0;
 264         } else {
 265                 pad_char = ' ';
 266         }
 267         for (;i<15;i++) {
 268                 cname[2*i]   = 'A' + (pad_char>>4);
 269                 cname[1+2*i] = 'A' + (pad_char&0xF);
 270         }
 271 
 272         pad_char = type;
 273         cname[2*i]   = 'A' + (pad_char>>4);
 274         cname[1+2*i] = 'A' + (pad_char&0xF);
 275 
 276         cname[32] = 0;
 277         return cname;
 278 }
 279 
 280 
 281 /**
 282   pull a nbt name from the wire
 283 */
 284 _PUBLIC_ enum ndr_err_code ndr_pull_nbt_name(struct ndr_pull *ndr, int ndr_flags, struct nbt_name *r)
     /* [<][>][^][v][top][bottom][index][help] */
 285 {
 286         uint8_t *scope;
 287         char *cname;
 288         const char *s;
 289         bool ok;
 290 
 291         if (!(ndr_flags & NDR_SCALARS)) {
 292                 return NDR_ERR_SUCCESS;
 293         }
 294 
 295         NDR_CHECK(ndr_pull_nbt_string(ndr, ndr_flags, &s));
 296 
 297         scope = (uint8_t *)strchr(s, '.');
 298         if (scope) {
 299                 *scope = 0;
 300                 r->scope = talloc_strdup(ndr->current_mem_ctx, (const char *)&scope[1]);
 301                 NDR_ERR_HAVE_NO_MEMORY(r->scope);
 302         } else {
 303                 r->scope = NULL;
 304         }
 305 
 306         cname = discard_const_p(char, s);
 307 
 308         /* the first component is limited to 16 bytes in the DOS charset,
 309            which is 32 in the 'compressed' form */
 310         if (strlen(cname) > 32) {
 311                 return ndr_pull_error(ndr, NDR_ERR_STRING,
 312                                       "NBT NAME cname > 32");
 313         }
 314 
 315         /* decompress the first component */
 316         ok = decompress_name(cname, &r->type);
 317         if (!ok) {
 318                 return ndr_pull_error(ndr, NDR_ERR_STRING,
 319                                       "NBT NAME failed to decompress");
 320         }
 321 
 322         r->name = talloc_strdup(ndr->current_mem_ctx, cname);
 323         NDR_ERR_HAVE_NO_MEMORY(r->name);
 324 
 325         talloc_free(cname);
 326 
 327         return NDR_ERR_SUCCESS;
 328 }
 329 
 330 /**
 331   push a nbt name to the wire
 332 */
 333 _PUBLIC_ enum ndr_err_code ndr_push_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r)
     /* [<][>][^][v][top][bottom][index][help] */
 334 {
 335         uint8_t *cname, *fullname;
 336         enum ndr_err_code ndr_err;
 337 
 338         if (!(ndr_flags & NDR_SCALARS)) {
 339                 return NDR_ERR_SUCCESS;
 340         }
 341 
 342         if (strlen(r->name) > 15) {
 343                 return ndr_push_error(ndr, NDR_ERR_STRING,
 344                                       "nbt_name longer as 15 chars: %s",
 345                                       r->name);
 346         }
 347 
 348         cname = compress_name(ndr, (const uint8_t *)r->name, r->type);
 349         NDR_ERR_HAVE_NO_MEMORY(cname);
 350 
 351         if (r->scope) {
 352                 fullname = (uint8_t *)talloc_asprintf(ndr, "%s.%s", cname, r->scope);
 353                 NDR_ERR_HAVE_NO_MEMORY(fullname);
 354                 talloc_free(cname);
 355         } else {
 356                 fullname = cname;
 357         }
 358 
 359         ndr_err = ndr_push_nbt_string(ndr, ndr_flags, (const char *)fullname);
 360 
 361         return ndr_err;
 362 }
 363 
 364 
 365 /**
 366   copy a nbt name structure
 367 */
 368 _PUBLIC_ NTSTATUS nbt_name_dup(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name *newname)
     /* [<][>][^][v][top][bottom][index][help] */
 369 {
 370         *newname = *name;
 371         newname->name = talloc_strdup(mem_ctx, newname->name);
 372         NT_STATUS_HAVE_NO_MEMORY(newname->name);
 373         newname->scope = talloc_strdup(mem_ctx, newname->scope);
 374         if (name->scope) {
 375                 NT_STATUS_HAVE_NO_MEMORY(newname->scope);
 376         }
 377         return NT_STATUS_OK;
 378 }
 379 
 380 /**
 381   push a nbt name into a blob
 382 */
 383 _PUBLIC_ NTSTATUS nbt_name_to_blob(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, DATA_BLOB *blob, struct nbt_name *name)
     /* [<][>][^][v][top][bottom][index][help] */
 384 {
 385         enum ndr_err_code ndr_err;
 386 
 387         ndr_err = ndr_push_struct_blob(blob, mem_ctx, iconv_convenience, name, (ndr_push_flags_fn_t)ndr_push_nbt_name);
 388         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 389                 return ndr_map_error2ntstatus(ndr_err);
 390         }
 391 
 392         return NT_STATUS_OK;
 393 }
 394 
 395 /**
 396   pull a nbt name from a blob
 397 */
 398 _PUBLIC_ NTSTATUS nbt_name_from_blob(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, struct nbt_name *name)
     /* [<][>][^][v][top][bottom][index][help] */
 399 {
 400         enum ndr_err_code ndr_err;
 401 
 402         ndr_err = ndr_pull_struct_blob(blob, mem_ctx, NULL, name,
 403                                        (ndr_pull_flags_fn_t)ndr_pull_nbt_name);
 404         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 405                 return ndr_map_error2ntstatus(ndr_err);
 406         }
 407 
 408         return NT_STATUS_OK;
 409 }
 410 
 411 
 412 /**
 413   choose a name to use when calling a server in a NBT session request.
 414   we use heuristics to see if the name we have been given is a IP
 415   address, or a too-long name. If it is then use *SMBSERVER, or a
 416   truncated name
 417 */
 418 _PUBLIC_ void nbt_choose_called_name(TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 419                             struct nbt_name *n, const char *name, int type)
 420 {
 421         n->scope = NULL;
 422         n->type = type;
 423 
 424         if ((name == NULL) || is_ipaddress(name)) {
 425                 n->name = "*SMBSERVER";
 426                 return;
 427         }
 428         if (strlen(name) > 15) {
 429                 const char *p = strchr(name, '.');
 430                 char *s;
 431                 if (p - name > 15) {
 432                         n->name = "*SMBSERVER";
 433                         return;
 434                 }
 435                 s = talloc_strndup(mem_ctx, name, PTR_DIFF(p, name));
 436                 n->name = talloc_strdup_upper(mem_ctx, s);
 437                 return;
 438         }
 439 
 440         n->name = talloc_strdup_upper(mem_ctx, name);
 441 }
 442 
 443 
 444 /*
 445   escape a string into a form containing only a small set of characters,
 446   the rest is hex encoded. This is similar to URL encoding
 447 */
 448 static const char *nbt_hex_encode(TALLOC_CTX *mem_ctx, const char *s)
     /* [<][>][^][v][top][bottom][index][help] */
 449 {
 450         int i, len;
 451         char *ret;
 452         const char *valid_chars = "_-.$@ ";
 453 #define NBT_CHAR_ALLOW(c) (isalnum((unsigned char)c) || strchr(valid_chars, c))
 454 
 455         for (len=i=0;s[i];i++,len++) {
 456                 if (!NBT_CHAR_ALLOW(s[i])) {
 457                         len += 2;
 458                 }
 459         }
 460 
 461         ret = talloc_array(mem_ctx, char, len+1);
 462         if (ret == NULL) return NULL;
 463 
 464         for (len=i=0;s[i];i++) {
 465                 if (NBT_CHAR_ALLOW(s[i])) {
 466                         ret[len++] = s[i];
 467                 } else {
 468                         snprintf(&ret[len], 4, "%%%02x", (unsigned char)s[i]);
 469                         len += 3;
 470                 }
 471         }
 472         ret[len] = 0;
 473 
 474         return ret;
 475 }
 476 
 477 
 478 /**
 479   form a string for a NBT name
 480 */
 481 _PUBLIC_ char *nbt_name_string(TALLOC_CTX *mem_ctx, const struct nbt_name *name)
     /* [<][>][^][v][top][bottom][index][help] */
 482 {
 483         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 484         char *ret;
 485         if (name->scope) {
 486                 ret = talloc_asprintf(mem_ctx, "%s<%02x>-%s",
 487                                       nbt_hex_encode(tmp_ctx, name->name),
 488                                       name->type,
 489                                       nbt_hex_encode(tmp_ctx, name->scope));
 490         } else {
 491                 ret = talloc_asprintf(mem_ctx, "%s<%02x>",
 492                                       nbt_hex_encode(tmp_ctx, name->name),
 493                                       name->type);
 494         }
 495         talloc_free(tmp_ctx);
 496         return ret;
 497 }
 498 
 499 /**
 500   pull a nbt name, WINS Replication uses another on wire format for nbt name
 501 */
 502 _PUBLIC_ enum ndr_err_code ndr_pull_wrepl_nbt_name(struct ndr_pull *ndr, int ndr_flags, const struct nbt_name **_r)
     /* [<][>][^][v][top][bottom][index][help] */
 503 {
 504         struct nbt_name *r;
 505         uint8_t *namebuf;
 506         uint32_t namebuf_len;
 507 
 508         if (!(ndr_flags & NDR_SCALARS)) {
 509                 return NDR_ERR_SUCCESS;
 510         }
 511 
 512         NDR_CHECK(ndr_pull_align(ndr, 4));
 513         NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &namebuf_len));
 514         if (namebuf_len < 1 || namebuf_len > 255) {
 515                 return ndr_pull_error(ndr, NDR_ERR_ALLOC, "value out of range");
 516         }
 517         NDR_PULL_ALLOC_N(ndr, namebuf, namebuf_len);
 518         NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len));
 519 
 520         NDR_PULL_ALLOC(ndr, r);
 521 
 522         /* oh wow, what a nasty bug in windows ... */
 523         if (namebuf[0] == 0x1b && namebuf_len >= 16) {
 524                 namebuf[0] = namebuf[15];
 525                 namebuf[15] = 0x1b;
 526         }
 527 
 528         if (namebuf_len < 17) {
 529                 r->type = 0x00;
 530 
 531                 r->name = talloc_strndup(r, (char *)namebuf, namebuf_len);
 532                 if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
 533 
 534                 r->scope= NULL;
 535 
 536                 talloc_free(namebuf);
 537                 *_r = r;
 538                 return NDR_ERR_SUCCESS;
 539         }
 540 
 541         r->type = namebuf[15];
 542 
 543         namebuf[15] = '\0';
 544         trim_string((char *)namebuf, NULL, " ");
 545         r->name = talloc_strdup(r, (char *)namebuf);
 546         if (!r->name) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
 547 
 548         if (namebuf_len > 18) {
 549                 r->scope = talloc_strndup(r, (char *)(namebuf+17), namebuf_len-17);
 550                 if (!r->scope) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "out of memory");
 551         } else {
 552                 r->scope = NULL;
 553         }
 554 
 555         talloc_free(namebuf);
 556         *_r = r;
 557         return NDR_ERR_SUCCESS;
 558 }
 559 
 560 /**
 561   push a nbt name, WINS Replication uses another on wire format for nbt name
 562 */
 563 _PUBLIC_ enum ndr_err_code ndr_push_wrepl_nbt_name(struct ndr_push *ndr, int ndr_flags, const struct nbt_name *r)
     /* [<][>][^][v][top][bottom][index][help] */
 564 {
 565         uint8_t *namebuf;
 566         uint32_t namebuf_len;
 567         uint32_t _name_len;
 568         uint32_t scope_len = 0;
 569 
 570         if (r == NULL) {
 571                 return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER,
 572                                       "wrepl_nbt_name NULL pointer");
 573         }
 574 
 575         if (!(ndr_flags & NDR_SCALARS)) {
 576                 return NDR_ERR_SUCCESS;
 577         }
 578 
 579         _name_len = strlen(r->name);
 580         if (_name_len > 15) {
 581                 return ndr_push_error(ndr, NDR_ERR_STRING,
 582                                       "wrepl_nbt_name longer as 15 chars: %s",
 583                                       r->name);
 584         }
 585 
 586         if (r->scope) {
 587                 scope_len = strlen(r->scope);
 588         }
 589         if (scope_len > 238) {
 590                 return ndr_push_error(ndr, NDR_ERR_STRING,
 591                                       "wrepl_nbt_name scope longer as 238 chars: %s",
 592                                       r->scope);
 593         }
 594 
 595         namebuf = (uint8_t *)talloc_asprintf(ndr, "%-15s%c%s",
 596                                              r->name, 'X',
 597                                              (r->scope?r->scope:""));
 598         if (!namebuf) return ndr_push_error(ndr, NDR_ERR_ALLOC, "out of memory");
 599 
 600         namebuf_len = strlen((char *)namebuf) + 1;
 601 
 602         /*
 603          * we need to set the type here, and use a place-holder in the talloc_asprintf()
 604          * as the type can be 0x00, and then the namebuf_len = strlen(namebuf); would give wrong results
 605          */
 606         namebuf[15] = r->type;
 607 
 608         /* oh wow, what a nasty bug in windows ... */
 609         if (r->type == 0x1b) {
 610                 namebuf[15] = namebuf[0];
 611                 namebuf[0] = 0x1b;
 612         }
 613 
 614         NDR_CHECK(ndr_push_align(ndr, 4));
 615         NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, namebuf_len));
 616         NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, namebuf, namebuf_len));
 617 
 618         talloc_free(namebuf);
 619         return NDR_ERR_SUCCESS;
 620 }
 621 
 622 _PUBLIC_ void ndr_print_wrepl_nbt_name(struct ndr_print *ndr, const char *name, const struct nbt_name *r)
     /* [<][>][^][v][top][bottom][index][help] */
 623 {
 624         char *s = nbt_name_string(ndr, r);
 625         ndr_print_string(ndr, name, s);
 626         talloc_free(s);
 627 }
 628 
 629 _PUBLIC_ enum ndr_err_code ndr_push_nbt_res_rec(struct ndr_push *ndr, int ndr_flags, const struct nbt_res_rec *r)
     /* [<][>][^][v][top][bottom][index][help] */
 630 {
 631         {
 632                 uint32_t _flags_save_STRUCT = ndr->flags;
 633                 ndr_set_flags(&ndr->flags, LIBNDR_PRINT_ARRAY_HEX);
 634                 if (ndr_flags & NDR_SCALARS) {
 635                         NDR_CHECK(ndr_push_align(ndr, 4));
 636                         NDR_CHECK(ndr_push_nbt_name(ndr, NDR_SCALARS, &r->name));
 637                         NDR_CHECK(ndr_push_nbt_qtype(ndr, NDR_SCALARS, r->rr_type));
 638                         NDR_CHECK(ndr_push_nbt_qclass(ndr, NDR_SCALARS, r->rr_class));
 639                         NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->ttl));
 640                         NDR_CHECK(ndr_push_set_switch_value(ndr, &r->rdata, ((((r->rr_type) == NBT_QTYPE_NETBIOS) && ((r->rdata).data.length == 2))?0:r->rr_type)));
 641                         NDR_CHECK(ndr_push_nbt_rdata(ndr, NDR_SCALARS, &r->rdata));
 642                 }
 643                 if (ndr_flags & NDR_BUFFERS) {
 644                 }
 645                 ndr->flags = _flags_save_STRUCT;
 646         }
 647         return NDR_ERR_SUCCESS;
 648 }

/* [<][>][^][v][top][bottom][index][help] */