~ubuntu-branches/ubuntu/oneiric/samba/oneiric-security

« back to all changes in this revision

Viewing changes to .pc/security-CVE-2011-0719.patch/source3/libsmb/nmblib.c

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-03-10 10:03:01 UTC
  • mfrom: (0.39.11 sid)
  • Revision ID: james.westby@ubuntu.com-20110310100301-jfjg41wv0iq05zj4
Tags: 2:3.5.8~dfsg-1ubuntu1
* Merge from debian unstable.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access. 
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/mksmbpasswd.awk:
    - Do not add user with UID less than 1000 to smbpasswd
  + debian/control:
    - Make libwbclient0 replace/conflict with hardy's likewise-open.
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
    - Add cuups breaks to push the package to aslo upgrade cups (LP: #639768)
  + debian/rules:
    - enable "native" PIE hardening.
    - Add BIND_NOW to maximize benefit of RELRO hardening.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
    - Don't ship the /etc/network/if-up.d file.
  + debian/samba.postinst: 
    - Fixed bashism.
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/samba.logrotate: Make it upstart compatible
  + debian/samba-common.dhcp: Fix typo to get a proper parsing in
    /etc/samba/dhcp.
  + Dropped:
    - debian/patches/fix-windows7-print-connection.patch: Merged upstream.
    - debian/patches/security-CVE-2011-0719.patch: Merged upstream. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
   Unix SMB/CIFS implementation.
3
 
   NBT netbios library routines
4
 
   Copyright (C) Andrew Tridgell 1994-1998
5
 
   Copyright (C) Jeremy Allison 2007
6
 
 
7
 
   This program is free software; you can redistribute it and/or modify
8
 
   it under the terms of the GNU General Public License as published by
9
 
   the Free Software Foundation; either version 3 of the License, or
10
 
   (at your option) any later version.
11
 
 
12
 
   This program is distributed in the hope that it will be useful,
13
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
   GNU General Public License for more details.
16
 
 
17
 
   You should have received a copy of the GNU General Public License
18
 
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 
 
20
 
*/
21
 
 
22
 
#include "includes.h"
23
 
 
24
 
static const struct opcode_names {
25
 
        const char *nmb_opcode_name;
26
 
        int opcode;
27
 
} nmb_header_opcode_names[] = {
28
 
        {"Query",           0 },
29
 
        {"Registration",      5 },
30
 
        {"Release",           6 },
31
 
        {"WACK",              7 },
32
 
        {"Refresh",           8 },
33
 
        {"Refresh(altcode)",  9 },
34
 
        {"Multi-homed Registration", 15 },
35
 
        {0, -1 }
36
 
};
37
 
 
38
 
/****************************************************************************
39
 
 Lookup a nmb opcode name.
40
 
****************************************************************************/
41
 
 
42
 
static const char *lookup_opcode_name( int opcode )
43
 
{
44
 
        const struct opcode_names *op_namep;
45
 
        int i;
46
 
 
47
 
        for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
48
 
                op_namep = &nmb_header_opcode_names[i];
49
 
                if(opcode == op_namep->opcode)
50
 
                        return op_namep->nmb_opcode_name;
51
 
        }
52
 
        return "<unknown opcode>";
53
 
}
54
 
 
55
 
/****************************************************************************
56
 
 Print out a res_rec structure.
57
 
****************************************************************************/
58
 
 
59
 
static void debug_nmb_res_rec(struct res_rec *res, const char *hdr)
60
 
{
61
 
        int i, j;
62
 
 
63
 
        DEBUGADD( 4, ( "    %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
64
 
                hdr,
65
 
                nmb_namestr(&res->rr_name),
66
 
                res->rr_type,
67
 
                res->rr_class,
68
 
                res->ttl ) );
69
 
 
70
 
        if( res->rdlength == 0 || res->rdata == NULL )
71
 
                return;
72
 
 
73
 
        for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) {
74
 
                DEBUGADD(4, ("    %s %3x char ", hdr, i));
75
 
 
76
 
                for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
77
 
                        unsigned char x = res->rdata[i+j];
78
 
                        if (x < 32 || x > 127)
79
 
                                x = '.';
80
 
 
81
 
                        if (i+j >= res->rdlength)
82
 
                                break;
83
 
                        DEBUGADD(4, ("%c", x));
84
 
                }
85
 
 
86
 
                DEBUGADD(4, ("   hex "));
87
 
 
88
 
                for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) {
89
 
                        if (i+j >= res->rdlength)
90
 
                                break;
91
 
                        DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j]));
92
 
                }
93
 
 
94
 
                DEBUGADD(4, ("\n"));
95
 
        }
96
 
}
97
 
 
98
 
/****************************************************************************
99
 
 Process a nmb packet.
100
 
****************************************************************************/
101
 
 
102
 
void debug_nmb_packet(struct packet_struct *p)
103
 
{
104
 
        struct nmb_packet *nmb = &p->packet.nmb;
105
 
 
106
 
        if( DEBUGLVL( 4 ) ) {
107
 
                dbgtext( "nmb packet from %s(%d) header: id=%d "
108
 
                                "opcode=%s(%d) response=%s\n",
109
 
                        inet_ntoa(p->ip), p->port,
110
 
                        nmb->header.name_trn_id,
111
 
                        lookup_opcode_name(nmb->header.opcode),
112
 
                        nmb->header.opcode,
113
 
                        BOOLSTR(nmb->header.response) );
114
 
                dbgtext( "    header: flags: bcast=%s rec_avail=%s "
115
 
                                "rec_des=%s trunc=%s auth=%s\n",
116
 
                        BOOLSTR(nmb->header.nm_flags.bcast),
117
 
                        BOOLSTR(nmb->header.nm_flags.recursion_available),
118
 
                        BOOLSTR(nmb->header.nm_flags.recursion_desired),
119
 
                        BOOLSTR(nmb->header.nm_flags.trunc),
120
 
                        BOOLSTR(nmb->header.nm_flags.authoritative) );
121
 
                dbgtext( "    header: rcode=%d qdcount=%d ancount=%d "
122
 
                                "nscount=%d arcount=%d\n",
123
 
                        nmb->header.rcode,
124
 
                        nmb->header.qdcount,
125
 
                        nmb->header.ancount,
126
 
                        nmb->header.nscount,
127
 
                        nmb->header.arcount );
128
 
        }
129
 
 
130
 
        if (nmb->header.qdcount) {
131
 
                DEBUGADD( 4, ( "    question: q_name=%s q_type=%d q_class=%d\n",
132
 
                        nmb_namestr(&nmb->question.question_name),
133
 
                        nmb->question.question_type,
134
 
                        nmb->question.question_class) );
135
 
        }
136
 
 
137
 
        if (nmb->answers && nmb->header.ancount) {
138
 
                debug_nmb_res_rec(nmb->answers,"answers");
139
 
        }
140
 
        if (nmb->nsrecs && nmb->header.nscount) {
141
 
                debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
142
 
        }
143
 
        if (nmb->additional && nmb->header.arcount) {
144
 
                debug_nmb_res_rec(nmb->additional,"additional");
145
 
        }
146
 
}
147
 
 
148
 
