Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
28 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/nmbd/asyncdns.c

    r664 r745  
    1919
    2020#include "includes.h"
    21 
     21#include "nmbd/nmbd.h"
    2222#ifdef __OS2__
    2323#define pipe(A) os2_pipe(A)
     
    142142{
    143143        int fd1[2], fd2[2];
     144        NTSTATUS status;
    144145
    145146        CatchChild();
     
    167168        CatchSignal(SIGUSR1, SIG_IGN);
    168169        CatchSignal(SIGHUP, SIG_IGN);
    169         CatchSignal(SIGTERM, SIGNAL_CAST sig_term );
    170 
    171         if (!NT_STATUS_IS_OK(reinit_after_fork(nmbd_messaging_context(),
    172                                                nmbd_event_context(), true))) {
     170        CatchSignal(SIGTERM, sig_term);
     171
     172        status = reinit_after_fork(nmbd_messaging_context(),
     173                                   nmbd_event_context(),
     174                                   procid_self(), true);
     175
     176        if (!NT_STATUS_IS_OK(status)) {
    173177                DEBUG(0,("reinit_after_fork() failed\n"));
    174178                smb_panic("reinit_after_fork() failed");
     
    263267                        p->locked = False;
    264268
    265                         if (p->prev)
    266                                 p->prev->next = p->next;
    267                         else
    268                                 dns_queue = p->next;
    269                         if (p->next)
    270                                 p->next->prev = p->prev;
    271269                        p2 = p->next;
     270                        DLIST_REMOVE(dns_queue, p);
    272271                        free_packet(p);
    273272                        p = p2;
     
    279278        if (dns_queue) {
    280279                dns_current = dns_queue;
    281                 dns_queue = dns_queue->next;
    282                 if (dns_queue)
    283                         dns_queue->prev = NULL;
    284                 dns_current->next = NULL;
     280                DLIST_REMOVE(dns_queue, dns_queue);
    285281
    286282                if (!write_child(dns_current)) {
     
    309305        } else {
    310306                p->locked = True;
    311                 p->next = dns_queue;
    312                 p->prev = NULL;
    313                 if (p->next)
    314                         p->next->prev = p;
    315                 dns_queue = p;
     307                DLIST_ADD(dns_queue, p);
    316308        }
    317309
  • trunk/server/source3/nmbd/nmbd.c

    r596 r745  
    55   Copyright (C) Jeremy Allison 1997-2002
    66   Copyright (C) Jelmer Vernooij 2002,2003 (Conversion to popt)
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20    
    2120*/
    2221
    2322#include "includes.h"
     23#include "system/filesys.h"
     24#include "popt_common.h"
     25#include "nmbd/nmbd.h"
     26#include "serverid.h"
     27#include "messages.h"
    2428
    2529int ClientNMB       = -1;
     
    4549struct event_context *nmbd_event_context(void)
    4650{
    47         static struct event_context *ctx;
    48 
    49         if (!ctx && !(ctx = event_context_init(NULL))) {
    50                 smb_panic("Could not init nmbd event context");
    51         }
    52         return ctx;
     51        return server_event_context();
    5352}
    5453
    5554struct messaging_context *nmbd_messaging_context(void)
    5655{
    57         static struct messaging_context *ctx;
    58 
    59         if (ctx == NULL) {
    60                 ctx = messaging_init(NULL, server_id_self(),
    61                                      nmbd_event_context());
    62         }
    63         if (ctx == NULL) {
    64                 DEBUG(0, ("Could not init nmbd messaging context.\n"));
    65         }
    66         return ctx;
     56        struct messaging_context *msg_ctx = server_messaging_context();
     57        if (likely(msg_ctx != NULL)) {
     58                return msg_ctx;
     59        }
     60        smb_panic("Could not init nmbd's messaging context.\n");
     61        return NULL;
    6762}
    6863
     
    8883
    8984        gencache_stabilize();
     85        serverid_deregister(procid_self());
    9086
    9187        pidfile_unlink();
     
    258254                }
    259255
    260                 ip = ((struct sockaddr_in *)&iface->ip)->sin_addr;
    261                 nmask = ((struct sockaddr_in *)&iface->netmask)->sin_addr;
     256                ip = ((struct sockaddr_in *)(void *)&iface->ip)->sin_addr;
     257                nmask = ((struct sockaddr_in *)(void *)
     258                         &iface->netmask)->sin_addr;
    262259
    263260                /*
     
    267264                 */
    268265
    269                 if (is_loopback_addr((struct sockaddr *)&iface->ip)) {
     266                if (is_loopback_addr((struct sockaddr *)(void *)&iface->ip)) {
    270267                        DEBUG(2,("reload_interfaces: Ignoring loopback "
    271268                                "interface %s\n",
     
    306303                                continue;
    307304                        }
    308                         ip = ((struct sockaddr_in *)&iface->ip)->sin_addr;
    309                         nmask = ((struct sockaddr_in *)&iface->netmask)->sin_addr;
     305                        ip = ((struct sockaddr_in *)(void *)
     306                              &iface->ip)->sin_addr;
     307                        nmask = ((struct sockaddr_in *)(void *)
     308                                 &iface->netmask)->sin_addr;
    310309                        if (ip_equal_v4(ip, subrec->myip) &&
    311310                            ip_equal_v4(nmask, subrec->mask_ip)) {
     
    342341                 * cause us to exit.
    343342                 */
    344                 saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
     343                saved_handler = CatchSignal(SIGTERM, SIG_DFL);
    345344
    346345                /* We only count IPv4, non-loopback interfaces here. */
     
    350349                }
    351350
    352                 CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
     351                CatchSignal(SIGTERM, saved_handler);
    353352
    354353                /*
     
    447446
    448447        in_addr_to_sockaddr_storage(&ss, p->ip);
    449         pss = iface_ip((struct sockaddr *)&ss);
     448        pss = iface_ip((struct sockaddr *)(void *)&ss);
    450449
    451450        if (pss == NULL) {
     
    672671                if (lp_enhanced_browsing())
    673672                        sync_all_dmbs(t);
    674 
    675                 /*
    676                  * clear the unexpected packet queue
    677                  */
    678 
    679                 clear_unexpected(t);
    680673
    681674                /* check for new network interfaces */
     
    788781        { NULL }
    789782        };
    790         TALLOC_CTX *frame = talloc_stackframe(); /* Setup tos. */
     783        TALLOC_CTX *frame;
     784        NTSTATUS status;
     785
     786        /*
     787         * Do this before any other talloc operation
     788         */
     789        talloc_enable_null_tracking();
     790        frame = talloc_stackframe();
    791791
    792792#ifdef __OS2__
     
    868868                exit(1);
    869869        }
    870 
    871         setup_logging( argv[0], log_stdout );
     870        if (log_stdout) {
     871                setup_logging( argv[0], DEBUG_STDOUT);
     872        } else {
     873                setup_logging( argv[0], DEBUG_FILE);
     874        }
    872875
    873876        reopen_logs();
     
    907910        if (is_daemon && !opt_interactive) {
    908911                DEBUG( 2, ( "Becoming a daemon.\n" ) );
    909                 become_daemon(Fork, no_process_group);
     912                become_daemon(Fork, no_process_group, log_stdout);
    910913        }
    911914
     
    937940        pidfile_create("nmbd");
    938941
    939         if (!NT_STATUS_IS_OK(reinit_after_fork(nmbd_messaging_context(),
    940                                                nmbd_event_context(), false))) {
     942        status = reinit_after_fork(nmbd_messaging_context(),
     943                                   nmbd_event_context(),
     944                                   procid_self(), false);
     945
     946        if (!NT_STATUS_IS_OK(status)) {
    941947                DEBUG(0,("reinit_after_fork() failed\n"));
    942948                exit(1);
     
    949955
    950956        /* get broadcast messages */
    951         claim_connection(NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP);
     957
     958        if (!serverid_register(procid_self(),
     959                               FLAG_MSG_GENERAL|FLAG_MSG_DBWRAP)) {
     960                DEBUG(1, ("Could not register myself in serverid.tdb\n"));
     961                exit(1);
     962        }
    952963
    953964        messaging_register(nmbd_messaging_context(), NULL,
     
    10181029        }
    10191030
     1031        if (!nmbd_init_packet_server()) {
     1032                kill_async_dns_child();
     1033                exit(1);
     1034        }
     1035
    10201036        TALLOC_FREE(frame);
    10211037        process();
    10221038
    1023         if (dbf)
    1024                 x_fclose(dbf);
    10251039        kill_async_dns_child();
    10261040        return(0);
  • trunk/server/source3/nmbd/nmbd_become_dmb.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "../librpc/gen_ndr/svcctl.h"
     25#include "nmbd/nmbd.h"
    2426
    2527extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
  • trunk/server/source3/nmbd/nmbd_become_lmb.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
     25#include "../librpc/gen_ndr/svcctl.h"
    2426
    2527extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
  • trunk/server/source3/nmbd/nmbd_browserdb.c

    r414 r745  
    2828
    2929#include "includes.h"
     30#include "nmbd/nmbd.h"
    3031
    3132/* -------------------------------------------------------------------------- **
  • trunk/server/source3/nmbd/nmbd_browsesync.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
    2425
    2526/* This is our local master browser list database. */
     
    645646        }
    646647
     648        /* leave if we don't have to do any syncs */
     649        if (count == 0) {
     650                return;
     651        }
     652
    647653        /* sync with a probability of 1/count */
    648654        for (work=unicast_subnet->workgrouplist; work; work = work->next) {
  • trunk/server/source3/nmbd/nmbd_elections.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
     25#include "smbprofile.h"
    2426
    2527/* Election parameters. */
     
    257259******************************************************************/
    258260
    259 void process_election(struct subnet_record *subrec, struct packet_struct *p, char *buf)
     261void process_election(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
    260262{
    261263        struct dgram_packet *dgram = &p->packet.dgram;
  • trunk/server/source3/nmbd/nmbd_incomingdgrams.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "../librpc/gen_ndr/svcctl.h"
     25#include "nmbd/nmbd.h"
     26#include "smbprofile.h"
    2427
    2528extern bool found_lm_clients;
     
    9396*******************************************************************/
    9497
    95 void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
     98void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
    9699{
    97100        struct dgram_packet *dgram = &p->packet.dgram;
     
    193196*******************************************************************/
    194197
    195 void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
     198void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
    196199{
    197200        struct dgram_packet *dgram = &p->packet.dgram;
     
    250253*******************************************************************/
    251254
    252 void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf)
     255void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
    253256{
    254257        struct dgram_packet *dgram = &p->packet.dgram;
     
    365368
    366369void process_master_browser_announce(struct subnet_record *subrec,
    367                                      struct packet_struct *p,char *buf)
     370                                     struct packet_struct *p,const char *buf)
    368371{
    369372        unstring local_master_name;
     
    416419*******************************************************************/
    417420
    418 void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf, int len)
     421void process_lm_host_announce(struct subnet_record *subrec, struct packet_struct *p, const char *buf, int len)
    419422{
    420423        struct dgram_packet *dgram = &p->packet.dgram;
     
    429432        unstring source_name;
    430433        fstring comment;
    431         char *s = get_safe_str_ptr(buf,len,buf,9);
     434        char *s = get_safe_str_ptr(buf,len,discard_const_p(char, buf),9);
    432435
    433436        START_PROFILE(lm_host_announce);
     
    639642
    640643void process_get_backup_list_request(struct subnet_record *subrec,
    641                                      struct packet_struct *p,char *buf)
     644                                     struct packet_struct *p,const char *buf)
    642645{
    643646        struct dgram_packet *dgram = &p->packet.dgram;
     
    722725
    723726void process_reset_browser(struct subnet_record *subrec,
    724                                   struct packet_struct *p,char *buf)
     727                                  struct packet_struct *p,const char *buf)
    725728{
    726729        struct dgram_packet *dgram = &p->packet.dgram;
     
    774777******************************************************************/
    775778
    776 void process_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf)
     779void process_announce_request(struct subnet_record *subrec, struct packet_struct *p, const char *buf)
    777780{
    778781        struct dgram_packet *dgram = &p->packet.dgram;
     
    815818******************************************************************/
    816819
    817 void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, char *buf, int len)
     820void process_lm_announce_request(struct subnet_record *subrec, struct packet_struct *p, const char *buf, int len)
    818821{
    819822        struct dgram_packet *dgram = &p->packet.dgram;
  • trunk/server/source3/nmbd/nmbd_incomingrequests.c

    r414 r745  
    2626
    2727#include "includes.h"
     28#include "nmbd/nmbd.h"
    2829
    2930/****************************************************************************
     
    374375                /* Remove duplicate names. */
    375376                if (names_added > 1) {
     377                        /* TODO: should use a real type and
     378                           TYPESAFE_QSORT() */
    376379                        qsort( buf0, names_added, 18, QSORT_CAST status_compare );
    377380                }
  • trunk/server/source3/nmbd/nmbd_lmhosts.c

    r414 r745  
    2424
    2525#include "includes.h"
     26#include "../libcli/nbt/libnbt.h"
     27#include "nmbd/nmbd.h"
    2628
    2729/****************************************************************************
  • trunk/server/source3/nmbd/nmbd_logonnames.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "../librpc/gen_ndr/svcctl.h"
     25#include "nmbd/nmbd.h"
    2426
    2527extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
  • trunk/server/source3/nmbd/nmbd_mynames.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
    2425
    2526extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
  • trunk/server/source3/nmbd/nmbd_namelistdb.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "system/filesys.h"
     25#include "nmbd/nmbd.h"
    2426
    2527uint16 samba_nb_type = 0; /* samba's NetBIOS name type */
  • trunk/server/source3/nmbd/nmbd_namequery.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
    2425
    2526/****************************************************************************
  • trunk/server/source3/nmbd/nmbd_nameregister.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
    2425
    2526/* forward declarations */
  • trunk/server/source3/nmbd/nmbd_namerelease.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
    2425
    2526/****************************************************************************
  • trunk/server/source3/nmbd/nmbd_nodestatus.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
    2425
    2526/****************************************************************************
  • trunk/server/source3/nmbd/nmbd_packets.c

    r620 r745  
    55   Copyright (C) Luke Kenneth Casson Leighton 1994-1998
    66   Copyright (C) Jeremy Allison 1994-2003
    7    
     7
    88   This program is free software; you can redistribute it and/or modify
    99   it under the terms of the GNU General Public License as published by
    1010   the Free Software Foundation; either version 3 of the License, or
    1111   (at your option) any later version.
    12    
     12
    1313   This program is distributed in the hope that it will be useful,
    1414   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616   GNU General Public License for more details.
    17    
     17
    1818   You should have received a copy of the GNU General Public License
    1919   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20    
    2120*/
    2221
    2322#include "includes.h"
     23#include "nmbd/nmbd.h"
     24#include "../lib/util/select.h"
     25#include "system/select.h"
     26#include "libsmb/libsmb.h"
    2427
    2528extern int ClientNMB;
     
    3033
    3134bool rescan_listen_set = False;
     35
     36static struct nb_packet_server *packet_server;
     37
     38bool nmbd_init_packet_server(void)
     39{
     40        NTSTATUS status;
     41
     42        status = nb_packet_server_create(
     43                NULL, nmbd_event_context(),
     44                lp_parm_int(-1, "nmbd", "unexpected_clients", 200),
     45                &packet_server);
     46        if (!NT_STATUS_IS_OK(status)) {
     47                DEBUG(0, ("ERROR: nb_packet_server_create failed: %s\n",
     48                          nt_errstr(status)));
     49                return false;
     50        }
     51        return true;
     52}
    3253
    3354
     
    89110**************************************************************************/
    90111
    91 static void debug_browse_data(char *outbuf, int len)
     112static void debug_browse_data(const char *outbuf, int len)
    92113{
    93114        int i,j;
     
    105126                        if (x < 32 || x > 127)
    106127                                x = '.';
    107            
     128
    108129                        DEBUGADD( 4, ( "%c", x ) );
    109130                }
     
    159180                return False;
    160181        }
    161  
     182
    162183        return True;
    163184}
     
    184205                return NULL;
    185206        }
    186    
     207
    187208        memset((char *)packet,'\0',sizeof(*packet));
    188209
     
    196217        nmb->header.nm_flags.authoritative = False;
    197218        nmb->header.nm_flags.bcast = bcast;
    198  
     219
    199220        nmb->header.rcode = 0;
    200221        nmb->header.qdcount = 1;
     
    213234        packet->packet_type = NMB_PACKET;
    214235        packet->locked = False;
    215  
     236
    216237        return packet; /* Caller must free. */
    217238}
     
    237258        nmb->additional->rr_type  = RR_TYPE_NB;
    238259        nmb->additional->rr_class = RR_CLASS_IN;
    239        
     260
    240261        /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
    241262        if (nmb->header.nm_flags.bcast)
     
    243264        else
    244265                nmb->additional->ttl = lp_max_ttl();
    245        
     266
    246267        nmb->additional->rdlength = 6;
    247        
     268
    248269        set_nb_flags(nmb->additional->rdata,nb_flags);
    249        
     270
    250271        /* Set the address for the name we are registering. */
    251272        putip(&nmb->additional->rdata[2], register_ip);
    252        
     273
    253274        /*
    254275           it turns out that Jeremys code was correct, we are supposed
     
    295316{   
    296317        struct nmb_packet *nmb = NULL;
    297  
     318
    298319        nmb = &packet->packet.nmb;
    299320
    300321        nmb->header.opcode = NMB_NAME_QUERY_OPCODE;
    301322        nmb->header.arcount = 0;
    302    
     323
    303324        nmb->header.nm_flags.recursion_desired = False;
    304  
     325
    305326        DEBUG(4,("initiate_name_query_packet_from_wins_server: sending query for name %s (bcast=%s) to IP %s\n",
    306327                nmb_namestr(&nmb->question.question_name),
    307328                BOOLSTR(nmb->header.nm_flags.bcast), inet_ntoa(packet->ip)));
    308    
     329
    309330        return send_netbios_packet( packet );
    310331}
     
    350371
    351372        nmb->header.nm_flags.recursion_desired = True;
    352        
     373
    353374        if(create_and_init_additional_record(packet, nb_flags, register_ip) == False)
    354375                return False;
    355        
     376
    356377        DEBUG(4,("initiate_multihomed_name_register_packet: sending registration \
    357378for name %s IP %s (bcast=%s) to IP %s\n",
     
    479500
    480501        in_addr_to_sockaddr_storage(&ss, subrec->bcast_ip);
    481         pss = iface_ip((struct sockaddr *)&ss);
     502        pss = iface_ip((struct sockaddr *)(void *)&ss);
    482503        if (!pss || pss->ss_family != AF_INET) {
    483504                p->locked = False;
     
    589610        struct response_record *rrec;
    590611        bool ret;
    591        
     612
    592613        /* Sanity check. */
    593614        if(subrec != unicast_subnet) {
     
    599620        if(assert_check_subnet(subrec))
    600621                return NULL;
    601      
     622
    602623        if ((p = create_and_init_netbios_packet(nmbname, False, True, wins_ip)) == NULL)
    603624                return NULL;
     
    613634                return NULL;
    614635        } 
    615  
     636
    616637        if ((rrec = make_response_record(subrec,    /* subnet record. */
    617638                                         p,                     /* packet we sent. */
     
    625646                return NULL;
    626647        } 
    627        
     648
    628649        return rrec;
    629650}
     
    687708 Queue a query name packet to the broadcast address of a subnet.
    688709****************************************************************************/
    689  
     710
    690711struct response_record *queue_query_name( struct subnet_record *subrec,
    691712                          response_function resp_fn,
     
    704725
    705726        to_ip = subrec->bcast_ip;
    706  
     727
    707728        /* queries to the WINS server turn up here as queries to IP 0.0.0.0
    708729                        These need to be handled a bit differently */
     
    10121033void queue_packet(struct packet_struct *packet)
    10131034{
    1014         struct packet_struct *p;
    1015 
    1016         if (!packet_queue) {
    1017                 packet->prev = NULL;
    1018                 packet->next = NULL;
    1019                 packet_queue = packet;
    1020                 return;
    1021         }
    1022 
    1023         /* find the bottom */
    1024         for (p=packet_queue;p->next;p=p->next)
    1025                 ;
    1026 
    1027         p->next = packet;
    1028         packet->next = NULL;
    1029         packet->prev = p;
     1035        DLIST_ADD_END(packet_queue, packet, struct packet_struct *);
    10301036}
    10311037
     
    10581064****************************************************************************/
    10591065
    1060 static void process_browse_packet(struct packet_struct *p, char *buf,int len)
     1066static void process_browse_packet(struct packet_struct *p, const char *buf,int len)
    10611067{
    10621068        struct dgram_packet *dgram = &p->packet.dgram;
     
    11451151****************************************************************************/
    11461152
    1147 static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
     1153static void process_lanman_packet(struct packet_struct *p, const char *buf,int len)
    11481154{
    11491155        struct dgram_packet *dgram = &p->packet.dgram;
     
    12121218static void process_dgram(struct packet_struct *p)
    12131219{
    1214         char *buf;
    1215         char *buf2;
     1220        const char *buf;
     1221        const char *buf2;
    12161222        int len;
    12171223        struct dgram_packet *dgram = &p->packet.dgram;
     
    12191225        /* If we aren't listening to the destination name then ignore the packet */
    12201226        if (!listening(p,&dgram->dest_name)) {
    1221                         unexpected_packet(p);
     1227                        nb_packet_dispatch(packet_server, p);
    12221228                        DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
    12231229                                nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
     
    12261232
    12271233        if (dgram->header.msg_type != 0x10 && dgram->header.msg_type != 0x11 && dgram->header.msg_type != 0x12) {
    1228                 unexpected_packet(p);
     1234                nb_packet_dispatch(packet_server, p);
    12291235                /* Don't process error packets etc yet */
    12301236                DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
     
    13121318        }
    13131319
    1314         unexpected_packet(p);
     1320        nb_packet_dispatch(packet_server, p);
    13151321}
    13161322
     
    14321438                        DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
    14331439                                nmb->header.name_trn_id));
    1434                         unexpected_packet(p);
     1440                        nb_packet_dispatch(packet_server, p);
    14351441                        return NULL;
    14361442                }
     
    15831589
    15841590        while ((p = packet_queue)) {
    1585                 packet_queue = p->next;
    1586                 if (packet_queue)
    1587                         packet_queue->prev = NULL;
    1588                 p->next = p->prev = NULL;
     1591                DLIST_REMOVE(packet_queue, p);
    15891592
    15901593                switch (p->packet_type) {
     
    16741677***************************************************************************/
    16751678
    1676 static bool create_listen_fdset(fd_set **ppset, int **psock_array, int *listen_number, int *maxfd)
    1677 {
    1678         int *sock_array = NULL;
     1679struct socket_attributes {
     1680        enum packet_type type;
     1681        bool broadcast;
     1682};
     1683
     1684static bool create_listen_pollfds(struct pollfd **pfds,
     1685                                  struct socket_attributes **pattrs,
     1686                                  int *pnum_sockets)
     1687{
    16791688        struct subnet_record *subrec = NULL;
    16801689        int count = 0;
    16811690        int num = 0;
    1682         fd_set *pset = SMB_MALLOC_P(fd_set);
    1683 
    1684         if(pset == NULL) {
    1685                 DEBUG(0,("create_listen_fdset: malloc fail !\n"));
    1686                 return True;
    1687         }
    1688 
    1689         /* The Client* sockets */
    1690         count++;
     1691        struct pollfd *fds;
     1692        struct socket_attributes *attrs;
     1693
     1694        /* The ClientNMB and ClientDGRAM sockets */
     1695        count = 2;
    16911696
    16921697        /* Check that we can add all the fd's we need. */
    1693         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec))
    1694                 count++;
    1695 
    1696         /* each interface gets 4 sockets */
    1697         count *= 4;
    1698 
    1699         if(count >= FD_SETSIZE) {
    1700                 DEBUG(0,("create_listen_fdset: Too many file descriptors needed (%d). We can \
    1701 only use %d.\n", count, FD_SETSIZE));
    1702                 SAFE_FREE(pset);
    1703                 return True;
    1704         }
    1705 
    1706         if((sock_array = SMB_MALLOC_ARRAY(int, count)) == NULL) {
    1707                 DEBUG(0,("create_listen_fdset: malloc fail for socket array. size %d\n", count));
    1708                 SAFE_FREE(pset);
    1709                 return True;
    1710         }
    1711 
    1712         FD_ZERO(pset);
    1713 
    1714         /* Add in the lp_socket_address() interface on 137. */
    1715         if (ClientNMB < 0 || ClientNMB >= FD_SETSIZE) {
    1716                 errno = EBADF;
    1717                 SAFE_FREE(pset);
    1718                 return True;
    1719         }
    1720 
    1721         FD_SET(ClientNMB,pset);
    1722         sock_array[num++] = ClientNMB;
    1723         *maxfd = MAX( *maxfd, ClientNMB);
    1724 
    1725         /* the lp_socket_address() interface has only one socket */
    1726         sock_array[num++] = -1;
    1727 
    1728         /* Add in the 137 sockets on all the interfaces. */
     1698        for (subrec = FIRST_SUBNET;
     1699             subrec != NULL;
     1700             subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
     1701                count += 2;     /* nmb_sock and dgram_sock */
     1702                if (subrec->nmb_bcast != -1) {
     1703                        count += 1;
     1704                }
     1705                if (subrec->dgram_bcast != -1) {
     1706                        count += 1;
     1707                }
     1708        }
     1709
     1710        fds = TALLOC_ZERO_ARRAY(NULL, struct pollfd, count);
     1711        if (fds == NULL) {
     1712                DEBUG(1, ("create_listen_pollfds: malloc fail for fds. "
     1713                          "size %d\n", count));
     1714                return true;
     1715        }
     1716
     1717        attrs = TALLOC_ARRAY(NULL, struct socket_attributes, count);
     1718        if (fds == NULL) {
     1719                DEBUG(1, ("create_listen_pollfds: malloc fail for attrs. "
     1720                          "size %d\n", count));
     1721                SAFE_FREE(fds);
     1722                return true;
     1723        }
     1724
     1725        num = 0;
     1726
     1727        fds[num].fd = ClientNMB;
     1728        attrs[num].type = NMB_PACKET;
     1729        attrs[num].broadcast = false;
     1730        num += 1;
     1731
     1732        fds[num].fd = ClientDGRAM;
     1733        attrs[num].type = DGRAM_PACKET;
     1734        attrs[num].broadcast = false;
     1735        num += 1;
     1736
    17291737        for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
    1730                 if (subrec->nmb_sock < 0 || subrec->nmb_sock >= FD_SETSIZE) {
    1731                         /* We have to ignore sockets outside FD_SETSIZE. */
    1732                         sock_array[num++] = -1;
    1733                 } else {
    1734                         FD_SET(subrec->nmb_sock,pset);
    1735                         sock_array[num++] = subrec->nmb_sock;
    1736                         *maxfd = MAX( *maxfd, subrec->nmb_sock);
    1737                 }
    1738 
    1739                 if (subrec->nmb_bcast < 0 || subrec->nmb_bcast >= FD_SETSIZE) {
    1740                         /* We have to ignore sockets outside FD_SETSIZE. */
    1741                         sock_array[num++] = -1;
    1742                 } else {
    1743                         sock_array[num++] = subrec->nmb_bcast;
    1744                         if (subrec->nmb_bcast != -1) {
    1745                                 FD_SET(subrec->nmb_bcast,pset);
    1746                                 *maxfd = MAX( *maxfd, subrec->nmb_bcast);
    1747                         }
    1748                 }
    1749         }
    1750 
    1751         /* Add in the lp_socket_address() interface on 138. */
    1752         if (ClientDGRAM < 0 || ClientDGRAM >= FD_SETSIZE) {
    1753                 errno = EBADF;
    1754                 SAFE_FREE(pset);
    1755                 return True;
    1756         }
    1757         FD_SET(ClientDGRAM,pset);
    1758         sock_array[num++] = ClientDGRAM;
    1759         *maxfd = MAX( *maxfd, ClientDGRAM);
    1760 
    1761         /* the lp_socket_address() interface has only one socket */
    1762         sock_array[num++] = -1;
    1763 
    1764         /* Add in the 138 sockets on all the interfaces. */
    1765         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
    1766                 if (subrec->dgram_sock < 0 || subrec->dgram_sock >= FD_SETSIZE) {
    1767                         /* We have to ignore sockets outside FD_SETSIZE. */
    1768                         sock_array[num++] = -1;
    1769                 } else {
    1770                         FD_SET(subrec->dgram_sock,pset);
    1771                         sock_array[num++] = subrec->dgram_sock;
    1772                         *maxfd = MAX( *maxfd, subrec->dgram_sock);
    1773                 }
    1774 
    1775                 if (subrec->dgram_bcast < 0 || subrec->dgram_bcast >= FD_SETSIZE) {
    1776                         /* We have to ignore sockets outside FD_SETSIZE. */
    1777                         sock_array[num++] = -1;
    1778                 } else {
    1779                         sock_array[num++] = subrec->dgram_bcast;
    1780                         if (subrec->dgram_bcast != -1) {
    1781                                 FD_SET(subrec->dgram_bcast,pset);
    1782                                 *maxfd = MAX( *maxfd, subrec->dgram_bcast);
    1783                         }
    1784                 }
    1785         }
    1786 
    1787         SMB_ASSERT(count == num);
    1788 
    1789         *listen_number = count;
    1790 
    1791         SAFE_FREE(*ppset);
    1792         SAFE_FREE(*psock_array);
    1793 
    1794         *ppset = pset;
    1795         *psock_array = sock_array;
     1738
     1739                fds[num].fd = subrec->nmb_sock;
     1740                attrs[num].type = NMB_PACKET;
     1741                attrs[num].broadcast = false;
     1742                num += 1;
     1743
     1744                if (subrec->nmb_bcast != -1) {
     1745                        fds[num].fd = subrec->nmb_bcast;
     1746                        attrs[num].type = NMB_PACKET;
     1747                        attrs[num].broadcast = true;
     1748                        num += 1;
     1749                }
     1750
     1751                fds[num].fd = subrec->dgram_sock;
     1752                attrs[num].type = DGRAM_PACKET;
     1753                attrs[num].broadcast = false;
     1754                num += 1;
     1755
     1756                if (subrec->dgram_bcast != -1) {
     1757                        fds[num].fd = subrec->dgram_bcast;
     1758                        attrs[num].type = DGRAM_PACKET;
     1759                        attrs[num].broadcast = true;
     1760                        num += 1;
     1761                }
     1762        }
     1763
     1764        TALLOC_FREE(*pfds);
     1765        *pfds = fds;
     1766
     1767        TALLOC_FREE(*pattrs);
     1768        *pattrs = attrs;
     1769
     1770        *pnum_sockets = count;
    17961771
    17971772        return False;
     
    18531828                p->packet_id = packet->packet.dgram.header.dgm_id;
    18541829        } else {
     1830                SAFE_FREE(p);
    18551831                return false;
    18561832        }
     
    18821858bool listen_for_packets(bool run_election)
    18831859{
    1884         static fd_set *listen_set = NULL;
     1860        static struct pollfd *fds = NULL;
     1861        static struct socket_attributes *attrs = NULL;
    18851862        static int listen_number = 0;
    1886         static int *sock_array = NULL;
     1863        int num_sockets;
    18871864        int i;
    1888         static int maxfd = 0;
    1889 
    1890         fd_set r_fds;
    1891         fd_set w_fds;
    1892         int selrtn;
    1893         struct timeval timeout;
     1865
     1866        int pollrtn;
     1867        int timeout;
    18941868#ifndef SYNC_DNS
    18951869        int dns_fd;
     1870        int dns_pollidx = -1;
    18961871#endif
    18971872        struct processed_packet *processed_packet_list = NULL;
    18981873
    1899         if(listen_set == NULL || rescan_listen_set) {
    1900                 if(create_listen_fdset(&listen_set, &sock_array, &listen_number, &maxfd)) {
     1874        if ((fds == NULL) || rescan_listen_set) {
     1875                if (create_listen_pollfds(&fds, &attrs, &listen_number)) {
    19011876                        DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
    19021877                        return True;
     
    19051880        }
    19061881
    1907         memcpy((char *)&r_fds, (char *)listen_set, sizeof(fd_set));
    1908         FD_ZERO(&w_fds);
     1882        /*
     1883         * "fds" can be enlarged by event_add_to_poll_args
     1884         * below. Shrink it again to what was given to us by
     1885         * create_listen_pollfds.
     1886         */
     1887
     1888        fds = TALLOC_REALLOC_ARRAY(NULL, fds, struct pollfd, listen_number);
     1889        if (fds == NULL) {
     1890                return true;
     1891        }
     1892        num_sockets = listen_number;
    19091893
    19101894#ifndef SYNC_DNS
    19111895        dns_fd = asyncdns_fd();
    1912         if (dns_fd >= 0 && dns_fd < FD_SETSIZE) {
    1913                 FD_SET(dns_fd, &r_fds);
    1914                 maxfd = MAX( maxfd, dns_fd);
     1896        if (dns_fd != -1) {
     1897                fds = TALLOC_REALLOC_ARRAY(NULL, fds, struct pollfd, num_sockets+1);
     1898                if (fds == NULL) {
     1899                        return true;
     1900                }
     1901                dns_pollidx = num_sockets;
     1902                fds[num_sockets].fd = dns_fd;
     1903                num_sockets += 1;
    19151904        }
    19161905#endif
    19171906
     1907        for (i=0; i<num_sockets; i++) {
     1908                fds[i].events = POLLIN|POLLHUP;
     1909        }
     1910
    19181911        /* Process a signal and timer events now... */
    1919         if (run_events(nmbd_event_context(), 0, NULL, NULL)) {
     1912        if (run_events_poll(nmbd_event_context(), 0, NULL, 0)) {
    19201913                return False;
    19211914        }
     
    19281921         */
    19291922
    1930         timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
    1931         timeout.tv_usec = 0;
    1932 
    1933         {
    1934                 struct timeval now = timeval_current();
    1935                 event_add_to_select_args(nmbd_event_context(), &now,
    1936                                          &r_fds, &w_fds, &timeout, &maxfd);
    1937         }
    1938 
    1939         selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&timeout);
    1940 
    1941         if (run_events(nmbd_event_context(), selrtn, &r_fds, &w_fds)) {
     1923        timeout = ((run_election||num_response_packets)
     1924                   ? 1 : NMBD_SELECT_LOOP) * 1000;
     1925
     1926        event_add_to_poll_args(nmbd_event_context(), NULL,
     1927                               &fds, &num_sockets, &timeout);
     1928
     1929        pollrtn = sys_poll(fds, num_sockets, timeout);
     1930
     1931        if (run_events_poll(nmbd_event_context(), pollrtn, fds, num_sockets)) {
    19421932                return False;
    19431933        }
    19441934
    1945         if (selrtn == -1) {
     1935        if (pollrtn == -1) {
    19461936                return False;
    19471937        }
    19481938
    19491939#ifndef SYNC_DNS
    1950         if (dns_fd != -1 && FD_ISSET(dns_fd,&r_fds)) {
     1940        if ((dns_fd != -1) && (dns_pollidx != -1) &&
     1941            (fds[dns_pollidx].revents & (POLLIN|POLLHUP|POLLERR))) {
    19511942                run_dns_queue();
    19521943        }
     
    19601951                int client_port;
    19611952
    1962                 if (sock_array[i] == -1) {
     1953                if ((fds[i].revents & (POLLIN|POLLHUP|POLLERR)) == 0) {
    19631954                        continue;
    19641955                }
    19651956
    1966                 if (!FD_ISSET(sock_array[i],&r_fds)) {
    1967                         continue;
    1968                 }
    1969 
    1970                 if (i < (listen_number/2)) {
     1957                if (attrs[i].type == NMB_PACKET) {
    19711958                        /* Port 137 */
    19721959                        packet_type = NMB_PACKET;
     
    19821969                }
    19831970
    1984                 packet = read_packet(sock_array[i], packet_type);
     1971                packet = read_packet(fds[i].fd, packet_type);
    19851972                if (!packet) {
    19861973                        continue;
     
    19921979                 */
    19931980                if (lp_bind_interfaces_only() &&
    1994                     (sock_array[i] == client_fd) &&
     1981                    (fds[i].fd == client_fd) &&
    19951982                    (!is_local_net_v4(packet->ip))) {
    19961983                        DEBUG(7,("discarding %s packet sent to broadcast socket from %s:%d\n",
     
    20182005                }
    20192006
    2020 
    20212007                if (is_processed_packet(processed_packet_list, packet)) {
    20222008                        DEBUG(7,("discarding duplicate packet from %s:%d\n",
     
    20282014                store_processed_packet(&processed_packet_list, packet);
    20292015
    2030                 /*
    2031                  * 0,2,4,... are unicast sockets
    2032                  * 1,3,5,... are broadcast sockets
    2033                  *
    2034                  * on broadcast socket we only receive packets
    2035                  * and send replies via the unicast socket.
    2036                  *
    2037                  * 0,1 and 2,3 and ... belong together.
    2038                  */
    2039                 if ((i % 2) != 0) {
     2016                if (attrs[i].broadcast) {
    20402017                        /* this is a broadcast socket */
    2041                         packet->send_fd = sock_array[i-1];
     2018                        packet->send_fd = fds[i-1].fd;
    20422019                } else {
    20432020                        /* this is already a unicast socket */
    2044                         packet->send_fd = sock_array[i];
     2021                        packet->send_fd = fds[i].fd;
    20452022                }
    20462023
  • trunk/server/source3/nmbd/nmbd_processlogon.c

    r414 r745  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   NBT netbios routines and daemon - version 2
     
    66   Copyright (C) Jeremy Allison 1994-2003
    77   Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
    8    
     8
    99   This program is free software; you can redistribute it and/or modify
    1010   it under the terms of the GNU General Public License as published by
    1111   the Free Software Foundation; either version 3 of the License, or
    1212   (at your option) any later version.
    13    
     13
    1414   This program is distributed in the hope that it will be useful,
    1515   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1616   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1717   GNU General Public License for more details.
    18    
     18
    1919   You should have received a copy of the GNU General Public License
    2020   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    21    
     21
    2222   Revision History:
    2323
     
    2525
    2626#include "includes.h"
    27 #include "../libcli/netlogon.h"
     27#include "../libcli/netlogon/netlogon.h"
    2828#include "../libcli/cldap/cldap.h"
    2929#include "../lib/tsocket/tsocket.h"
     30#include "../libcli/security/security.h"
     31#include "secrets.h"
     32#include "nmbd/nmbd.h"
    3033
    3134struct sam_database_info {
     
    184187
    185188        ndr_err = ndr_pull_struct_blob(
    186                 &blob, state, NULL, &state->req,
     189                &blob, state, &state->req,
    187190                (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet);
    188191        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    270273        DATA_BLOB response = data_blob_null;
    271274
    272         status = cldap_netlogon_recv(subreq, NULL, state, &state->io);
     275        status = cldap_netlogon_recv(subreq, state, &state->io);
    273276        if (!NT_STATUS_IS_OK(status)) {
    274277                DEBUG(0,("failed to recv cldap netlogon call: %s\n",
     
    278281        }
    279282
    280         status = push_netlogon_samlogon_response(&response, state, NULL,
     283        status = push_netlogon_samlogon_response(&response, state,
    281284                                                 &state->io.out.netlogon);
    282285        if (!NT_STATUS_IS_OK(status)) {
     
    302305**************************************************************************/
    303306
    304 void process_logon_packet(struct packet_struct *p, char *buf,int len,
     307void process_logon_packet(struct packet_struct *p, const char *buf,int len,
    305308                          const char *mailslot)
    306309{
     310        fstring source_name;
    307311        struct dgram_packet *dgram = &p->packet.dgram;
    308         fstring my_name;
    309         fstring reply_name;
    310         char outbuf[1024];
    311         int code;
    312         uint16 token = 0;
    313         uint32 ntversion = 0;
    314         uint16 lmnttoken = 0;
    315         uint16 lm20token = 0;
    316         uint32 domainsidsize;
    317         bool short_request = False;
    318         char *getdc;
    319         char *uniuser; /* Unicode user name. */
    320         fstring ascuser;
    321         char *unicomp; /* Unicode computer name. */
    322         size_t size;
    323312        struct sockaddr_storage ss;
    324313        const struct sockaddr_storage *pss;
    325314        struct in_addr ip;
     315
     316        DATA_BLOB blob_in, blob_out;
     317        enum ndr_err_code ndr_err;
     318        struct nbt_netlogon_packet request;
     319        struct nbt_netlogon_response response;
     320        NTSTATUS status;
     321        const char *pdc_name;
    326322
    327323        in_addr_to_sockaddr_storage(&ss, p->ip);
     
    335331        ip = ((struct sockaddr_in *)pss)->sin_addr;
    336332
    337         memset(outbuf, 0, sizeof(outbuf));
    338 
    339333        if (!lp_domain_logons()) {
    340334                DEBUG(5,("process_logon_packet: Logon packet received from IP %s and domain \
     
    343337        }
    344338
    345         fstrcpy(my_name, global_myname());
    346 
    347         code = get_safe_SVAL(buf,len,buf,0,-1);
    348         DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n", inet_ntoa(p->ip), code));
    349 
    350         switch (code) {
    351                 case 0:
    352                         {
    353                                 fstring mach_str, user_str, getdc_str;
    354                                 char *q = buf + 2;
    355                                 char *machine = q;
    356                                 char *user = skip_string(buf,len,machine);
    357 
    358                                 if (!user || PTR_DIFF(user, buf) >= len) {
    359                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    360                                         return;
    361                                 }
    362                                 getdc = skip_string(buf,len,user);
    363 
    364                                 if (!getdc || PTR_DIFF(getdc, buf) >= len) {
    365                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    366                                         return;
    367                                 }
    368                                 q = skip_string(buf,len,getdc);
    369 
    370                                 if (!q || PTR_DIFF(q + 5, buf) > len) {
    371                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    372                                         return;
    373                                 }
    374                                 token = SVAL(q,3);
    375 
    376                                 fstrcpy(reply_name,my_name);
    377 
    378                                 pull_ascii_fstring(mach_str, machine);
    379                                 pull_ascii_fstring(user_str, user);
    380                                 pull_ascii_fstring(getdc_str, getdc);
    381 
    382                                 DEBUG(5,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
    383                                         mach_str,inet_ntoa(p->ip),user_str,token));
    384 
    385                                 q = outbuf;
    386                                 SSVAL(q, 0, 6);
    387                                 q += 2;
    388 
    389                                 fstrcpy(reply_name, "\\\\");
    390                                 fstrcat(reply_name, my_name);
    391                                 size = push_ascii(q,reply_name,
    392                                                 sizeof(outbuf)-PTR_DIFF(q, outbuf),
    393                                                 STR_TERMINATE);
    394                                 if (size == (size_t)-1) {
    395                                         return;
    396                                 }
    397                                 q = skip_string(outbuf,sizeof(outbuf),q); /* PDC name */
    398 
    399                                 SSVAL(q, 0, token);
    400                                 q += 2;
    401 
    402                                 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf));
    403 
    404                                 send_mailslot(True, getdc_str,
    405                                                 outbuf,PTR_DIFF(q,outbuf),
    406                                                 global_myname(), 0x0,
    407                                                 mach_str,
    408                                                 dgram->source_name.name_type,
    409                                                 p->ip, ip, p->port);
    410                                 break;
     339        pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
     340
     341        pdc_name = talloc_asprintf(talloc_tos(), "\\\\%s", global_myname());
     342        if (!pdc_name) {
     343                return;
     344        }
     345
     346        ZERO_STRUCT(request);
     347
     348        blob_in = data_blob_const(buf, len);
     349
     350        ndr_err = ndr_pull_struct_blob(&blob_in, talloc_tos(), &request,
     351                (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet);
     352        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     353                DEBUG(1,("process_logon_packet: Failed to pull logon packet\n"));
     354                return;
     355        }
     356
     357        if (DEBUGLEVEL >= 10) {
     358                NDR_PRINT_DEBUG(nbt_netlogon_packet, &request);
     359        }
     360
     361        DEBUG(4,("process_logon_packet: Logon from %s: code = 0x%x\n",
     362                inet_ntoa(p->ip), request.command));
     363
     364        switch (request.command) {
     365        case LOGON_REQUEST: {
     366
     367                struct nbt_netlogon_response2 response2;
     368
     369                DEBUG(5,("process_logon_packet: Domain login request from %s at IP %s user=%s token=%x\n",
     370                        request.req.logon0.computer_name, inet_ntoa(p->ip),
     371                        request.req.logon0.user_name,
     372                        request.req.logon0.lm20_token));
     373
     374                response2.command       = LOGON_RESPONSE2;
     375                response2.pdc_name      = pdc_name;
     376                response2.lm20_token    = 0xffff;
     377
     378                response.response_type = NETLOGON_RESPONSE2;
     379                response.data.response2 = response2;
     380
     381                status = push_nbt_netlogon_response(&blob_out, talloc_tos(), &response);
     382                if (!NT_STATUS_IS_OK(status)) {
     383                        DEBUG(0,("process_logon_packet: failed to push packet\n"));
     384                        return;
     385                }
     386
     387                if (DEBUGLEVEL >= 10) {
     388                        NDR_PRINT_DEBUG(nbt_netlogon_response2, &response.data.response2);
     389                }
     390
     391                send_mailslot(True, request.req.logon0.mailslot_name,
     392                                (char *)blob_out.data,
     393                                blob_out.length,
     394                                global_myname(), 0x0,
     395                                source_name,
     396                                dgram->source_name.name_type,
     397                                p->ip, ip, p->port);
     398                break;
     399        }
     400
     401        case LOGON_PRIMARY_QUERY: {
     402
     403                struct nbt_netlogon_response_from_pdc get_pdc;
     404
     405                if (!lp_domain_master()) {
     406                        /* We're not Primary Domain Controller -- ignore this */
     407                        return;
     408                }
     409
     410                DEBUG(5,("process_logon_packet: GETDC request from %s at IP %s, "
     411                        "reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
     412                        request.req.pdc.computer_name,
     413                        inet_ntoa(p->ip),
     414                        global_myname(),
     415                        lp_workgroup(),
     416                        NETLOGON_RESPONSE_FROM_PDC,
     417                        request.req.pdc.nt_version,
     418                        request.req.pdc.lmnt_token,
     419                        request.req.pdc.lm20_token));
     420
     421                get_pdc.command                 = NETLOGON_RESPONSE_FROM_PDC;
     422                get_pdc.pdc_name                = global_myname();
     423                get_pdc._pad                    = data_blob_null;
     424                get_pdc.unicode_pdc_name        = global_myname();
     425                get_pdc.domain_name             = lp_workgroup();
     426                get_pdc.nt_version              = NETLOGON_NT_VERSION_1;
     427                get_pdc.lmnt_token              = 0xffff;
     428                get_pdc.lm20_token              = 0xffff;
     429
     430                response.response_type = NETLOGON_GET_PDC;
     431                response.data.get_pdc = get_pdc;
     432
     433                status = push_nbt_netlogon_response(&blob_out, talloc_tos(), &response);
     434                if (!NT_STATUS_IS_OK(status)) {
     435                        DEBUG(0,("process_logon_packet: failed to push packet\n"));
     436                        return;
     437                }
     438
     439                if (DEBUGLEVEL >= 10) {
     440                        NDR_PRINT_DEBUG(nbt_netlogon_response_from_pdc, &response.data.get_pdc);
     441                }
     442
     443                send_mailslot(True, request.req.pdc.mailslot_name,
     444                        (char *)blob_out.data,
     445                        blob_out.length,
     446                        global_myname(), 0x0,
     447                        source_name,
     448                        dgram->source_name.name_type,
     449                        p->ip, ip, p->port);
     450
     451                return;
     452        }
     453
     454        case LOGON_SAM_LOGON_REQUEST: {
     455                char *source_addr;
     456                bool user_unknown = false;
     457
     458                struct netlogon_samlogon_response samlogon;
     459
     460                if (global_nmbd_proxy_logon) {
     461                        nmbd_proxy_logon(global_nmbd_proxy_logon,
     462                                         ip, p, (uint8_t *)buf, len);
     463                        return;
     464                }
     465
     466                source_addr = SMB_STRDUP(inet_ntoa(dgram->header.source_ip));
     467                if (source_addr == NULL) {
     468                        DEBUG(3, ("out of memory copying client"
     469                                  " address string\n"));
     470                        return;
     471                }
     472
     473                DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
     474                        request.req.logon.computer_name,
     475                        inet_ntoa(p->ip),
     476                        request.req.logon.user_name,
     477                        pdc_name,
     478                        lp_workgroup(),
     479                        LOGON_SAM_LOGON_RESPONSE,
     480                        request.req.logon.lmnt_token));
     481
     482                if (!request.req.logon.user_name) {
     483                        user_unknown = true;
     484                }
     485
     486                /* we want the simple version unless we are an ADS PDC..which means  */
     487                /* never, at least for now */
     488
     489                if ((request.req.logon.nt_version < (NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX_WITH_IP)) ||
     490                    (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
     491
     492                        struct NETLOGON_SAM_LOGON_RESPONSE_NT40 nt4;
     493
     494                        nt4.command             = user_unknown ? LOGON_SAM_LOGON_USER_UNKNOWN :
     495                                                                 LOGON_SAM_LOGON_RESPONSE;
     496                        nt4.pdc_name            = pdc_name;
     497                        nt4.user_name           = request.req.logon.user_name;
     498                        nt4.domain_name         = lp_workgroup();
     499                        nt4.nt_version          = NETLOGON_NT_VERSION_1;
     500                        nt4.lmnt_token          = 0xffff;
     501                        nt4.lm20_token          = 0xffff;
     502
     503                        samlogon.ntver = NETLOGON_NT_VERSION_1;
     504                        samlogon.data.nt4 = nt4;
     505
     506                        if (DEBUGLEVEL >= 10) {
     507                                NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_NT40, &nt4);
    411508                        }
    412 
    413                 case LOGON_PRIMARY_QUERY:
    414                         {
    415                                 fstring mach_str, getdc_str;
    416                                 fstring source_name;
    417                                 char *q = buf + 2;
    418                                 char *machine = q;
    419 
    420                                 if (!lp_domain_master()) {
    421                                         /* We're not Primary Domain Controller -- ignore this */
    422                                         return;
    423                                 }
    424 
    425                                 getdc = skip_string(buf,len,machine);
    426 
    427                                 if (!getdc || PTR_DIFF(getdc, buf) >= len) {
    428                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    429                                         return;
    430                                 }
    431                                 q = skip_string(buf,len,getdc);
    432 
    433                                 if (!q || PTR_DIFF(q, buf) >= len) {
    434                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    435                                         return;
    436                                 }
    437                                 q = ALIGN2(q, buf);
    438 
    439                                 /* At this point we can work out if this is a W9X or NT style
    440                                    request. Experiments show that the difference is wether the
    441                                    packet ends here. For a W9X request we now end with a pair of
    442                                    bytes (usually 0xFE 0xFF) whereas with NT we have two further
    443                                    strings - the following is a simple way of detecting this */
    444 
    445                                 if (len - PTR_DIFF(q, buf) <= 3) {
    446                                         short_request = True;
    447                                 } else {
    448                                         unicomp = q;
    449 
    450                                         if (PTR_DIFF(q, buf) >= len) {
    451                                                 DEBUG(0,("process_logon_packet: bad packet\n"));
    452                                                 return;
    453                                         }
    454 
    455                                         /* A full length (NT style) request */
    456                                         q = skip_unibuf(unicomp, PTR_DIFF(buf + len, unicomp));
    457 
    458                                         if (PTR_DIFF(q, buf) >= len) {
    459                                                 DEBUG(0,("process_logon_packet: bad packet\n"));
    460                                                 return;
    461                                         }
    462 
    463                                         if (len - PTR_DIFF(q, buf) > 8) {
    464                                                 /* with NT5 clients we can sometimes
    465                                                         get additional data - a length specificed string
    466                                                         containing the domain name, then 16 bytes of
    467                                                         data (no idea what it is) */
    468                                                 int dom_len = CVAL(q, 0);
    469                                                 q++;
    470                                                 if (dom_len != 0) {
    471                                                         q += dom_len + 1;
    472                                                 }
    473                                                 q += 16;
    474                                         }
    475 
    476                                         if (PTR_DIFF(q + 8, buf) > len) {
    477                                                 DEBUG(0,("process_logon_packet: bad packet\n"));
    478                                                 return;
    479                                         }
    480 
    481                                         ntversion = IVAL(q, 0);
    482                                         lmnttoken = SVAL(q, 4);
    483                                         lm20token = SVAL(q, 6);
    484                                 }
    485 
    486                                 /* Construct reply. */
    487                                 q = outbuf;
    488                                 SSVAL(q, 0, NETLOGON_RESPONSE_FROM_PDC);
    489                                 q += 2;
    490 
    491                                 fstrcpy(reply_name,my_name);
    492                                 size = push_ascii(q, reply_name,
    493                                                 sizeof(outbuf)-PTR_DIFF(q, outbuf),
    494                                                 STR_TERMINATE);
    495                                 if (size == (size_t)-1) {
    496                                         return;
    497                                 }
    498                                 q = skip_string(outbuf,sizeof(outbuf),q); /* PDC name */
    499 
    500                                 /* PDC and domain name */
    501                                 if (!short_request) {
    502                                         /* Make a full reply */
    503                                         q = ALIGN2(q, outbuf);
    504 
    505                                         q += dos_PutUniCode(q, my_name,
    506                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
    507                                                 True); /* PDC name */
    508                                         q += dos_PutUniCode(q, lp_workgroup(),
    509                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
    510                                                 True); /* Domain name*/
    511                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) {
    512                                                 return;
    513                                         }
    514                                         SIVAL(q, 0, 1); /* our nt version */
    515                                         SSVAL(q, 4, 0xffff); /* our lmnttoken */
    516                                         SSVAL(q, 6, 0xffff); /* our lm20token */
    517                                         q += 8;
    518                                 }
    519 
    520                                 /* RJS, 21-Feb-2000, we send a short reply if the request was short */
    521 
    522                                 pull_ascii_fstring(mach_str, machine);
    523 
    524                                 DEBUG(5,("process_logon_packet: GETDC request from %s at IP %s, \
    525 reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
    526                                         mach_str,inet_ntoa(p->ip), reply_name, lp_workgroup(),
    527                                         NETLOGON_RESPONSE_FROM_PDC, (uint32)ntversion, (uint32)lmnttoken,
    528                                         (uint32)lm20token ));
    529 
    530                                 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf));
    531 
    532                                 pull_ascii_fstring(getdc_str, getdc);
    533                                 pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
    534 
    535                                 send_mailslot(True, getdc_str,
    536                                         outbuf,PTR_DIFF(q,outbuf),
    537                                         global_myname(), 0x0,
    538                                         source_name,
    539                                         dgram->source_name.name_type,
    540                                         p->ip, ip, p->port);
     509                }
     510#ifdef HAVE_ADS
     511                else {
     512
     513                        struct NETLOGON_SAM_LOGON_RESPONSE_EX nt5_ex;
     514                        struct GUID domain_guid;
     515                        struct nbt_sockaddr saddr;
     516                        char *domain;
     517                        const char *hostname;
     518
     519                        saddr.sockaddr_family   = 2; /* AF_INET */
     520                        saddr.pdc_ip            = inet_ntoa(ip);
     521                        saddr.remaining         = data_blob_talloc_zero(talloc_tos(), 8); /* ??? */
     522
     523                        domain = get_mydnsdomname(talloc_tos());
     524                        if (!domain) {
     525                                DEBUG(2,("get_mydnsdomname failed.\n"));
    541526                                return;
    542527                        }
    543528
    544                 case LOGON_SAM_LOGON_REQUEST:
    545 
    546                         {
    547                                 fstring getdc_str;
    548                                 fstring source_name;
    549                                 char *source_addr;
    550                                 char *q = buf + 2;
    551                                 fstring asccomp;
    552 
    553                                 if (global_nmbd_proxy_logon) {
    554                                         nmbd_proxy_logon(global_nmbd_proxy_logon,
    555                                                          ip, p, (uint8_t *)buf, len);
    556                                         return;
    557                                 }
    558 
    559                                 q += 2;
    560 
    561                                 if (PTR_DIFF(q, buf) >= len) {
    562                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    563                                         return;
    564                                 }
    565 
    566                                 unicomp = q;
    567                                 uniuser = skip_unibuf(unicomp, PTR_DIFF(buf+len, unicomp));
    568 
    569                                 if (PTR_DIFF(uniuser, buf) >= len) {
    570                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    571                                         return;
    572                                 }
    573 
    574                                 getdc = skip_unibuf(uniuser,PTR_DIFF(buf+len, uniuser));
    575 
    576                                 if (PTR_DIFF(getdc, buf) >= len) {
    577                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    578                                         return;
    579                                 }
    580 
    581                                 q = skip_string(buf,len,getdc);
    582 
    583                                 if (!q || PTR_DIFF(q + 8, buf) >= len) {
    584                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    585                                         return;
    586                                 }
    587 
    588                                 q += 4; /* Account Control Bits - indicating username type */
    589                                 domainsidsize = IVAL(q, 0);
    590                                 q += 4;
    591 
    592                                 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST sidsize %d, len = %d\n", domainsidsize, len));
    593 
    594                                 if (domainsidsize < (len - PTR_DIFF(q, buf)) && (domainsidsize != 0)) {
    595                                         q += domainsidsize;
    596                                         q = ALIGN4(q, buf);
    597                                 }
    598 
    599                                 DEBUG(5,("process_logon_packet: len = %d PTR_DIFF(q, buf) = %ld\n", len, (unsigned long)PTR_DIFF(q, buf) ));
    600 
    601                                 if (len - PTR_DIFF(q, buf) > 8) {
    602                                         /* with NT5 clients we can sometimes
    603                                                 get additional data - a length specificed string
    604                                                 containing the domain name, then 16 bytes of
    605                                                 data (no idea what it is) */
    606                                         int dom_len = CVAL(q, 0);
    607                                         q++;
    608                                         if (dom_len < (len - PTR_DIFF(q, buf)) && (dom_len != 0)) {
    609                                                 q += dom_len + 1;
    610                                         }
    611                                         q += 16;
    612                                 }
    613 
    614                                 if (PTR_DIFF(q + 8, buf) > len) {
    615                                         DEBUG(0,("process_logon_packet: bad packet\n"));
    616                                         return;
    617                                 }
    618 
    619                                 ntversion = IVAL(q, 0);
    620                                 lmnttoken = SVAL(q, 4);
    621                                 lm20token = SVAL(q, 6);
    622                                 q += 8;
    623 
    624                                 DEBUG(3,("process_logon_packet: LOGON_SAM_LOGON_REQUEST sidsize %d ntv %d\n", domainsidsize, ntversion));
    625 
    626                                 /*
    627                                  * we respond regadless of whether the machine is in our password
    628                                  * database. If it isn't then we let smbd send an appropriate error.
    629                                  * Let's ignore the SID.
    630                                  */
    631                                 pull_ucs2_fstring(ascuser, uniuser);
    632                                 pull_ucs2_fstring(asccomp, unicomp);
    633                                 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST user %s\n", ascuser));
    634 
    635                                 fstrcpy(reply_name, "\\\\"); /* Here it wants \\LOGONSERVER. */
    636                                 fstrcat(reply_name, my_name);
    637 
    638                                 DEBUG(5,("process_logon_packet: LOGON_SAM_LOGON_REQUEST request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
    639                                         asccomp,inet_ntoa(p->ip), ascuser, reply_name, lp_workgroup(),
    640                                 LOGON_SAM_LOGON_RESPONSE ,lmnttoken));
    641 
    642                                 /* Construct reply. */
    643 
    644                                 q = outbuf;
    645                                 /* we want the simple version unless we are an ADS PDC..which means  */
    646                                 /* never, at least for now */
    647                                 if ((ntversion < 11) || (SEC_ADS != lp_security()) || (ROLE_DOMAIN_PDC != lp_server_role())) {
    648                                         if (SVAL(uniuser, 0) == 0) {
    649                                                 SSVAL(q, 0, LOGON_SAM_LOGON_USER_UNKNOWN);      /* user unknown */
    650                                         } else {
    651                                                 SSVAL(q, 0, LOGON_SAM_LOGON_RESPONSE);
    652                                         }
    653 
    654                                         q += 2;
    655 
    656                                         q += dos_PutUniCode(q, reply_name,
    657                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
    658                                                 True);
    659                                         q += dos_PutUniCode(q, ascuser,
    660                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
    661                                                 True);
    662                                         q += dos_PutUniCode(q, lp_workgroup(),
    663                                                 sizeof(outbuf) - PTR_DIFF(q, outbuf),
    664                                                 True);
    665                                 }
    666 #ifdef HAVE_ADS
    667                                 else {
    668                                         struct GUID domain_guid;
    669                                         UUID_FLAT flat_guid;
    670                                         char *domain;
    671                                         char *hostname;
    672                                         char *component, *dc, *q1;
    673                                         char *q_orig = q;
    674                                         int str_offset;
    675                                         char *saveptr = NULL;
    676 
    677                                         domain = get_mydnsdomname(talloc_tos());
    678                                         if (!domain) {
    679                                                 DEBUG(2,
    680                                                 ("get_mydnsdomname failed.\n"));
    681                                                 return;
    682                                         }
    683                                         hostname = get_myname(talloc_tos());
    684                                         if (!hostname) {
    685                                                 DEBUG(2,
    686                                                 ("get_myname failed.\n"));
    687                                                 return;
    688                                         }
    689 
    690                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) {
    691                                                 return;
    692                                         }
    693                                         if (SVAL(uniuser, 0) == 0) {
    694                                                 SIVAL(q, 0, LOGON_SAM_LOGON_USER_UNKNOWN_EX);   /* user unknown */
    695                                         } else {
    696                                                 SIVAL(q, 0, LOGON_SAM_LOGON_RESPONSE_EX);
    697                                         }
    698                                         q += 4;
    699 
    700                                         SIVAL(q, 0, NBT_SERVER_PDC|NBT_SERVER_GC|NBT_SERVER_LDAP|NBT_SERVER_DS|
    701                                                 NBT_SERVER_KDC|NBT_SERVER_TIMESERV|NBT_SERVER_CLOSEST|NBT_SERVER_WRITABLE);
    702                                         q += 4;
    703 
    704                                         /* Push Domain GUID */
    705                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < UUID_FLAT_SIZE) {
    706                                                 return;
    707                                         }
    708                                         if (False == secrets_fetch_domain_guid(domain, &domain_guid)) {
    709                                                 DEBUG(2, ("Could not fetch DomainGUID for %s\n", domain));
    710                                                 return;
    711                                         }
    712 
    713                                         smb_uuid_pack(domain_guid, &flat_guid);
    714                                         memcpy(q, &flat_guid.info, UUID_FLAT_SIZE);
    715                                         q += UUID_FLAT_SIZE;
    716 
    717                                         /* Forest */
    718                                         str_offset = q - q_orig;
    719                                         dc = domain;
    720                                         q1 = q;
    721                                         while ((component = strtok_r(dc, ".", &saveptr)) != NULL) {
    722                                                 dc = NULL;
    723                                                 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 1) {
    724                                                         return;
    725                                                 }
    726                                                 size = push_ascii(&q[1], component,
    727                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
    728                                                         0);
    729                                                 if (size == (size_t)-1 || size > 0xff) {
    730                                                         return;
    731                                                 }
    732                                                 SCVAL(q, 0, size);
    733                                                 q += (size + 1);
    734                                         }
    735 
    736                                         /* Unk0 */
    737                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 4) {
    738                                                 return;
    739                                         }
    740                                         SCVAL(q, 0, 0);
    741                                         q++;
    742 
    743                                         /* Domain */
    744                                         SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
    745                                         SCVAL(q, 1, str_offset & 0xFF);
    746                                         q += 2;
    747 
    748                                         /* Hostname */
    749                                         size = push_ascii(&q[1], hostname,
    750                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
    751                                                         0);
    752                                         if (size == (size_t)-1 || size > 0xff) {
    753                                                 return;
    754                                         }
    755                                         SCVAL(q, 0, size);
    756                                         q += (size + 1);
    757 
    758                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 3) {
    759                                                 return;
    760                                         }
    761 
    762                                         SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
    763                                         SCVAL(q, 1, str_offset & 0xFF);
    764                                         q += 2;
    765 
    766                                         /* NETBIOS of domain */
    767                                         size = push_ascii(&q[1], lp_workgroup(),
    768                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
    769                                                         STR_UPPER);
    770                                         if (size == (size_t)-1 || size > 0xff) {
    771                                                 return;
    772                                         }
    773                                         SCVAL(q, 0, size);
    774                                         q += (size + 1);
    775 
    776                                         /* Unk1 */
    777                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 2) {
    778                                                 return;
    779                                         }
    780 
    781                                         SCVAL(q, 0, 0);
    782                                         q++;
    783 
    784                                         /* NETBIOS of hostname */
    785                                         size = push_ascii(&q[1], my_name,
    786                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
    787                                                         0);
    788                                         if (size == (size_t)-1 || size > 0xff) {
    789                                                 return;
    790                                         }
    791                                         SCVAL(q, 0, size);
    792                                         q += (size + 1);
    793 
    794                                         /* Unk2 */
    795                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 4) {
    796                                                 return;
    797                                         }
    798 
    799                                         SCVAL(q, 0, 0);
    800                                         q++;
    801 
    802                                         /* User name */
    803                                         if (SVAL(uniuser, 0) != 0) {
    804                                                 size = push_ascii(&q[1], ascuser,
    805                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
    806                                                         0);
    807                                                 if (size == (size_t)-1 || size > 0xff) {
    808                                                         return;
    809                                                 }
    810                                                 SCVAL(q, 0, size);
    811                                                 q += (size + 1);
    812                                         }
    813 
    814                                         q_orig = q;
    815                                         /* Site name */
    816                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 1) {
    817                                                 return;
    818                                         }
    819                                         size = push_ascii(&q[1], "Default-First-Site-Name",
    820                                                         sizeof(outbuf) - PTR_DIFF(q+1, outbuf),
    821                                                         0);
    822                                         if (size == (size_t)-1 || size > 0xff) {
    823                                                 return;
    824                                         }
    825                                         SCVAL(q, 0, size);
    826                                         q += (size + 1);
    827 
    828                                         if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 18) {
    829                                                 return;
    830                                         }
    831 
    832                                         /* Site name (2) */
    833                                         str_offset = q - q_orig;
    834                                         SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F));
    835                                         SCVAL(q, 1, str_offset & 0xFF);
    836                                         q += 2;
    837 
    838                                         SCVAL(q, 0, PTR_DIFF(q,q1));
    839                                         SCVAL(q, 1, 0x10); /* unknown */
    840 
    841                                         SIVAL(q, 0, 0x00000002);
    842                                         q += 4; /* unknown */
    843                                         SIVAL(q, 0, ntohl(ip.s_addr));
    844                                         q += 4;
    845                                         SIVAL(q, 0, 0x00000000);
    846                                         q += 4; /* unknown */
    847                                         SIVAL(q, 0, 0x00000000);
    848                                         q += 4; /* unknown */
    849                                 }
    850 #endif
    851 
    852                                 if (sizeof(outbuf) - PTR_DIFF(q, outbuf) < 8) {
    853                                         return;
    854                                 }
    855 
    856                                 /* tell the client what version we are */
    857                                 SIVAL(q, 0, ((ntversion < 11) || (SEC_ADS != lp_security())) ? 1 : 13);
    858                                 /* our ntversion */
    859                                 SSVAL(q, 4, 0xffff); /* our lmnttoken */
    860                                 SSVAL(q, 6, 0xffff); /* our lm20token */
    861                                 q += 8;
    862 
    863                                 dump_data(4, (uint8 *)outbuf, PTR_DIFF(q, outbuf));
    864 
    865                                 pull_ascii_fstring(getdc_str, getdc);
    866                                 pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name);
    867                                 source_addr = SMB_STRDUP(inet_ntoa(dgram->header.source_ip));
    868                                 if (source_addr == NULL) {
    869                                         DEBUG(3, ("out of memory copying client"
    870                                                   " address string\n"));
    871                                         return;
    872                                 }
    873 
    874                                 /*
    875                                  * handle delay.
    876                                  * packets requeued after delay are marked as
    877                                  * locked.
    878                                  */
    879                                 if ((p->locked == False) &&
    880                                     (strlen(ascuser) == 0) &&
    881                                     delay_logon(source_name, source_addr))
    882                                 {
    883                                         struct timeval when;
    884 
    885                                         DEBUG(3, ("process_logon_packet: "
    886                                                   "delaying initial logon "
    887                                                   "reply for client %s(%s) for "
    888                                                   "%u milliseconds\n",
    889                                                   source_name, source_addr,
    890                                                   lp_init_logon_delay()));
    891 
    892                                         when = timeval_current_ofs(0,
    893                                                 lp_init_logon_delay() * 1000);
    894                                         p->locked = true;
    895                                         event_add_timed(nmbd_event_context(),
    896                                                         NULL,
    897                                                         when,
    898                                                         delayed_init_logon_handler,
    899                                                         p);
    900                                 } else {
    901                                         DEBUG(3, ("process_logon_packet: "
    902                                                   "processing delayed initial "
    903                                                   "logon reply for client "
    904                                                   "%s(%s)\n",
    905                                                   source_name, source_addr));
    906 
    907                                         p->locked = false;
    908                                         send_mailslot(true, getdc,
    909                                                 outbuf,PTR_DIFF(q,outbuf),
    910                                                 global_myname(), 0x0,
    911                                                 source_name,
    912                                                 dgram->source_name.name_type,
    913                                                 p->ip, ip, p->port);
    914                                 }
    915 
    916                                 SAFE_FREE(source_addr);
    917 
    918                                 break;
     529                        hostname = get_mydnsfullname();
     530                        if (!hostname) {
     531                                DEBUG(2,("get_mydnsfullname failed.\n"));
     532                                return;
    919533                        }
    920534
    921                 /* Announce change to UAS or SAM.  Send by the domain controller when a
    922                 replication event is required. */
    923 
    924                 case NETLOGON_ANNOUNCE_UAS:
    925                         DEBUG(5, ("Got NETLOGON_ANNOUNCE_UAS\n"));
    926                         break;
    927 
    928                 default:
    929                         DEBUG(3,("process_logon_packet: Unknown domain request %d\n",code));
     535                        if (!secrets_fetch_domain_guid(domain, &domain_guid)) {
     536                                DEBUG(2,("Could not fetch DomainGUID for %s\n", domain));
     537                                return;
     538                        }
     539
     540                        nt5_ex.command          = user_unknown ? LOGON_SAM_LOGON_USER_UNKNOWN_EX :
     541                                                                 LOGON_SAM_LOGON_RESPONSE_EX;
     542                        nt5_ex.sbz              = 0;
     543                        nt5_ex.server_type      = NBT_SERVER_PDC |
     544                                                  NBT_SERVER_GC |
     545                                                  NBT_SERVER_LDAP |
     546                                                  NBT_SERVER_DS |
     547                                                  NBT_SERVER_KDC |
     548                                                  NBT_SERVER_TIMESERV |
     549                                                  NBT_SERVER_CLOSEST |
     550                                                  NBT_SERVER_WRITABLE;
     551                        nt5_ex.domain_uuid      = domain_guid;
     552                        nt5_ex.forest           = domain;
     553                        nt5_ex.dns_domain       = domain;
     554                        nt5_ex.pdc_dns_name     = hostname;
     555                        nt5_ex.domain_name      = lp_workgroup();
     556                        nt5_ex.pdc_name         = global_myname();
     557                        nt5_ex.user_name        = request.req.logon.user_name;
     558                        nt5_ex.server_site      = "Default-First-Site-Name";
     559                        nt5_ex.client_site      = "Default-First-Site-Name";
     560                        nt5_ex.sockaddr_size    = 0x10; /* the w32 winsock addr size */
     561                        nt5_ex.sockaddr         = saddr;
     562                        nt5_ex.next_closest_site= NULL;
     563                        nt5_ex.nt_version       = NETLOGON_NT_VERSION_1 |
     564                                                  NETLOGON_NT_VERSION_5EX |
     565                                                  NETLOGON_NT_VERSION_5EX_WITH_IP;
     566                        nt5_ex.lmnt_token       = 0xffff;
     567                        nt5_ex.lm20_token       = 0xffff;
     568
     569                        samlogon.ntver = NETLOGON_NT_VERSION_1 |
     570                                         NETLOGON_NT_VERSION_5EX |
     571                                         NETLOGON_NT_VERSION_5EX_WITH_IP;
     572                        samlogon.data.nt5_ex = nt5_ex;
     573
     574                        if (DEBUGLEVEL >= 10) {
     575                                NDR_PRINT_DEBUG(NETLOGON_SAM_LOGON_RESPONSE_EX, &nt5_ex);
     576                        }
     577                }
     578#endif /* HAVE_ADS */
     579
     580                response.response_type = NETLOGON_SAMLOGON;
     581                response.data.samlogon = samlogon;
     582
     583                status = push_nbt_netlogon_response(&blob_out, talloc_tos(), &response);
     584                if (!NT_STATUS_IS_OK(status)) {
     585                        DEBUG(0,("process_logon_packet: failed to push packet\n"));
    930586                        return;
     587                }
     588
     589                /*
     590                 * handle delay.
     591                 * packets requeued after delay are marked as
     592                 * locked.
     593                 */
     594                if ((p->locked == False) &&
     595                    (strlen(request.req.logon.user_name) == 0) &&
     596                    delay_logon(source_name, source_addr))
     597                {
     598                        struct timeval when;
     599
     600                        DEBUG(3, ("process_logon_packet: "
     601                                  "delaying initial logon "
     602                                  "reply for client %s(%s) for "
     603                                  "%u milliseconds\n",
     604                                  source_name, source_addr,
     605                                  lp_init_logon_delay()));
     606
     607                        when = timeval_current_ofs(0,
     608                                lp_init_logon_delay() * 1000);
     609                        p->locked = true;
     610                        event_add_timed(nmbd_event_context(),
     611                                        NULL,
     612                                        when,
     613                                        delayed_init_logon_handler,
     614                                        p);
     615                } else {
     616                        DEBUG(3, ("process_logon_packet: "
     617                                  "processing delayed initial "
     618                                  "logon reply for client "
     619                                  "%s(%s)\n",
     620                                  source_name, source_addr));
     621                        p->locked = false;
     622                        send_mailslot(true, request.req.logon.mailslot_name,
     623                                (char *)blob_out.data,
     624                                blob_out.length,
     625                                global_myname(), 0x0,
     626                                source_name,
     627                                dgram->source_name.name_type,
     628                                p->ip, ip, p->port);
     629                }
     630
     631                SAFE_FREE(source_addr);
     632
     633                break;
     634        }
     635
     636        /* Announce change to UAS or SAM.  Send by the domain controller when a
     637        replication event is required. */
     638
     639        case NETLOGON_ANNOUNCE_UAS:
     640                DEBUG(5, ("Got NETLOGON_ANNOUNCE_UAS\n"));
     641                break;
     642
     643        default:
     644                DEBUG(3,("process_logon_packet: Unknown domain request %d\n",
     645                        request.command));
     646                return;
    931647        }
    932648}
  • trunk/server/source3/nmbd/nmbd_responserecordsdb.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "nmbd/nmbd.h"
    2425
    2526int num_response_packets = 0;
  • trunk/server/source3/nmbd/nmbd_sendannounce.c

    r414 r745  
    2525
    2626#include "includes.h"
     27#include "../librpc/gen_ndr/svcctl.h"
     28#include "nmbd/nmbd.h"
    2729
    2830extern int  updatecount;
  • trunk/server/source3/nmbd/nmbd_serverlistdb.c

    r454 r745  
    2222
    2323#include "includes.h"
     24#include "system/filesys.h"
     25#include "../librpc/gen_ndr/svcctl.h"
     26#include "nmbd/nmbd.h"
    2427
    2528int updatecount = 0;
     
    3740                DEBUG(7,("remove_all_servers: Removing server %s\n",servrec->serv.name));
    3841                nexts = servrec->next;
    39 
    40                 if (servrec->prev)
    41                         servrec->prev->next = servrec->next;
    42                 if (servrec->next)
    43                         servrec->next->prev = servrec->prev;
    44 
    45                 if (work->serverlist == servrec)
    46                         work->serverlist = servrec->next;
    47 
     42                DLIST_REMOVE(work->serverlist, servrec);
    4843                ZERO_STRUCTP(servrec);
    4944                SAFE_FREE(servrec);
     
    6055                             struct server_record *servrec)
    6156{
    62         struct server_record *servrec2;
    63 
    64         if (!work->serverlist) {
    65                 work->serverlist = servrec;
    66                 servrec->prev = NULL;
    67                 servrec->next = NULL;
    68                 return;
    69         }
    70 
    71         for (servrec2 = work->serverlist; servrec2->next; servrec2 = servrec2->next)
    72                 ;
    73 
    74         servrec2->next = servrec;
    75         servrec->next = NULL;
    76         servrec->prev = servrec2;
     57        DLIST_ADD_END(work->serverlist, servrec, struct server_record *);
    7758        work->subnet->work_changed = True;
    7859}
     
    10081void remove_server_from_workgroup(struct work_record *work, struct server_record *servrec)
    10182{
    102         if (servrec->prev)
    103                 servrec->prev->next = servrec->next;
    104         if (servrec->next)
    105                 servrec->next->prev = servrec->prev;
    106 
    107         if (work->serverlist == servrec)
    108                 work->serverlist = servrec->next;
    109 
     83        DLIST_REMOVE(work->serverlist, servrec);
    11084        ZERO_STRUCTP(servrec);
    11185        SAFE_FREE(servrec);
  • trunk/server/source3/nmbd/nmbd_subnetdb.c

    r620 r745  
    2424
    2525#include "includes.h"
     26#include "nmbd/nmbd.h"
    2627
    2728extern int global_nmb_port;
     
    260261                 */
    261262
    262                 saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
     263                saved_handler = CatchSignal(SIGTERM, SIG_DFL);
    263264
    264265                sleep(5);
     
    269270                 */
    270271
    271                 CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
     272                CatchSignal(SIGTERM, saved_handler);
    272273        }
    273274
     
    321322                                "smb.conf correct ?\n"));
    322323
    323                 saved_handler = CatchSignal( SIGTERM, SIGNAL_CAST SIG_DFL );
     324                saved_handler = CatchSignal(SIGTERM, SIG_DFL);
    324325
    325326                sleep(5);
    326327                load_interfaces();
    327328
    328                 CatchSignal( SIGTERM, SIGNAL_CAST saved_handler );
     329                CatchSignal(SIGTERM, saved_handler);
    329330                goto try_interfaces_again;
    330331        }
  • trunk/server/source3/nmbd/nmbd_synclists.c

    r414 r745  
    2828
    2929#include "includes.h"
     30#include "system/filesys.h"
     31#include "../librpc/gen_ndr/svcctl.h"
     32#include "nmbd/nmbd.h"
     33#include "libsmb/libsmb.h"
     34#include "libsmb/clirap.h"
     35#include "smbprofile.h"
    3036
    3137struct sync_record {
  • trunk/server/source3/nmbd/nmbd_winsproxy.c

    r414 r745  
    2121
    2222#include "includes.h"
     23#include "nmbd/nmbd.h"
    2324
    2425/****************************************************************************
  • trunk/server/source3/nmbd/nmbd_winsserver.c

    r454 r745  
    2222
    2323#include "includes.h"
     24#include "system/filesys.h"
     25#include "nmbd/nmbd.h"
     26#include "util_tdb.h"
    2427
    2528#define WINS_LIST "wins.dat"
     
    4952                SAFE_FREE(nr->data.ip);
    5053                SAFE_FREE(nr);
     54        }
     55}
     56
     57/****************************************************************************
     58 Delete all the temporary 1b name records on the in-memory linked list.
     59*****************************************************************************/
     60
     61static void wins_delete_all_1b_in_memory_records(void)
     62{
     63        struct name_record *nr = NULL;
     64        struct name_record *nrnext = NULL;
     65
     66        /* Delete all temporary 1b name records on the wins subnet linked list. */
     67        for( nr = wins_server_subnet->namelist; nr; nr = nrnext) {
     68                nrnext = nr->next;
     69                if (nr->name.name_type == 0x1b) {
     70                        DLIST_REMOVE(wins_server_subnet->namelist, nr);
     71                        SAFE_FREE(nr->data.ip);
     72                        SAFE_FREE(nr);
     73                }
    5174        }
    5275}
     
    405428        namerec->data.wins_flags|=flags;
    406429
    407         DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",
     430        DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: %d, flags: 0x%x, winsflags: 0x%x\n",
    408431                 namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
    409432}
     
    584607
    585608        /* Open the wins.tdb. */
    586         wins_tdb = tdb_open_log(state_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_CREAT|O_RDWR, 0600);
     609        wins_tdb = tdb_open_log(state_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
     610                        O_CREAT|O_RDWR, 0600);
    587611        if (!wins_tdb) {
    588612                DEBUG(0,("initialise_wins: failed to open wins.tdb. Error was %s\n",
     
    12511275
    12521276                        if(!find_ip_in_name_record(namerec, from_ip)) {
     1277                                /*
     1278                                 * Need to emulate the behaviour of Windows, as
     1279                                 * described in:
     1280                                 * http://lists.samba.org/archive/samba-technical/2001-October/016236.html
     1281                                 * (is there an MS reference for this
     1282                                 * somewhere?) because if the 1c list gets over
     1283                                 * 86 entries, the reply packet is too big
     1284                                 * (rdata>576 bytes) so no reply is sent.
     1285                                 *
     1286                                 * Keep only the "latest" 25 records, while
     1287                                 * ensuring that the PDC (0x1b) is never removed
     1288                                 * We do this by removing the first entry that
     1289                                 * isn't the 1b entry for the same name,
     1290                                 * on the grounds that insertion is at the end
     1291                                 * of the list, so the oldest entries are at
     1292                                 * the start.
     1293                                 *
     1294                                 */
     1295                                while(namerec->data.num_ips>=25) {
     1296                                        struct name_record *name1brec = NULL;
     1297
     1298                                        /* We only do this for 1c types. */
     1299                                        if (namerec->name.name_type != 0x1c) {
     1300                                                break;
     1301                                        }
     1302                                        DEBUG(3,("wins_process_name_registration_request: "
     1303                                                "More than 25 IPs already in "
     1304                                                "the list. Looking for a 1b "
     1305                                                "record\n"));
     1306
     1307                                        /* Ensure we have all the active 1b
     1308                                         * names on the list. */
     1309                                        wins_delete_all_1b_in_memory_records();
     1310                                        fetch_all_active_wins_1b_names();
     1311
     1312                                        /* Per the above, find the 1b record,
     1313                                           and then remove the first IP that isn't the same */
     1314                                        for(name1brec = subrec->namelist;
     1315                                                        name1brec;
     1316                                                        name1brec = name1brec->next ) {
     1317                                                if( WINS_STATE_ACTIVE(name1brec) &&
     1318                                                                name1brec->name.name_type == 0x1b) {
     1319                                                        DEBUG(3,("wins_process_name_registration_request: "
     1320                                                                "Found the #1b record "
     1321                                                                "with ip %s\n",
     1322                                                                inet_ntoa(name1brec->data.ip[0])));
     1323                                                        break;
     1324                                                }
     1325                                        }
     1326                                        if(!name1brec) {
     1327                                                DEBUG(3,("wins_process_name_registration_request: "
     1328                                                        "Didn't find a #1b name record. "
     1329                                                        "Removing the first available "
     1330                                                        "entry %s\n",
     1331                                                        inet_ntoa(namerec->data.ip[0])));
     1332                                                remove_ip_from_name_record(namerec, namerec->data.ip[0]);
     1333                                                wins_hook("delete", namerec, 0);
     1334                                        } else {
     1335                                                int i;
     1336                                                for(i=0; i<namerec->data.num_ips; i++) {
     1337                                                        /* The name1brec should only have
     1338                                                         * the single IP address in it,
     1339                                                         * so we only check against the first one*/
     1340                                                        if(!ip_equal_v4( namerec->data.ip[i], name1brec->data.ip[0])) {
     1341                                                                /* The i'th entry isn't the 1b address; delete it  */
     1342                                                                DEBUG(3,("wins_process_name_registration_request: "
     1343                                                                        "Entry at %d is not the #1b address. "
     1344                                                                        "About to remove it\n",
     1345                                                                        i));
     1346                                                                remove_ip_from_name_record(namerec, namerec->data.ip[i]);
     1347                                                                wins_hook("delete", namerec, 0);
     1348                                                                break;
     1349                                                        }
     1350                                                }
     1351                                        }
     1352                                }
     1353                                /* The list is guaranteed to be < 25 entries now
     1354                                 * - safe to add a new one  */
    12531355                                add_ip_to_name_record(namerec, from_ip);
    12541356                                /* we need to update the record for replication */
     
    18671969
    18681970        if(rcode == 0) {
     1971
     1972                int ip_count;
     1973
    18691974                ttl = (namerec->data.death_time != PERMANENT_TTL) ?  namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
     1975
     1976                /* The netbios reply packet data section is limited to 576 bytes.  In theory
     1977                 * this should give us space for 96 addresses, but in practice, 86 appears
     1978                 * to be the max (don't know why).  If we send any more than that,
     1979                 * reply_netbios_packet will fail to send a reply to avoid a memcpy buffer
     1980                 * overflow.  Keep the count to 85 and it will be ok */
     1981                ip_count=namerec->data.num_ips;
     1982                if(ip_count>85) {
     1983                        ip_count=85;   
     1984                }
    18701985
    18711986                /* Copy all known ip addresses into the return data. */
    18721987                /* Optimise for the common case of one IP address so we don't need a malloc. */
    18731988
    1874                 if( namerec->data.num_ips == 1 ) {
     1989                if( ip_count == 1 ) {
    18751990                        prdata = rdata;
    18761991                } else {
    1877                         if((prdata = (char *)SMB_MALLOC( namerec->data.num_ips * 6 )) == NULL) {
     1992                        if((prdata = (char *)SMB_MALLOC( ip_count * 6 )) == NULL) {
    18781993                                DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
    18791994                                return;
     
    18811996                }
    18821997
    1883                 for(i = 0; i < namerec->data.num_ips; i++) {
     1998                for(i = 0; i < ip_count; i++) {
    18841999                        set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
    18852000                        putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
     
    18872002
    18882003                sort_query_replies(prdata, i, p->ip);
    1889                 reply_data_len = namerec->data.num_ips * 6;
     2004                reply_data_len = ip_count * 6;
    18902005        }
    18912006
     
    20262141        struct name_record *namerec = NULL;
    20272142        struct in_addr from_ip;
    2028         bool releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
     2143        bool releasing_group_name = (nb_flags & NB_GROUP) ? True : False;
    20292144
    20302145        putip((char *)&from_ip,&nmb->additional->rdata[2]);
  • trunk/server/source3/nmbd/nmbd_workgroupdb.c

    r414 r745  
    2222
    2323#include "includes.h"
     24#include "../librpc/gen_ndr/svcctl.h"
     25#include "nmbd/nmbd.h"
    2426
    2527extern uint16 samba_nb_type;
     
    140142 
    141143        if (!work->serverlist) {
    142                 if (work->prev)
    143                         work->prev->next = work->next;
    144                 if (work->next)
    145                         work->next->prev = work->prev;
    146  
    147                 if (subrec->workgrouplist == work)
    148                         subrec->workgrouplist = work->next;
    149  
     144                DLIST_REMOVE(subrec->workgrouplist, work);
    150145                ZERO_STRUCTP(work);
    151146                SAFE_FREE(work);
Note: See TracChangeset for help on using the changeset viewer.