/*******************************************************************
149
 
 Handle "compressed" name pointers.
150
 
******************************************************************/
151
 
 
152
 
static bool handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
153
 
                             bool *got_pointer,int *ret)
154
 
{
155
 
        int loop_count=0;
156
 
 
157
 
        while ((ubuf[*offset] & 0xC0) == 0xC0) {
158
 
                if (!*got_pointer)
159
 
                        (*ret) += 2;
160
 
                (*got_pointer)=True;
161
 
                (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
162
 
                if (loop_count++ == 10 ||
163
 
                                (*offset) < 0 || (*offset)>(length-2)) {
164
 
                        return False;
165
 
                }
166
 
        }
167
 
        return True;
168
 
}
169
 
 
170
 
/*******************************************************************
171
 
 Parse a nmb name from "compressed" format to something readable
172
 
 return the space taken by the name, or 0 if the name is invalid
173
 
******************************************************************/
174
 
 
175
 
static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name)
176
 
{
177
 
        int m,n=0;
178
 
        unsigned char *ubuf = (unsigned char *)inbuf;
179
 
        int ret = 0;
180
 
        bool got_pointer=False;
181
 
        int loop_count=0;
182
 
        int offset = ofs;
183
 
 
184
 
        if (length - offset < 2)
185
 
                return(0);
186
 
 
187
 
        /* handle initial name pointers */
188
 
        if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
189
 
                return(0);
190
 
 
191
 
        m = ubuf[offset];
192
 
 
193
 
        if (!m)
194
 
                return(0);
195
 
        if ((m & 0xC0) || offset+m+2 > length)
196
 
                return(0);
197
 
 
198
 
        memset((char *)name,'\0',sizeof(*name));
199
 
 
200
 
        /* the "compressed" part */
201
 
        if (!got_pointer)
202
 
                ret += m + 2;
203
 
        offset++;
204
 
        while (m > 0) {
205
 
                unsigned char c1,c2;
206
 
                c1 = ubuf[offset++]-'A';
207
 
                c2 = ubuf[offset++]-'A';
208
 
                if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
209
 
                        return(0);
210
 
                name->name[n++] = (c1<<4) | c2;
211
 
                m -= 2;
212
 
        }
213
 
        name->name[n] = 0;
214
 
 
215
 
        if (n==MAX_NETBIOSNAME_LEN) {
216
 
                /* parse out the name type, its always
217
 
                 * in the 16th byte of the name */
218
 
                name->name_type = ((unsigned char)name->name[15]) & 0xff;
219
 
 
220
 
                /* remove trailing spaces */
221
 
                name->name[15] = 0;
222
 
                n = 14;
223
 
                while (n && name->name[n]==' ')
224
 
                        name->name[n--] = 0;
225
 
        }
226
 
 
227
 
        /* now the domain parts (if any) */
228
 
        n = 0;
229
 
        while (ubuf[offset]) {
230
 
                /* we can have pointers within the domain part as well */
231
 
                if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
232
 
                        return(0);
233
 
 
234
 
                m = ubuf[offset];
235
 
                /*
236
 
                 * Don't allow null domain parts.
237
 
                 */
238
 
                if (!m)
239
 
                        return(0);
240
 
                if (!got_pointer)
241
 
                        ret += m+1;
242
 
                if (n)
243
 
                        name->scope[n++] = '.';
244
 
                if (m+2+offset>length || n+m+1>sizeof(name->scope))
245
 
                        return(0);
246
 
                offset++;
247
 
                while (m--)
248
 
                        name->scope[n++] = (char)ubuf[offset++];
249
 
 
250
 
                /*
251
 
                 * Watch for malicious loops.
252
 
                 */
253
 
                if (loop_count++ == 10)
254
 
                        return 0;
255
 
        }
256
 
        name->scope[n++] = 0;
257
 
 
258
 
        return(ret);
259
 
}
260
 
 
261
 
/****************************************************************************
262
 
 Put a netbios name, padding(s) and a name type into a 16 character buffer.
263
 
 name is already in DOS charset.
264
 
 [15 bytes name + padding][1 byte name type].
265
 
****************************************************************************/
266
 
 
267
 
void put_name(char *dest, const char *name, int pad, unsigned int name_type)
268
 
{
269
 
        size_t len = strlen(name);
270
 
 
271
 
        memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ?
272
 
                        len : MAX_NETBIOSNAME_LEN - 1);
273
 
        if (len < MAX_NETBIOSNAME_LEN - 1) {
274
 
                memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len);
275
 
        }
276
 
        dest[MAX_NETBIOSNAME_LEN - 1] = name_type;
277
 
}
278
 
 
279
 
/*******************************************************************
280
 
 Put a compressed nmb name into a buffer. Return the length of the
281
 
 compressed name.
282
 
 
283
 
 Compressed names are really weird. The "compression" doubles the
284
 
 size. The idea is that it also means that compressed names conform
285
 
 to the doman name system. See RFC1002.
286
 
 
287
 
 If buf == NULL this is a length calculation.
288
 
******************************************************************/
289
 
 
290
 
static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
291
 
{
292
 
        int ret,m;
293
 
        nstring buf1;
294
 
        char *p;
295
 
 
296
 
        if (strcmp(name->name,"*") == 0) {
297
 
                /* special case for wildcard name */
298
 
                put_name(buf1, "*", '\0', name->name_type);
299
 
        } else {
300
 
                put_name(buf1, name->name, ' ', name->name_type);
301
 
        }
302
 
 
303
 
        if (buf) {
304
 
                buf[offset] = 0x20;
305
 
        }
306
 
 
307
 
        ret = 34;
308
 
 
309
 
        for (m=0;m<MAX_NETBIOSNAME_LEN;m++) {
310
 
                if (buf) {
311
 
                        buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
312
 
                        buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
313
 
                }
314
 
        }
315
 
        offset += 33;
316
 
 
317
 
        if (buf) {
318
 
                buf[offset] = 0;
319
 
        }
320
 
 
321
 
        if (name->scope[0]) {
322
 
                /* XXXX this scope handling needs testing */
323
 
                ret += strlen(name->scope) + 1;
324
 
                if (buf) {
325
 
                        safe_strcpy(&buf[offset+1],name->scope,
326
 
                                        sizeof(name->scope));
327
 
 
328
 
                        p = &buf[offset+1];
329
 
                        while ((p = strchr_m(p,'.'))) {
330
 
                                buf[offset] = PTR_DIFF(p,&buf[offset+1]);
331
 
                                offset += (buf[offset] + 1);
332
 
                                p = &buf[offset+1];
333
 
                        }
334
 
                        buf[offset] = strlen(&buf[offset+1]);
335
 
                }
336
 
        }
337
 
 
338
 
        return ret;
339
 
}
340
 
 
341
 
/*******************************************************************
342
 
 Useful for debugging messages.
343
 
******************************************************************/
344
 
 
345
 
char *nmb_namestr(const struct nmb_name *n)
346
 
{
347
 
        fstring name;
348
 
        char *result;
349
 
 
350
 
        pull_ascii_fstring(name, n->name);
351
 
        if (!n->scope[0])
352
 
                result = talloc_asprintf(talloc_tos(), "%s<%02x>", name,
353
 
                                         n->name_type);
354
 
        else
355
 
                result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name,
356
 
                                         n->name_type, n->scope);
357
 
 
358
 
        SMB_ASSERT(result != NULL);
359
 
        return result;
360
 
}
361
 
 
362
 
/*******************************************************************
363
 
 Allocate and parse some resource records.
364
 
******************************************************************/
365
 
 
366
 
static bool parse_alloc_res_rec(char *inbuf,int *offset,int length,
367
 
                                struct res_rec **recs, int count)
368
 
{
369
 
        int i;
370
 
 
371
 
        *recs = SMB_MALLOC_ARRAY(struct res_rec, count);
372
 
        if (!*recs)
373
 
                return(False);
374
 
 
375
 
        memset((char *)*recs,'\0',sizeof(**recs)*count);
376
 
 
377
 
        for (i=0;i<count;i++) {
378
 
                int l = parse_nmb_name(inbuf,*offset,length,
379
 
                                &(*recs)[i].rr_name);
380
 
                (*offset) += l;
381
 
                if (!l || (*offset)+10 > length) {
382
 
                        SAFE_FREE(*recs);
383
 
                        return(False);
384
 
                }
385
 
                (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
386
 
                (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
387
 
                (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
388
 
                (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
389
 
                (*offset) += 10;
390
 
                if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
391
 
                                (*offset)+(*recs)[i].rdlength > length) {
392
 
                        SAFE_FREE(*recs);
393
 
                        return(False);
394
 
                }
395
 
                memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
396
 
                (*offset) += (*recs)[i].rdlength;
397
 
        }
398
 
        return(True);
399
 
}
400
 
 
401
 
/*******************************************************************
402
 
 Put a resource record into a packet.
403
 
 If buf == NULL this is a length calculation.
404
 
******************************************************************/
405
 
 
406
 
static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
407
 
{
408
 
        int ret=0;
409
 
        int i;
410
 
 
411
 
        for (i=0;i<count;i++) {
412
 
                int l = put_nmb_name(buf,offset,&recs[i].rr_name);
413
 
                offset += l;
414
 
                ret += l;
415
 
                if (buf) {
416
 
                        RSSVAL(buf,offset,recs[i].rr_type);
417
 
                        RSSVAL(buf,offset+2,recs[i].rr_class);
418
 
                        RSIVAL(buf,offset+4,recs[i].ttl);
419
 
                        RSSVAL(buf,offset+8,recs[i].rdlength);
420
 
                        memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
421
 
                }
422
 
                offset += 10+recs[i].rdlength;
423
 
                ret += 10+recs[i].rdlength;
424
 
        }
425
 
 
426
 
        return ret;
427
 
}
428
 
 
429
 
/*******************************************************************
430
 
 Put a compressed name pointer record into a packet.
431
 
 If buf == NULL this is a length calculation.
432
 
******************************************************************/
433
 
 
434
 
static int put_compressed_name_ptr(unsigned char *buf,
435
 
                                int offset,
436
 
                                struct res_rec *rec,
437
 
                                int ptr_offset)
438
 
{
439
 
        int ret=0;
440
 
        if (buf) {
441
 
                buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF));
442
 
                buf[offset+1] = (ptr_offset & 0xFF);
443
 
        }
444
 
        offset += 2;
445
 
        ret += 2;
446
 
        if (buf) {
447
 
                RSSVAL(buf,offset,rec->rr_type);
448
 
                RSSVAL(buf,offset+2,rec->rr_class);
449
 
                RSIVAL(buf,offset+4,rec->ttl);
450
 
                RSSVAL(buf,offset+8,rec->rdlength);
451
 
                memcpy(buf+offset+10,rec->rdata,rec->rdlength);
452
 
        }
453
 
        offset += 10+rec->rdlength;
454
 
        ret += 10+rec->rdlength;
455
 
 
456
 
        return ret;
457
 
}
458
 
 
459
 
/*******************************************************************
460
 
 Parse a dgram packet. Return False if the packet can't be parsed
461
 
 or is invalid for some reason, True otherwise.
462
 
 
463
 
 This is documented in section 4.4.1 of RFC1002.
464
 
******************************************************************/
465
 
 
466
 
static bool parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
467
 
{
468
 
        int offset;
469
 
        int flags;
470
 
 
471
 
        memset((char *)dgram,'\0',sizeof(*dgram));
472
 
 
473
 
        if (length < 14)
474
 
                return(False);
475
 
 
476
 
        dgram->header.msg_type = CVAL(inbuf,0);
477
 
        flags = CVAL(inbuf,1);
478
 
        dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
479
 
        if (flags & 1)
480
 
                dgram->header.flags.more = True;
481
 
        if (flags & 2)
482
 
                dgram->header.flags.first = True;
483
 
        dgram->header.dgm_id = RSVAL(inbuf,2);
484
 
        putip((char *)&dgram->header.source_ip,inbuf+4);
485
 
        dgram->header.source_port = RSVAL(inbuf,8);
486
 
        dgram->header.dgm_length = RSVAL(inbuf,10);
487
 
        dgram->header.packet_offset = RSVAL(inbuf,12);
488
 
 
489
 
        offset = 14;
490
 
 
491
 
        if (dgram->header.msg_type == 0x10 ||
492
 
                        dgram->header.msg_type == 0x11 ||
493
 
                        dgram->header.msg_type == 0x12) {
494
 
                offset += parse_nmb_name(inbuf,offset,length,
495
 
                                &dgram->source_name);
496
 
                offset += parse_nmb_name(inbuf,offset,length,
497
 
                                &dgram->dest_name);
498
 
        }
499
 
 
500
 
        if (offset >= length || (length-offset > sizeof(dgram->data)))
501
 
                return(False);
502
 
 
503
 
        dgram->datasize = length-offset;
504
 
        memcpy(dgram->data,inbuf+offset,dgram->datasize);
505
 
 
506
 
        /* Paranioa. Ensure the last 2 bytes in the dgram buffer are
507
 
           zero. This should be true anyway, just enforce it for
508
 
           paranioa sake. JRA. */
509
 
        SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2));
510
 
        memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2);
511
 
 
512
 
        return(True);
513
 
}
514
 
 
515
 
/*******************************************************************
516
 
 Parse a nmb packet. Return False if the packet can't be parsed
517
 
 or is invalid for some reason, True otherwise.
518
 
******************************************************************/
519
 
 
520
 
static bool parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
521
 
{
522
 
        int nm_flags,offset;
523
 
 
524
 
        memset((char *)nmb,'\0',sizeof(*nmb));
525
 
 
526
 
        if (length < 12)
527
 
                return(False);
528
 
 
529
 
        /* parse the header */
530
 
        nmb->header.name_trn_id = RSVAL(inbuf,0);
531
 
 
532
 
        DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
533
 
 
534
 
        nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
535
 
        nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
536
 
        nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
537
 
        nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
538
 
        nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
539
 
        nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
540
 
        nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
541
 
        nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
542
 
        nmb->header.rcode = CVAL(inbuf,3) & 0xF;
543
 
        nmb->header.qdcount = RSVAL(inbuf,4);
544
 
        nmb->header.ancount = RSVAL(inbuf,6);
545
 
        nmb->header.nscount = RSVAL(inbuf,8);
546
 
        nmb->header.arcount = RSVAL(inbuf,10);
547
 
 
548
 
        if (nmb->header.qdcount) {
549
 
                offset = parse_nmb_name(inbuf,12,length,
550
 
                                &nmb->question.question_name);
551
 
                if (!offset)
552
 
                        return(False);
553
 
 
554
 
                if (length - (12+offset) < 4)
555
 
                        return(False);
556
 
                nmb->question.question_type = RSVAL(inbuf,12+offset);
557
 
                nmb->question.question_class = RSVAL(inbuf,12+offset+2);
558
 
 
559
 
                offset += 12+4;
560
 
        } else {
561
 
                offset = 12;
562
 
        }
563
 
 
564
 
        /* and any resource records */
565
 
        if (nmb->header.ancount &&
566
 
                        !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
567
 
                                        nmb->header.ancount))
568
 
                return(False);
569
 
 
570
 
        if (nmb->header.nscount &&
571
 
                        !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
572
 
                                        nmb->header.nscount))
573
 
                return(False);
574
 
 
575
 
        if (nmb->header.arcount &&
576
 
                        !parse_alloc_res_rec(inbuf,&offset,length,
577
 
                                &nmb->additional, nmb->header.arcount))
578
 
                return(False);
579
 
 
580
 
        return(True);
581
 
}
582
 
 
583
 
/*******************************************************************
584
 
 'Copy constructor' for an nmb packet.
585
 
******************************************************************/
586
 
 
587
 
static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
588
 
{
589
 
        struct nmb_packet *nmb;
590
 
        struct nmb_packet *copy_nmb;
591
 
        struct packet_struct *pkt_copy;
592
 
 
593
 
        if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
594
 
                DEBUG(0,("copy_nmb_packet: malloc fail.\n"));
595
 
                return NULL;
596
 
        }
597
 
 
598
 
        /* Structure copy of entire thing. */
599
 
 
600
 
        *pkt_copy = *packet;
601
 
 
602
 
        /* Ensure this copy is not locked. */
603
 
        pkt_copy->locked = False;
604
 
        pkt_copy->recv_fd = -1;
605
 
        pkt_copy->send_fd = -1;
606
 
 
607
 
        /* Ensure this copy has no resource records. */
608
 
        nmb = &packet->packet.nmb;
609
 
        copy_nmb = &pkt_copy->packet.nmb;
610
 
 
611
 
        copy_nmb->answers = NULL;
612
 
        copy_nmb->nsrecs = NULL;
613
 
        copy_nmb->additional = NULL;
614
 
 
615
 
        /* Now copy any resource records. */
616
 
 
617
 
        if (nmb->answers) {
618
 
                if((copy_nmb->answers = SMB_MALLOC_ARRAY(
619
 
                                struct res_rec,nmb->header.ancount)) == NULL)
620
 
                        goto free_and_exit;
621
 
                memcpy((char *)copy_nmb->answers, (char *)nmb->answers,
622
 
                                nmb->header.ancount * sizeof(struct res_rec));
623
 
        }
624
 
        if (nmb->nsrecs) {
625
 
                if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(
626
 
                                struct res_rec, nmb->header.nscount)) == NULL)
627
 
                        goto free_and_exit;
628
 
                memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs,
629
 
                                nmb->header.nscount * sizeof(struct res_rec));
630
 
        }
631
 
        if (nmb->additional) {
632
 
                if((copy_nmb->additional = SMB_MALLOC_ARRAY(
633
 
                                struct res_rec, nmb->header.arcount)) == NULL)
634
 
                        goto free_and_exit;
635
 
                memcpy((char *)copy_nmb->additional, (char *)nmb->additional,
636
 
                                nmb->header.arcount * sizeof(struct res_rec));
637
 
        }
638
 
 
639
 
        return pkt_copy;
640
 
 
641
 
 free_and_exit:
642
 
 
643
 
        SAFE_FREE(copy_nmb->answers);
644
 
        SAFE_FREE(copy_nmb->nsrecs);
645
 
        SAFE_FREE(copy_nmb->additional);
646
 
        SAFE_FREE(pkt_copy);
647
 
 
648
 
        DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
649
 
        return NULL;
650
 
}
651
 
 
652
 
/*******************************************************************
653
 
  'Copy constructor' for a dgram packet.
654
 
******************************************************************/
655
 
 
656
 
static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
657
 
{
658
 
        struct packet_struct *pkt_copy;
659
 
 
660
 
        if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) {
661
 
                DEBUG(0,("copy_dgram_packet: malloc fail.\n"));
662
 
                return NULL;
663
 
        }
664
 
 
665
 
        /* Structure copy of entire thing. */
666
 
 
667
 
        *pkt_copy = *packet;
668
 
 
669
 
        /* Ensure this copy is not locked. */
670
 
        pkt_copy->locked = False;
671
 
        pkt_copy->recv_fd = -1;
672
 
        pkt_copy->send_fd = -1;
673
 
 
674
 
        /* There are no additional pointers in a dgram packet,
675
 
                we are finished. */
676
 
        return pkt_copy;
677
 
}
678
 
 
679
 
/*******************************************************************
680
 
 'Copy constructor' for a generic packet.
681
 
******************************************************************/
682
 
 
683
 
struct packet_struct *copy_packet(struct packet_struct *packet)
684
 
{
685
 
        if(packet->packet_type == NMB_PACKET)
686
 
                return copy_nmb_packet(packet);
687
 
        else if (packet->packet_type == DGRAM_PACKET)
688
 
                return copy_dgram_packet(packet);
689
 
        return NULL;
690
 
}
691
 
 
692
 
/*******************************************************************
693
 
 Free up any resources associated with an nmb packet.
694
 
******************************************************************/
695
 
 
696
 
static void free_nmb_packet(struct nmb_packet *nmb)
697
 
{
698
 
        SAFE_FREE(nmb->answers);
699
 
        SAFE_FREE(nmb->nsrecs);
700
 
        SAFE_FREE(nmb->additional);
701
 
}
702
 
 
703
 
/*******************************************************************
704
 
 Free up any resources associated with a dgram packet.
705
 
******************************************************************/
706
 
 
707
 
static void free_dgram_packet(struct dgram_packet *nmb)
708
 
{
709
 
        /* We have nothing to do for a dgram packet. */
710
 
}
711
 
 
712
 
/*******************************************************************
713
 
 Free up any resources associated with a packet.
714
 
******************************************************************/
715
 
 
716
 
void free_packet(struct packet_struct *packet)
717
 
{
718
 
        if (packet->locked)
719
 
                return;
720
 
        if (packet->packet_type == NMB_PACKET)
721
 
                free_nmb_packet(&packet->packet.nmb);
722
 
        else if (packet->packet_type == DGRAM_PACKET)
723
 
                free_dgram_packet(&packet->packet.dgram);
724
 
        ZERO_STRUCTPN(packet);
725
 
        SAFE_FREE(packet);
726
 
}
727
 
 
728
 
/*******************************************************************
729
 
 Parse a packet buffer into a packet structure.
730
 
******************************************************************/
731
 
 
732
 
struct packet_struct *parse_packet(char *buf,int length,
733
 
                                   enum packet_type packet_type,
734
 
                                   struct in_addr ip,
735
 
                                   int port)
736
 
{
737
 
        struct packet_struct *p;
738
 
        bool ok=False;
739
 
 
740
 
        p = SMB_MALLOC_P(struct packet_struct);
741
 
        if (!p)
742
 
                return(NULL);
743
 
 
744
 
        ZERO_STRUCTP(p);        /* initialize for possible padding */
745
 
 
746
 
        p->next = NULL;
747
 
        p->prev = NULL;
748
 
        p->ip = ip;
749
 
        p->port = port;
750
 
        p->locked = False;
751
 
        p->timestamp = time(NULL);
752
 
        p->packet_type = packet_type;
753
 
 
754
 
        switch (packet_type) {
755
 
        case NMB_PACKET:
756
 
                ok = parse_nmb(buf,length,&p->packet.nmb);
757
 
                break;
758
 
 
759
 
        case DGRAM_PACKET:
760
 
                ok = parse_dgram(buf,length,&p->packet.dgram);
761
 
                break;
762
 
        }
763
 
 
764
 
        if (!ok) {
765
 
                free_packet(p);
766
 
                return NULL;
767
 
        }
768
 
 
769
 
        return p;
770
 
}
771
 
 
772
 
/*******************************************************************
773
 
 Read a packet from a socket and parse it, returning a packet ready
774
 
 to be used or put on the queue. This assumes a UDP socket.
775
 
******************************************************************/
776
 
 
777
 
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
778
 
{
779
 
        struct packet_struct *packet;
780
 
        struct sockaddr_storage sa;
781
 
        struct sockaddr_in *si = (struct sockaddr_in *)&sa;
782
 
        char buf[MAX_DGRAM_SIZE];
783
 
        int length;
784
 
 
785
 
        length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa);
786
 
        if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) {
787
 
                return NULL;
788
 
        }
789
 
 
790
 
        packet = parse_packet(buf,
791
 
                        length,
792
 
                        packet_type,
793
 
                        si->sin_addr,
794
 
                        ntohs(si->sin_port));
795
 
        if (!packet)
796
 
                return NULL;
797
 
 
798
 
        packet->recv_fd = fd;
799
 
        packet->send_fd = -1;
800
 
 
801
 
        DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
802
 
                 length, inet_ntoa(packet->ip), packet->port ) );
803
 
 
804
 
        return(packet);
805
 
}
806
 
 
807
 
/*******************************************************************
808
 
 Send a udp packet on a already open socket.
809
 
******************************************************************/
810
 
 
811
 
static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
812
 
{
813
 
        bool ret = False;
814
 
        int i;
815
 
        struct sockaddr_in sock_out;
816
 
 
817
 
        /* set the address and port */
818
 
        memset((char *)&sock_out,'\0',sizeof(sock_out));
819
 
        putip((char *)&sock_out.sin_addr,(char *)&ip);
820
 
        sock_out.sin_port = htons( port );
821
 
        sock_out.sin_family = AF_INET;
822
 
 
823
 
        DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n",
824
 
                        len, inet_ntoa(ip), port ) );
825
 
 
826
 
        /*
827
 
         * Patch to fix asynch error notifications from Linux kernel.
828
 
         */
829
 
 
830
 
        for (i = 0; i < 5; i++) {
831
 
                ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
832
 
                                        sizeof(sock_out)) >= 0);
833
 
                if (ret || errno != ECONNREFUSED)
834
 
                        break;
835
 
        }
836
 
 
837
 
        if (!ret)
838
 
                DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
839
 
                        inet_ntoa(ip),port,strerror(errno)));
840
 
 
841
 
        return(ret);
842
 
}
843
 
 
844
 
/*******************************************************************
845
 
 Build a dgram packet ready for sending.
846
 
 If buf == NULL this is a length calculation.
847
 
******************************************************************/
848
 
 
849
 
static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram)
850
 
{
851
 
        unsigned char *ubuf = (unsigned char *)buf;
852
 
        int offset=0;
853
 
 
854
 
        /* put in the header */
855
 
        if (buf) {
856
 
                ubuf[0] = dgram->header.msg_type;
857
 
                ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
858
 
                if (dgram->header.flags.more)
859
 
                        ubuf[1] |= 1;
860
 
                if (dgram->header.flags.first)
861
 
                        ubuf[1] |= 2;
862
 
                RSSVAL(ubuf,2,dgram->header.dgm_id);
863
 
                putip(ubuf+4,(char *)&dgram->header.source_ip);
864
 
                RSSVAL(ubuf,8,dgram->header.source_port);
865
 
                RSSVAL(ubuf,12,dgram->header.packet_offset);
866
 
        }
867
 
 
868
 
        offset = 14;
869
 
 
870
 
        if (dgram->header.msg_type == 0x10 ||
871
 
                        dgram->header.msg_type == 0x11 ||
872
 
                        dgram->header.msg_type == 0x12) {
873
 
                offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
874
 
                offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
875
 
        }
876
 
 
877
 
        if (buf) {
878
 
                memcpy(ubuf+offset,dgram->data,dgram->datasize);
879
 
        }
880
 
        offset += dgram->datasize;
881
 
 
882
 
        /* automatically set the dgm_length
883
 
         * NOTE: RFC1002 says the dgm_length does *not*
884
 
         *       include the fourteen-byte header. crh
885
 
         */
886
 
        dgram->header.dgm_length = (offset - 14);
887
 
        if (buf) {
888
 
                RSSVAL(ubuf,10,dgram->header.dgm_length);
889
 
        }
890
 
 
891
 
        return offset;
892
 
}
893
 
 
894
 
/*******************************************************************
895
 
 Build a nmb name
896
 
*******************************************************************/
897
 
 
898
 
void make_nmb_name( struct nmb_name *n, const char *name, int type)
899
 
{
900
 
        fstring unix_name;
901
 
        memset( (char *)n, '\0', sizeof(struct nmb_name) );
902
 
        fstrcpy(unix_name, name);
903
 
        strupper_m(unix_name);
904
 
        push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE);
905
 
        n->name_type = (unsigned int)type & 0xFF;
906
 
        push_ascii(n->scope,  global_scope(), 64, STR_TERMINATE);
907
 
}
908
 
 
909
 
/*******************************************************************
910
 
  Compare two nmb names
911
 
******************************************************************/
912
 
 
913
 
bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2)
914
 
{
915
 
        return ((n1->name_type == n2->name_type) &&
916
 
                strequal(n1->name ,n2->name ) &&
917
 
                strequal(n1->scope,n2->scope));
918
 
}
919
 
 
920
 
/*******************************************************************
921
 
 Build a nmb packet ready for sending.
922
 
 If buf == NULL this is a length calculation.
923
 
******************************************************************/
924
 
 
925
 
static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb)
926
 
{
927
 
        unsigned char *ubuf = (unsigned char *)buf;
928
 
        int offset=0;
929
 
 
930
 
        if (len && len < 12) {
931
 
                return 0;
932
 
        }
933
 
 
934
 
        /* put in the header */
935
 
        if (buf) {
936
 
                RSSVAL(ubuf,offset,nmb->header.name_trn_id);
937
 
                ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
938
 
                if (nmb->header.response)
939
 
                        ubuf[offset+2] |= (1<<7);
940
 
                if (nmb->header.nm_flags.authoritative &&
941
 
                                nmb->header.response)
942
 
                        ubuf[offset+2] |= 0x4;
943
 
                if (nmb->header.nm_flags.trunc)
944
 
                        ubuf[offset+2] |= 0x2;
945
 
                if (nmb->header.nm_flags.recursion_desired)
946
 
                        ubuf[offset+2] |= 0x1;
947
 
                if (nmb->header.nm_flags.recursion_available &&
948
 
                                nmb->header.response)
949
 
                        ubuf[offset+3] |= 0x80;
950
 
                if (nmb->header.nm_flags.bcast)
951
 
                        ubuf[offset+3] |= 0x10;
952
 
                ubuf[offset+3] |= (nmb->header.rcode & 0xF);
953
 
 
954
 
                RSSVAL(ubuf,offset+4,nmb->header.qdcount);
955
 
                RSSVAL(ubuf,offset+6,nmb->header.ancount);
956
 
                RSSVAL(ubuf,offset+8,nmb->header.nscount);
957
 
                RSSVAL(ubuf,offset+10,nmb->header.arcount);
958
 
        }
959
 
 
960
 
        offset += 12;
961
 
        if (nmb->header.qdcount) {
962
 
                /* XXXX this doesn't handle a qdcount of > 1 */
963
 
                if (len) {
964
 
                        /* Length check. */
965
 
                        int extra = put_nmb_name(NULL,offset,
966
 
                                        &nmb->question.question_name);
967
 
                        if (offset + extra > len) {
968
 
                                return 0;
969
 
                        }
970
 
                }
971
 
                offset += put_nmb_name((char *)ubuf,offset,
972
 
                                &nmb->question.question_name);
973
 
                if (buf) {
974
 
                        RSSVAL(ubuf,offset,nmb->question.question_type);
975
 
                        RSSVAL(ubuf,offset+2,nmb->question.question_class);
976
 
                }
977
 
                offset += 4;
978
 
        }
979
 
 
980
 
        if (nmb->header.ancount) {
981
 
                if (len) {
982
 
                        /* Length check. */
983
 
                        int extra = put_res_rec(NULL,offset,nmb->answers,
984
 
                                        nmb->header.ancount);
985
 
                        if (offset + extra > len) {
986
 
                                return 0;
987
 
                        }
988
 
                }
989
 
                offset += put_res_rec((char *)ubuf,offset,nmb->answers,
990
 
                                nmb->header.ancount);
991
 
        }
992
 
 
993
 
        if (nmb->header.nscount) {
994
 
                if (len) {
995
 
                        /* Length check. */
996
 
                        int extra = put_res_rec(NULL,offset,nmb->nsrecs,
997
 
                                nmb->header.nscount);
998
 
                        if (offset + extra > len) {
999
 
                                return 0;
1000
 
                        }
1001
 
                }
1002
 
                offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
1003
 
                                nmb->header.nscount);
1004
 
        }
1005
 
 
1006
 
        /*
1007
 
         * The spec says we must put compressed name pointers
1008
 
         * in the following outgoing packets :
1009
 
         * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST,
1010
 
         * NAME_RELEASE_REQUEST.
1011
 
         */
1012
 
 
1013
 
        if((nmb->header.response == False) &&
1014
 
                ((nmb->header.opcode == NMB_NAME_REG_OPCODE) ||
1015
 
                (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) ||
1016
 
                (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) ||
1017
 
                (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) ||
1018
 
                (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) &&
1019
 
                (nmb->header.arcount == 1)) {
1020
 
 
1021
 
                if (len) {
1022
 
                        /* Length check. */
1023
 
                        int extra = put_compressed_name_ptr(NULL,offset,
1024
 
                                        nmb->additional,12);
1025
 
                        if (offset + extra > len) {
1026
 
                                return 0;
1027
 
                        }
1028
 
                }
1029
 
                offset += put_compressed_name_ptr(ubuf,offset,
1030
 
                                nmb->additional,12);
1031
 
        } else if (nmb->header.arcount) {
1032
 
                if (len) {
1033
 
                        /* Length check. */
1034
 
                        int extra = put_res_rec(NULL,offset,nmb->additional,
1035
 
                                nmb->header.arcount);
1036
 
                        if (offset + extra > len) {
1037
 
                                return 0;
1038
 
                        }
1039
 
                }
1040
 
                offset += put_res_rec((char *)ubuf,offset,nmb->additional,
1041
 
                        nmb->header.arcount);
1042
 
        }
1043
 
        return offset;
1044
 
}
1045
 
 
1046
 
/*******************************************************************
1047
 
 Linearise a packet.
1048
 
******************************************************************/
1049
 
 
1050
 
int build_packet(char *buf, size_t buflen, struct packet_struct *p)
1051
 
{
1052
 
        int len = 0;
1053
 
 
1054
 
        switch (p->packet_type) {
1055
 
        case NMB_PACKET:
1056
 
                len = build_nmb(buf,buflen,&p->packet.nmb);
1057
 
                break;
1058
 
 
1059
 
        case DGRAM_PACKET:
1060
 
                len = build_dgram(buf,buflen,&p->packet.dgram);
1061
 
                break;
1062
 
        }
1063
 
 
1064
 
        return len;
1065
 
}
1066
 
 
1067
 
/*******************************************************************
1068
 
 Send a packet_struct.
1069
 
******************************************************************/
1070
 
 
1071
 
bool send_packet(struct packet_struct *p)
1072
 
{
1073
 
        char buf[1024];
1074
 
        int len=0;
1075
 
 
1076
 
        memset(buf,'\0',sizeof(buf));
1077
 
 
1078
 
        len = build_packet(buf, sizeof(buf), p);
1079
 
 
1080
 
        if (!len)
1081
 
                return(False);
1082
 
 
1083
 
        return(send_udp(p->send_fd,buf,len,p->ip,p->port));
1084
 
}
1085
 
 
1086
 
/****************************************************************************
1087
 
 Receive a packet with timeout on a open UDP filedescriptor.
1088
 
 The timeout is in milliseconds
1089
 
***************************************************************************/
1090
 
 
1091
 
struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
1092
 
{
1093
 
        fd_set fds;
1094
 
        struct timeval timeout;
1095
 
        int ret;
1096
 
 
1097
 
        FD_ZERO(&fds);
1098
 
        FD_SET(fd,&fds);
1099
 
        timeout.tv_sec = t/1000;
1100
 
        timeout.tv_usec = 1000*(t%1000);
1101
 
 
1102
 
        if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
1103
 
                /* errno should be EBADF or EINVAL. */
1104
 
                DEBUG(0,("select returned -1, errno = %s (%d)\n",
1105
 
                                        strerror(errno), errno));
1106
 
                return NULL;
1107
 
        }
1108
 
 
1109
 
        if (ret == 0) /* timeout */
1110
 
                return NULL;
1111
 
 
1112
 
        if (FD_ISSET(fd,&fds))
1113
 
                return(read_packet(fd,type));
1114
 
 
1115
 
        return(NULL);
1116
 
}
1117
 
 
1118
 
/****************************************************************************
1119
 
 Receive a UDP/137 packet either via UDP or from the unexpected packet
1120
 
 queue. The packet must be a reply packet and have the specified trn_id.
1121
 
 The timeout is in milliseconds.
1122
 
***************************************************************************/
1123
 
 
1124
 
struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
1125
 
{
1126
 
        struct packet_struct *p;
1127
 
 
1128
 
        p = receive_packet(fd, NMB_PACKET, t);
1129
 
 
1130
 
        if (p && p->packet.nmb.header.response &&
1131
 
                        p->packet.nmb.header.name_trn_id == trn_id) {
1132
 
                return p;
1133
 
        }
1134
 
        if (p)
1135
 
                free_packet(p);
1136
 
 
1137
 
        /* try the unexpected packet queue */
1138
 
        return receive_unexpected(NMB_PACKET, trn_id, NULL);
1139
 
}
1140
 
 
1141
 
/****************************************************************************
1142
 
 Receive a UDP/138 packet either via UDP or from the unexpected packet
1143
 
 queue. The packet must be a reply packet and have the specified mailslot name
1144
 
 The timeout is in milliseconds.
1145
 
***************************************************************************/
1146
 
 
1147
 
struct packet_struct *receive_dgram_packet(int fd, int t,
1148
 
                const char *mailslot_name)
1149
 
{
1150
 
        struct packet_struct *p;
1151
 
 
1152
 
        p = receive_packet(fd, DGRAM_PACKET, t);
1153
 
 
1154
 
        if (p && match_mailslot_name(p, mailslot_name)) {
1155
 
                return p;
1156
 
        }
1157
 
        if (p)
1158
 
                free_packet(p);
1159
 
 
1160
 
        /* try the unexpected packet queue */
1161
 
        return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
1162
 
}
1163
 
 
1164
 
/****************************************************************************
1165
 
 See if a datagram has the right mailslot name.
1166
 
***************************************************************************/
1167
 
 
1168
 
bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name)
1169
 
{
1170
 
        struct dgram_packet *dgram = &p->packet.dgram;
1171
 
        char *buf;
1172
 
 
1173
 
        buf = &dgram->data[0];
1174
 
        buf -= 4;
1175
 
 
1176
 
        buf = smb_buf(buf);
1177
 
 
1178
 
        if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
1179
 
                return True;
1180
 
        }
1181
 
 
1182
 
        return False;
1183
 
}
1184
 
 
1185
 
/****************************************************************************
1186
 
 Return the number of bits that match between two len character buffers
1187
 
***************************************************************************/
1188
 
 
1189
 
int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len)
1190
 
{
1191
 
        size_t i, j;
1192
 
        int ret = 0;
1193
 
        for (i=0; i<len; i++) {
1194
 
                if (p1[i] != p2[i])
1195
 
                        break;
1196
 
                ret += 8;
1197
 
        }
1198
 
 
1199
 
        if (i==len)
1200
 
                return ret;
1201
 
 
1202
 
        for (j=0; j<8; j++) {
1203
 
                if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j))))
1204
 
                        break;
1205
 
                ret++;
1206
 
        }
1207
 
 
1208
 
        return ret;
1209
 
}
1210
 
 
1211
 
static unsigned char sort_ip[4];
1212
 
 
1213
 
/****************************************************************************
1214
 
 Compare two query reply records.
1215
 
***************************************************************************/
1216
 
 
1217
 
static int name_query_comp(unsigned char *p1, unsigned char *p2)
1218
 
{
1219
 
        return matching_len_bits(p2+2, sort_ip, 4) -
1220
 
                matching_len_bits(p1+2, sort_ip, 4);
1221
 
}
1222
 
 
1223
 
/****************************************************************************
1224
 
 Sort a set of 6 byte name query response records so that the IPs that
1225
 
 have the most leading bits in common with the specified address come first.
1226
 
***************************************************************************/
1227
 
 
1228
 
void sort_query_replies(char *data, int n, struct in_addr ip)
1229
 
{
1230
 
        if (n <= 1)
1231
 
                return;
1232
 
 
1233
 
        putip(sort_ip, (char *)&ip);
1234
 
 
1235
 
        qsort(data, n, 6, QSORT_CAST name_query_comp);
1236
 
}
1237
 
 
1238
 
/****************************************************************************
1239
 
 Interpret the weird netbios "name" into a unix fstring. Return the name type.
1240
 
 Returns -1 on error.
1241
 
****************************************************************************/
1242
 
 
1243
 
static int name_interpret(unsigned char *buf, size_t buf_len,
1244
 
                unsigned char *in, fstring name)
1245
 
{
1246
 
        unsigned char *end_ptr = buf + buf_len;
1247
 
        int ret;
1248
 
        unsigned int len;
1249
 
        fstring out_string;
1250
 
        unsigned char *out = (unsigned char *)out_string;
1251
 
 
1252
 
        *out=0;
1253
 
 
1254
 
        if (in >= end_ptr) {
1255
 
                return -1;
1256
 
        }
1257
 
        len = (*in++) / 2;
1258
 
 
1259
 
        if (len<1) {
1260
 
                return -1;
1261
 
        }
1262
 
 
1263
 
        while (len--) {
1264
 
                if (&in[1] >= end_ptr) {
1265
 
                        return -1;
1266
 
                }
1267
 
                if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
1268
 
                        *out = 0;
1269
 
                        return(0);
1270
 
                }
1271
 
                *out = ((in[0]-'A')<<4) + (in[1]-'A');
1272
 
                in += 2;
1273
 
                out++;
1274
 
                if (PTR_DIFF(out,out_string) >= sizeof(fstring)) {
1275
 
                        return -1;
1276
 
                }
1277
 
        }
1278
 
        ret = out[-1];
1279
 
        out[-1] = 0;
1280
 
 
1281
 
        pull_ascii_fstring(name, out_string);
1282
 
 
1283
 
        return(ret);
1284
 
}
1285
 
 
1286
 
/****************************************************************************
1287
 
 Mangle a name into netbios format.
1288
 
 Note:  <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
1289
 
****************************************************************************/
1290
 
 
1291
 
char *name_mangle(TALLOC_CTX *mem_ctx, char *In, char name_type)
1292
 
{
1293
 
        int   i;
1294
 
        int   len;
1295
 
        nstring buf;
1296
 
        char *result;
1297
 
        char *p;
1298
 
 
1299
 
        result = talloc_array(mem_ctx, char, 33 + strlen(global_scope()) + 2);
1300
 
        if (result == NULL) {
1301
 
                return NULL;
1302
 
        }
1303
 
        p = result;
1304
 
 
1305
 
        /* Safely copy the input string, In, into buf[]. */
1306
 
        if (strcmp(In,"*") == 0)
1307
 
                put_name(buf, "*", '\0', 0x00);
1308
 
        else {
1309
 
                /* We use an fstring here as mb dos names can expend x3 when
1310
 
                   going to utf8. */
1311
 
                fstring buf_unix;
1312
 
                nstring buf_dos;
1313
 
 
1314
 
                pull_ascii_fstring(buf_unix, In);
1315
 
                strupper_m(buf_unix);
1316
 
 
1317
 
                push_ascii_nstring(buf_dos, buf_unix);
1318
 
                put_name(buf, buf_dos, ' ', name_type);
1319
 
        }
1320
 
 
1321
 
        /* Place the length of the first field into the output buffer. */
1322
 
        p[0] = 32;
1323
 
        p++;
1324
 
 
1325
 
        /* Now convert the name to the rfc1001/1002 format. */
1326
 
        for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) {
1327
 
                p[i*2]     = ( (buf[i] >> 4) & 0x000F ) + 'A';
1328
 
                p[(i*2)+1] = (buf[i] & 0x000F) + 'A';
1329
 
        }
1330
 
        p += 32;
1331
 
        p[0] = '\0';
1332
 
 
1333
 
        /* Add the scope string. */
1334
 
        for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) {
1335
 
                switch( (global_scope())[i] ) {
1336
 
                        case '\0':
1337
 
                                p[0] = len;
1338
 
                                if( len > 0 )
1339
 
                                        p[len+1] = 0;
1340
 
                                return result;
1341
 
                        case '.':
1342
 
                                p[0] = len;
1343
 
                                p   += (len + 1);
1344
 
                                len  = -1;
1345
 
                                break;
1346
 
                        default:
1347
 
                                p[len+1] = (global_scope())[i];
1348
 
                                break;
1349
 
                }
1350
 
        }
1351
 
 
1352
 
        return result;
1353
 
}
1354
 
 
1355
 
/****************************************************************************
1356
 
 Find a pointer to a netbios name.
1357
 
****************************************************************************/
1358
 
 
1359
 
static unsigned char *name_ptr(unsigned char *buf, size_t buf_len, unsigned int ofs)
1360
 
{
1361
 
        unsigned char c = 0;
1362
 
 
1363
 
        if (ofs > buf_len || buf_len < 1) {
1364
 
                return NULL;
1365
 
        }
1366
 
 
1367
 
        c = *(unsigned char *)(buf+ofs);
1368
 
        if ((c & 0xC0) == 0xC0) {
1369
 
                uint16 l = 0;
1370
 
 
1371
 
                if (ofs > buf_len - 1) {
1372
 
                        return NULL;
1373
 
                }
1374
 
                l = RSVAL(buf, ofs) & 0x3FFF;
1375
 
                if (l > buf_len) {
1376
 
                        return NULL;
1377
 
                }
1378
 
                DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
1379
 
                return(buf + l);
1380
 
        } else {
1381
 
                return(buf+ofs);
1382
 
        }
1383
 
}
1384
 
 
1385
 
/****************************************************************************
1386
 
 Extract a netbios name from a buf (into a unix string) return name type.
1387
 
 Returns -1 on error.
1388
 
****************************************************************************/
1389
 
 
1390
 
int name_extract(unsigned char *buf, size_t buf_len, unsigned int ofs, fstring name)
1391
 
{
1392
 
        unsigned char *p = name_ptr(buf,buf_len,ofs);
1393
 
 
1394
 
        name[0] = '\0';
1395
 
        if (p == NULL) {
1396
 
                return -1;
1397
 
        }
1398
 
        return(name_interpret(buf,buf_len,p,name));
1399
 
}
1400
 
 
1401
 
/****************************************************************************
1402
 
 Return the total storage length of a mangled name.
1403
 
 Returns -1 on error.
1404
 
****************************************************************************/
1405
 
 
1406
 
int name_len(unsigned char *s1, size_t buf_len)
1407
 
{
1408
 
        /* NOTE: this argument _must_ be unsigned */
1409
 
        unsigned char *s = (unsigned char *)s1;
1410
 
        int len = 0;
1411
 
 
1412
 
        if (buf_len < 1) {
1413
 
                return -1;
1414
 
        }
1415
 
        /* If the two high bits of the byte are set, return 2. */
1416
 
        if (0xC0 == (*s & 0xC0)) {
1417
 
                if (buf_len < 2) {
1418
 
                        return -1;
1419
 
                }
1420
 
                return(2);
1421
 
        }
1422
 
 
1423
 
        /* Add up the length bytes. */
1424
 
        for (len = 1; (*s); s += (*s) + 1) {
1425
 
                len += *s + 1;
1426
 
                if (len > buf_len) {
1427
 
                        return -1;
1428
 
                }
1429
 
        }
1430
 
 
1431
 
        return(len);
1432
 
}