diff options
Diffstat (limited to 'source3/nmbd')
-rw-r--r-- | source3/nmbd/nmbd.c | 98 | ||||
-rw-r--r-- | source3/nmbd/nmbd_become_lmb.c | 3 | ||||
-rw-r--r-- | source3/nmbd/nmbd_browserdb.c | 139 | ||||
-rw-r--r-- | source3/nmbd/nmbd_browsesync.c | 8 | ||||
-rw-r--r-- | source3/nmbd/nmbd_elections.c | 2 | ||||
-rw-r--r-- | source3/nmbd/nmbd_incomingdgrams.c | 16 | ||||
-rw-r--r-- | source3/nmbd/nmbd_incomingrequests.c | 2 | ||||
-rw-r--r-- | source3/nmbd/nmbd_namelistdb.c | 4 | ||||
-rw-r--r-- | source3/nmbd/nmbd_processlogon.c | 67 | ||||
-rw-r--r-- | source3/nmbd/nmbd_sendannounce.c | 10 | ||||
-rw-r--r-- | source3/nmbd/nmbd_serverlistdb.c | 6 | ||||
-rw-r--r-- | source3/nmbd/nmbd_winsserver.c | 416 | ||||
-rw-r--r-- | source3/nmbd/nmbd_workgroupdb.c | 2 |
13 files changed, 423 insertions, 350 deletions
diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index ad5ab4d734..2801e54551 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -299,12 +299,35 @@ static BOOL reload_nmbd_services(BOOL test) } /**************************************************************************** ** + * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP + * We use buf here to return BOOL result to process() when reload_interfaces() + * detects that there are no subnets. + **************************************************************************** */ +static void msg_reload_nmbd_services(int msg_type, pid_t src, void *buf, size_t len) +{ + write_browse_list( 0, True ); + dump_all_namelists(); + reload_nmbd_services( True ); + reopen_logs(); + + if(buf) { + /* We were called from process() */ + /* If reload_interfaces() returned True */ + /* we need to shutdown if there are no subnets... */ + /* pass this info back to process() */ + *((BOOL*)buf) = reload_interfaces(0); + } +} + + +/**************************************************************************** ** The main select loop. **************************************************************************** */ static void process(void) { BOOL run_election; + BOOL no_subnets; while( True ) { time_t t = time(NULL); @@ -513,11 +536,8 @@ static void process(void) if(reload_after_sighup) { DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) ); - write_browse_list( 0, True ); - dump_all_namelists(); - reload_nmbd_services( True ); - reopen_logs(); - if(reload_interfaces(0)) + msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, (void*) &no_subnets, 0); + if(no_subnets) return; reload_after_sighup = 0; } @@ -573,8 +593,10 @@ static BOOL open_sockets(BOOL isdaemon, int port) **************************************************************************** */ int main(int argc, const char *argv[]) { - static BOOL opt_interactive = False; + pstring logfile; + static BOOL opt_interactive; poptContext pc; + int opt; struct poptOption long_options[] = { POPT_AUTOHELP {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" }, @@ -586,46 +608,47 @@ static BOOL open_sockets(BOOL isdaemon, int port) POPT_COMMON_SAMBA { NULL } }; - pstring logfile; - - global_nmb_port = NMB_PORT; - global_in_nmbd = True; - - StartupTime = time(NULL); - - sys_srandom(time(NULL) ^ sys_getpid()); - slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE); - lp_set_logfile(logfile); + global_nmb_port = NMB_PORT; - fault_setup((void (*)(void *))fault_continue ); - - /* POSIX demands that signals are inherited. If the invoking process has - * these signals masked, we will have problems, as we won't receive them. */ - BlockSignals(False, SIGHUP); - BlockSignals(False, SIGUSR1); - BlockSignals(False, SIGTERM); - - CatchSignal( SIGHUP, SIGNAL_CAST sig_hup ); - CatchSignal( SIGTERM, SIGNAL_CAST sig_term ); + pc = poptGetContext("nmbd", argc, argv, long_options, 0); + while ((opt = poptGetNextOpt(pc)) != -1) ; + poptFreeContext(pc); + global_in_nmbd = True; + + StartupTime = time(NULL); + + sys_srandom(time(NULL) ^ sys_getpid()); + + slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE); + lp_set_logfile(logfile); + + fault_setup((void (*)(void *))fault_continue ); + + /* POSIX demands that signals are inherited. If the invoking process has + * these signals masked, we will have problems, as we won't receive them. */ + BlockSignals(False, SIGHUP); + BlockSignals(False, SIGUSR1); + BlockSignals(False, SIGTERM); + + CatchSignal( SIGHUP, SIGNAL_CAST sig_hup ); + CatchSignal( SIGTERM, SIGNAL_CAST sig_term ); + #if defined(SIGFPE) - /* we are never interested in SIGFPE */ - BlockSignals(True,SIGFPE); + /* we are never interested in SIGFPE */ + BlockSignals(True,SIGFPE); #endif - /* We no longer use USR2... */ + /* We no longer use USR2... */ #if defined(SIGUSR2) - BlockSignals(True, SIGUSR2); + BlockSignals(True, SIGUSR2); #endif - pc = poptGetContext("nmbd", argc, argv, long_options, 0); - - poptFreeContext(pc); - if ( opt_interactive ) { - Fork = False; - log_stdout = True; - } + if ( opt_interactive ) { + Fork = False; + log_stdout = True; + } if ( log_stdout && Fork ) { DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n")); @@ -693,6 +716,7 @@ static BOOL open_sockets(BOOL isdaemon, int port) message_register(MSG_FORCE_ELECTION, nmbd_message_election); message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry); message_register(MSG_SHUTDOWN, nmbd_terminate); + message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services); DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) ); diff --git a/source3/nmbd/nmbd_become_lmb.c b/source3/nmbd/nmbd_become_lmb.c index 6f8e7efb1a..d390bf72e9 100644 --- a/source3/nmbd/nmbd_become_lmb.c +++ b/source3/nmbd/nmbd_become_lmb.c @@ -600,6 +600,5 @@ local_master_browser_name for workgroup %s to workgroup name.\n", } #endif - StrnCpy(work->local_master_browser_name, newname, - sizeof(work->local_master_browser_name)-1); + fstrcpy(work->local_master_browser_name, newname); } diff --git a/source3/nmbd/nmbd_browserdb.c b/source3/nmbd/nmbd_browserdb.c index a4ef98e265..4a302ddfd4 100644 --- a/source3/nmbd/nmbd_browserdb.c +++ b/source3/nmbd/nmbd_browserdb.c @@ -37,7 +37,6 @@ ubi_dlNewList( lmb_browserlist ); - /* -------------------------------------------------------------------------- ** * Functions... */ @@ -52,9 +51,9 @@ ubi_dlNewList( lmb_browserlist ); * ************************************************************************** ** */ static void remove_lmb_browser_entry( struct browse_cache_record *browc ) - { - safe_free( ubi_dlRemThis( lmb_browserlist, browc ) ); - } /* remove_lmb_browser_entry */ +{ + safe_free( ubi_dlRemThis( lmb_browserlist, browc ) ); +} /* ************************************************************************** ** * Update a browser death time. @@ -65,10 +64,10 @@ static void remove_lmb_browser_entry( struct browse_cache_record *browc ) * ************************************************************************** ** */ void update_browser_death_time( struct browse_cache_record *browc ) - { - /* Allow the new lmb to miss an announce period before we remove it. */ - browc->death_time = time(NULL) + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 ); - } /* update_browser_death_time */ +{ + /* Allow the new lmb to miss an announce period before we remove it. */ + browc->death_time = time(NULL) + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 ); +} /* ************************************************************************** ** * Create a browser entry and add it to the local master browser list. @@ -84,48 +83,47 @@ void update_browser_death_time( struct browse_cache_record *browc ) struct browse_cache_record *create_browser_in_lmb_cache( char *work_name, char *browser_name, struct in_addr ip ) - { - struct browse_cache_record *browc; - time_t now = time( NULL ); +{ + struct browse_cache_record *browc; + time_t now = time( NULL ); - browc = (struct browse_cache_record *)malloc( sizeof( *browc ) ); + browc = (struct browse_cache_record *)malloc( sizeof( *browc ) ); - if( NULL == browc ) - { - DEBUG( 0, ("create_browser_in_lmb_cache: malloc fail !\n") ); - return( NULL ); - } + if( NULL == browc ) { + DEBUG( 0, ("create_browser_in_lmb_cache: malloc fail !\n") ); + return( NULL ); + } - memset( (char *)browc, '\0', sizeof( *browc ) ); + memset( (char *)browc, '\0', sizeof( *browc ) ); - /* For a new lmb entry we want to sync with it after one minute. This - will allow it time to send out a local announce and build its - browse list. - */ - browc->sync_time = now + 60; - - /* Allow the new lmb to miss an announce period before we remove it. */ - browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 ); - - StrnCpy( browc->lmb_name, browser_name, sizeof(browc->lmb_name)-1 ); - StrnCpy( browc->work_group, work_name, sizeof(browc->work_group)-1 ); - strupper( browc->lmb_name ); - strupper( browc->work_group ); + /* For a new lmb entry we want to sync with it after one minute. This + will allow it time to send out a local announce and build its + browse list. + */ + + browc->sync_time = now + 60; + + /* Allow the new lmb to miss an announce period before we remove it. */ + browc->death_time = now + ( (CHECK_TIME_MST_ANNOUNCE + 2) * 60 ); + + pstrcpy( browc->lmb_name, browser_name); + pstrcpy( browc->work_group, work_name); + strupper_m( browc->lmb_name ); + strupper_m( browc->work_group ); - browc->ip = ip; + browc->ip = ip; - (void)ubi_dlAddTail( lmb_browserlist, browc ); - - if( DEBUGLVL( 3 ) ) - { - Debug1( "nmbd_browserdb:create_browser_in_lmb_cache()\n" ); - Debug1( " Added lmb cache entry for workgroup %s ", browc->work_group ); - Debug1( "name %s IP %s ", browc->lmb_name, inet_ntoa(ip) ); - Debug1( "ttl %d\n", (int)browc->death_time ); - } + (void)ubi_dlAddTail( lmb_browserlist, browc ); + + if( DEBUGLVL( 3 ) ) { + Debug1( "nmbd_browserdb:create_browser_in_lmb_cache()\n" ); + Debug1( " Added lmb cache entry for workgroup %s ", browc->work_group ); + Debug1( "name %s IP %s ", browc->lmb_name, inet_ntoa(ip) ); + Debug1( "ttl %d\n", (int)browc->death_time ); + } - return( browc ); - } /* create_browser_in_lmb_cache */ + return( browc ); +} /* ************************************************************************** ** * Find a browser entry in the local master browser list. @@ -137,17 +135,16 @@ struct browse_cache_record *create_browser_in_lmb_cache( char *work_name, * ************************************************************************** ** */ struct browse_cache_record *find_browser_in_lmb_cache( char *browser_name ) - { - struct browse_cache_record *browc; +{ + struct browse_cache_record *browc; - for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist ); - browc; - browc = (struct browse_cache_record *)ubi_dlNext( browc ) ) - if( strequal( browser_name, browc->lmb_name ) ) - break; + for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist ); + browc; browc = (struct browse_cache_record *)ubi_dlNext( browc ) ) + if( strequal( browser_name, browc->lmb_name ) ) + break; - return( browc ); - } /* find_browser_in_lmb_cache */ + return( browc ); +} /* ************************************************************************** ** * Expire timed out browsers in the browserlist. @@ -159,24 +156,20 @@ struct browse_cache_record *find_browser_in_lmb_cache( char *browser_name ) * ************************************************************************** ** */ void expire_lmb_browsers( time_t t ) - { - struct browse_cache_record *browc; - struct browse_cache_record *nextbrowc; - - for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist ); - browc; - browc = nextbrowc ) - { - nextbrowc = (struct browse_cache_record *)ubi_dlNext( browc ); - - if( browc->death_time < t ) - { - if( DEBUGLVL( 3 ) ) - { - Debug1( "nmbd_browserdb:expire_lmb_browsers()\n" ); - Debug1( " Removing timed out lmb entry %s\n", browc->lmb_name ); - } - remove_lmb_browser_entry( browc ); - } - } - } /* expire_lmb_browsers */ +{ + struct browse_cache_record *browc; + struct browse_cache_record *nextbrowc; + + for( browc = (struct browse_cache_record *)ubi_dlFirst( lmb_browserlist ); + browc; browc = nextbrowc ) { + nextbrowc = (struct browse_cache_record *)ubi_dlNext( browc ); + + if( browc->death_time < t ) { + if( DEBUGLVL( 3 ) ) { + Debug1( "nmbd_browserdb:expire_lmb_browsers()\n" ); + Debug1( " Removing timed out lmb entry %s\n", browc->lmb_name ); + } + remove_lmb_browser_entry( browc ); + } + } +} diff --git a/source3/nmbd/nmbd_browsesync.c b/source3/nmbd/nmbd_browsesync.c index adfefc9f27..26d4735744 100644 --- a/source3/nmbd/nmbd_browsesync.c +++ b/source3/nmbd/nmbd_browsesync.c @@ -106,6 +106,7 @@ As a local master browser, send an announce packet to the domain master browser. static void announce_local_master_browser_to_domain_master_browser( struct work_record *work) { pstring outbuf; + fstring myname; char *p; if(ismyip(work->dmb_addr)) @@ -125,8 +126,11 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_ SCVAL(p,0,ANN_MasterAnnouncement); p++; - StrnCpy(p,global_myname(),15); - strupper(p); + fstrcpy(myname, global_myname()); + strupper_m(myname); + myname[15]='\0'; + push_pstring_base(p, myname, outbuf); + p = skip_string(p,1); if( DEBUGLVL( 4 ) ) diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c index 339a27d207..b948eb9d04 100644 --- a/source3/nmbd/nmbd_elections.c +++ b/source3/nmbd/nmbd_elections.c @@ -48,7 +48,7 @@ static void send_election_dgram(struct subnet_record *subrec, const char *workgr SIVAL(p,5,timeup*1000); /* ms - Despite what the spec says. */ p += 13; pstrcpy_base(p, server_name, outbuf); - strupper(p); + strupper_m(p); p = skip_string(p,1); send_mailslot(False, BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf), diff --git a/source3/nmbd/nmbd_incomingdgrams.c b/source3/nmbd/nmbd_incomingdgrams.c index cd6954fc62..80465ada0d 100644 --- a/source3/nmbd/nmbd_incomingdgrams.c +++ b/source3/nmbd/nmbd_incomingdgrams.c @@ -172,7 +172,7 @@ void process_host_announce(struct subnet_record *subrec, struct packet_struct *p /* Update the record. */ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY; update_server_ttl( servrec, ttl); - StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1); + fstrcpy(servrec->serv.comment,comment); } } else @@ -343,7 +343,7 @@ a local master browser for workgroup %s and we think we are master. Forcing elec /* Update the record. */ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY; update_server_ttl(servrec, ttl); - StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1); + fstrcpy(servrec->serv.comment,comment); } set_workgroup_local_master_browser_name( work, server_name ); @@ -520,7 +520,7 @@ originate from OS/2 Warp client. Ignoring packet.\n")); /* Update the record. */ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY; update_server_ttl( servrec, ttl); - StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1); + fstrcpy(servrec->serv.comment,comment); } } else @@ -559,6 +559,7 @@ static void send_backup_list_response(struct subnet_record *subrec, #if 0 struct server_record *servrec; #endif + fstring myname; memset(outbuf,'\0',sizeof(outbuf)); @@ -578,8 +579,11 @@ static void send_backup_list_response(struct subnet_record *subrec, /* We always return at least one name - our own. */ count = 1; - StrnCpy(p,global_myname(),15); - strupper(p); + fstrcpy(myname, global_myname()); + strupper_m(myname); + myname[15]='\0'; + push_pstring_base(p, myname, outbuf); + p = skip_string(p,1); /* Look for backup browsers in this workgroup. */ @@ -610,7 +614,7 @@ static void send_backup_list_response(struct subnet_record *subrec, continue; StrnCpy(p, servrec->serv.name, 15); - strupper(p); + strupper_m(p); count++; DEBUG(5,("send_backup_list_response: Adding server %s number %d\n", diff --git a/source3/nmbd/nmbd_incomingrequests.c b/source3/nmbd/nmbd_incomingrequests.c index a8168566f1..a3faf5e104 100644 --- a/source3/nmbd/nmbd_incomingrequests.c +++ b/source3/nmbd/nmbd_incomingrequests.c @@ -364,7 +364,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name), /* Start with the name. */ memset(buf,'\0',18); slprintf(buf, 17, "%-15.15s",namerec->name.name); - strupper(buf); + strupper_m(buf); /* Put the name type and netbios flags in the buffer. */ buf[15] = name_type; diff --git a/source3/nmbd/nmbd_namelistdb.c b/source3/nmbd/nmbd_namelistdb.c index 932d926a91..3f6d2f3b64 100644 --- a/source3/nmbd/nmbd_namelistdb.c +++ b/source3/nmbd/nmbd_namelistdb.c @@ -49,8 +49,8 @@ static void upcase_name( struct nmb_name *target, struct nmb_name *source ) if( NULL != source ) (void)memcpy( target, source, sizeof( struct nmb_name ) ); - strupper( target->name ); - strupper( target->scope ); + strupper_m( target->name ); + strupper_m( target->scope ); /* fudge... We're using a byte-by-byte compare, so we must be sure that * unused space doesn't have garbage in it. diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index a702fc3015..42edcc871f 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -304,19 +304,19 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", pstring hostname; char *component, *dc, *q1; uint8 size; + char *q_orig = q; + int str_offset; get_mydomname(domain); get_myname(hostname); if (SVAL(uniuser, 0) == 0) { - SSVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */ + SIVAL(q, 0, SAMLOGON_AD_UNK_R); /* user unknown */ } else { - SSVAL(q, 0, SAMLOGON_AD_R); + SIVAL(q, 0, SAMLOGON_AD_R); } - q += 2; + q += 4; - SSVAL(q, 0, 0); - q += 2; SIVAL(q, 0, ADS_PDC|ADS_GC|ADS_LDAP|ADS_DS| ADS_KDC|ADS_TIMESERV|ADS_CLOSEST|ADS_WRITABLE); q += 4; @@ -329,7 +329,8 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", memcpy(q, &domain_guid, sizeof(domain_guid)); q += sizeof(domain_guid); - /* Push domain components */ + /* Forest */ + str_offset = q - q_orig; dc = domain; q1 = q; while ((component = strtok(dc, "."))) { @@ -338,44 +339,60 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", SCVAL(q, 0, size); q += (size + 1); } + + /* Unk0 */ SCVAL(q, 0, 0); q++; - SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */ - q += 2; /* it must follow the domain name. */ - /* Push dns host name */ + /* Domain */ + SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); + SCVAL(q, 1, str_offset & 0xFF); + q += 2; + + /* Hostname */ size = push_ascii(&q[1], hostname, -1, 0); SCVAL(q, 0, size); q += (size + 1); - SSVAL(q, 0, 0x18c0); /* not sure what this is for, but */ - q += 2; /* it must follow the domain name. */ + SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); + SCVAL(q, 1, str_offset & 0xFF); + q += 2; - /* Push NETBIOS of domain */ + /* NETBIOS of domain */ size = push_ascii(&q[1], lp_workgroup(), -1, STR_UPPER); SCVAL(q, 0, size); q += (size + 1); - SCVAL(q, 0, 0); q++; /* is this a null terminator or empty field */ - /* null terminator would not be needed because size is included */ - /* Push NETBIOS of hostname */ + /* Unk1 */ + SCVAL(q, 0, 0); q++; + + /* NETBIOS of hostname */ size = push_ascii(&q[1], my_name, -1, 0); SCVAL(q, 0, size); q += (size + 1); - SCVAL(q, 0, 0); q++; /* null terminator or empty field? */ - /* Push user account */ - size = push_ascii(&q[1], ascuser, -1, 0); - SCVAL(q, 0, size); - q += (size + 1); + /* Unk2 */ + SCVAL(q, 0, 0); q++; + + /* User name */ + if (SVAL(uniuser, 0) != 0) { + size = push_ascii(&q[1], ascuser, -1, 0); + SCVAL(q, 0, size); + q += (size + 1); + } - /* Push 'Default-First-Site-Name' */ + q_orig = q; + /* Site name */ size = push_ascii(&q[1], "Default-First-Site-Name", -1, 0); SCVAL(q, 0, size); q += (size + 1); - SSVAL(q, 0, 0xc000); /* unknown */ - SCVAL(q, 2, PTR_DIFF(q,q1)); - SCVAL(q, 3, 0x10); /* unknown */ - q += 4; + /* Site name (2) */ + str_offset = q - q_orig; + SCVAL(q, 0, 0xc0 | ((str_offset >> 8) & 0x3F)); + SCVAL(q, 1, str_offset & 0xFF); + q += 2; + + SCVAL(q, 0, PTR_DIFF(q,q1)); + SCVAL(q, 1, 0x10); /* unknown */ SIVAL(q, 0, 0x00000002); q += 4; /* unknown */ SIVAL(q, 0, (iface_ip(p->ip))->s_addr); q += 4; diff --git a/source3/nmbd/nmbd_sendannounce.c b/source3/nmbd/nmbd_sendannounce.c index 40d07aae16..353717ee62 100644 --- a/source3/nmbd/nmbd_sendannounce.c +++ b/source3/nmbd/nmbd_sendannounce.c @@ -142,7 +142,7 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type p += 10; /*StrnCpy(p,server_name,15); - strupper(p); + strupper_m(p); p = skip_string(p,1); pstrcpy(p,server_comment); p = skip_string(p,1);*/ @@ -555,6 +555,7 @@ void browse_sync_remote(time_t t) struct work_record *work; pstring outbuf; char *p; + fstring myname; if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL))) return; @@ -589,8 +590,11 @@ for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name )); SCVAL(p,0,ANN_MasterAnnouncement); p++; - StrnCpy(p,global_myname(),15); - strupper(p); + fstrcpy(myname, global_myname()); + strupper_m(myname); + myname[15]='\0'; + push_pstring_base(p, myname, outbuf); + p = skip_string(p,1); for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) diff --git a/source3/nmbd/nmbd_serverlistdb.c b/source3/nmbd/nmbd_serverlistdb.c index ee0c021d5d..2484a7f830 100644 --- a/source3/nmbd/nmbd_serverlistdb.c +++ b/source3/nmbd/nmbd_serverlistdb.c @@ -153,9 +153,9 @@ workgroup %s. This is a bug.\n", name, work->work_group)); servrec->subnet = work->subnet; - StrnCpy(servrec->serv.name,name,sizeof(servrec->serv.name)-1); - StrnCpy(servrec->serv.comment,comment,sizeof(servrec->serv.comment)-1); - strupper(servrec->serv.name); + fstrcpy(servrec->serv.name,name); + fstrcpy(servrec->serv.comment,comment); + strupper_m(servrec->serv.name); servrec->serv.type = servertype; update_server_ttl(servrec, ttl); diff --git a/source3/nmbd/nmbd_winsserver.c b/source3/nmbd/nmbd_winsserver.c index 47ce8119f3..eafff03b76 100644 --- a/source3/nmbd/nmbd_winsserver.c +++ b/source3/nmbd/nmbd_winsserver.c @@ -22,7 +22,7 @@ #include "includes.h" -#define WINS_LIST "wins.tdb" +#define WINS_LIST "wins.dat" #define WINS_VERSION 1 /**************************************************************************** @@ -221,123 +221,177 @@ Load or create the WINS database. BOOL initialise_wins(void) { - time_t time_now = time(NULL); - TDB_CONTEXT *tdb; - TDB_DATA kbuf, dbuf, newkey; - struct name_record *namerec = NULL; - struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0"); + time_t time_now = time(NULL); + XFILE *fp; + pstring line; - DEBUG(2,("initialise_wins: started\n")); + if(!lp_we_are_a_wins_server()) + return True; - if(!lp_we_are_a_wins_server()) - return True; + add_samba_names_to_subnet(wins_server_subnet); - add_samba_names_to_subnet(wins_server_subnet); + if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL) + { + DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n", + WINS_LIST, strerror(errno) )); + return True; + } - tdb = tdb_open_log(lock_path(WINS_LIST), 0, TDB_DEFAULT, O_RDONLY, 0600); - if (!tdb) { - DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n", WINS_LIST, strerror(errno) )); - return True; - } + while (!x_feof(fp)) + { + pstring name_str, ip_str, ttl_str, nb_flags_str; + unsigned int num_ips; + pstring name; + struct in_addr *ip_list; + int type = 0; + int nb_flags; + int ttl; + const char *ptr; + char *p; + BOOL got_token; + BOOL was_ip; + int i; + unsigned hash; + int version; + + /* Read a line from the wins.dat file. Strips whitespace + from the beginning and end of the line. + */ + if (!fgets_slash(line,sizeof(pstring),fp)) + continue; + + if (*line == '#') + continue; + + if (strncmp(line,"VERSION ", 8) == 0) { + if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 || + version != WINS_VERSION) { + DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line)); + x_fclose(fp); + return True; + } + continue; + } - if (tdb_fetch_int32(tdb, INFO_VERSION) != WINS_VERSION) { - DEBUG(0,("Discarding invalid wins.tdb file\n")); - tdb_close(tdb); - return True; - } + ptr = line; - for (kbuf = tdb_firstkey(tdb); - kbuf.dptr; - newkey = tdb_nextkey(tdb, kbuf), safe_free(kbuf.dptr), kbuf=newkey) { - - fstring name_type; - pstring name, ip_str; - char *p; - int type = 0; - int nb_flags; - int ttl; - unsigned int num_ips; - int high, low; - struct in_addr wins_ip; - struct in_addr *ip_list; - int wins_flags; - int len,i; - - if (strncmp(kbuf.dptr, ENTRY_PREFIX, strlen(ENTRY_PREFIX)) != 0) - continue; - - dbuf = tdb_fetch(tdb, kbuf); - if (!dbuf.dptr) - continue; + /* + * Now we handle multiple IP addresses per name we need + * to iterate over the line twice. The first time to + * determine how many IP addresses there are, the second + * time to actually parse them into the ip_list array. + */ - fstrcpy(name_type, kbuf.dptr+strlen(ENTRY_PREFIX)); + if (!next_token(&ptr,name_str,NULL,sizeof(name_str))) + { + DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line )); + continue; + } - pstrcpy(name, name_type); + if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str))) + { + DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line )); + continue; + } - if((p = strchr(name,'#')) != NULL) { - *p = 0; - sscanf(p+1,"%x",&type); - } + /* + * Determine the number of IP addresses per line. + */ + num_ips = 0; + do + { + got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str)); + was_ip = False; - len = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddfddd", - &nb_flags, &high, &low, - ip_str, &ttl, &num_ips, &wins_flags); + if(got_token && strchr(ip_str, '.')) + { + num_ips++; + was_ip = True; + } + } while( got_token && was_ip); - wins_ip=*interpret_addr2(ip_str); + if(num_ips == 0) + { + DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line )); + continue; + } - /* Don't reload replica records */ - if (!ip_equal(wins_ip, our_fake_ip)) { - SAFE_FREE(dbuf.dptr); - continue; - } + if(!got_token) + { + DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line )); + continue; + } - /* Don't reload released or tombstoned records */ - if ((wins_flags&WINS_STATE_MASK) != WINS_ACTIVE) { - SAFE_FREE(dbuf.dptr); - continue; - } + /* Allocate the space for the ip_list. */ + if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) + { + DEBUG(0,("initialise_wins: Malloc fail !\n")); + return False; + } + + /* Reset and re-parse the line. */ + ptr = line; + next_token(&ptr,name_str,NULL,sizeof(name_str)); + next_token(&ptr,ttl_str,NULL,sizeof(ttl_str)); + for(i = 0; i < num_ips; i++) + { + next_token(&ptr, ip_str, NULL, sizeof(ip_str)); + ip_list[i] = *interpret_addr2(ip_str); + } + next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str)); - /* Allocate the space for the ip_list. */ - if((ip_list = (struct in_addr *)malloc( num_ips * sizeof(struct in_addr))) == NULL) { - SAFE_FREE(dbuf.dptr); - DEBUG(0,("initialise_wins: Malloc fail !\n")); - return False; - } + /* + * Deal with SELF or REGISTER name encoding. Default is REGISTER + * for compatibility with old nmbds. + */ - for (i = 0; i < num_ips; i++) { - len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f", ip_str); - ip_list[i] = *interpret_addr2(ip_str); - } + if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') + { + DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line)); + SAFE_FREE(ip_list); + continue; + } + + if(nb_flags_str[strlen(nb_flags_str)-1] == 'R') + nb_flags_str[strlen(nb_flags_str)-1] = '\0'; + + /* Netbios name. # divides the name from the type (hex): netbios#xx */ + pstrcpy(name,name_str); + + if((p = strchr(name,'#')) != NULL) + { + *p = 0; + sscanf(p+1,"%x",&type); + } + + /* Decode the netbios flags (hex) and the time-to-live (in seconds). */ + sscanf(nb_flags_str,"%x",&nb_flags); + sscanf(ttl_str,"%d",&ttl); - /* add all entries that have 60 seconds or more to live */ - if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) { - if(ttl != PERMANENT_TTL) - ttl -= time_now; + /* add all entries that have 60 seconds or more to live */ + if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) + { + if(ttl != PERMANENT_TTL) + ttl -= time_now; - DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n", - name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); - - namerec=add_name_to_subnet( wins_server_subnet, name, type, nb_flags, - ttl, REGISTER_NAME, num_ips, ip_list); - if (namerec!=NULL) { - update_wins_owner(namerec, wins_ip); - update_wins_flag(namerec, wins_flags); - /* we don't reload the ID, on startup we restart at 1 */ - get_global_id_and_update(&namerec->data.id, True); - } + DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n", + name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); - } else { - DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n", - name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); - } + (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags, + ttl, REGISTER_NAME, num_ips, ip_list ); - SAFE_FREE(dbuf.dptr); - SAFE_FREE(ip_list); - } + } + else + { + DEBUG(4, ("initialise_wins: not adding name (ttl problem) %s#%02x ttl = %d first IP %s flags = %2x\n", + name, type, ttl, inet_ntoa(ip_list[0]), nb_flags)); + } + + SAFE_FREE(ip_list); + } - tdb_close(tdb); - DEBUG(2,("initialise_wins: done\n")); - return True; + x_fclose(fp); + return True; } /**************************************************************************** @@ -1765,113 +1819,87 @@ we are not the wins owner !\n", nmb_namestr(&namerec->name))); ******************************************************************/ void wins_write_database(BOOL background) { - struct name_record *namerec; - pstring fname, fnamenew; - TDB_CONTEXT *tdb; - TDB_DATA kbuf, dbuf; - pstring key, buf; - int len; - int num_record=0; - SMB_BIG_UINT id; - - if(!lp_we_are_a_wins_server()) - return; - - /* we will do the writing in a child process to ensure that the parent - doesn't block while this is done */ - if (background) { - CatchChild(); - if (sys_fork()) { - return; - } - } - - slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST); - all_string_sub(fname,"//", "/", 0); - slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid()); - - tdb = tdb_open_log(fnamenew, 0, TDB_DEFAULT, O_RDWR|O_CREAT|O_TRUNC, 0644); - if (!tdb) { - DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno))); - if (background) - _exit(0); - return; - } - - DEBUG(3,("wins_write_database: Dump of WINS name list.\n")); - - tdb_store_int32(tdb, INFO_VERSION, WINS_VERSION); - - for (namerec = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); - namerec; - namerec = (struct name_record *)ubi_trNext( namerec ) ) { - - int i; - struct tm *tm; - - DEBUGADD(3,("%-19s ", nmb_namestr(&namerec->name) )); + struct name_record *namerec; + pstring fname, fnamenew; - if( namerec->data.death_time != PERMANENT_TTL ) { - char *ts, *nl; - - tm = LocalTime(&namerec->data.death_time); - ts = asctime(tm); - nl = strrchr_m( ts, '\n' ); - if( NULL != nl ) - *nl = '\0'; + XFILE *fp; + + if(!lp_we_are_a_wins_server()) + return; - DEBUGADD(3,("TTL = %s ", ts )); - } else - DEBUGADD(3,("TTL = PERMANENT ")); + /* we will do the writing in a child process to ensure that the parent + doesn't block while this is done */ + if (background) { + CatchChild(); + if (sys_fork()) { + return; + } + } - for (i = 0; i < namerec->data.num_ips; i++) - DEBUGADD(0,("%15s ", inet_ntoa(namerec->data.ip[i]) )); + slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST); + all_string_sub(fname,"//", "/", 0); + slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid()); - DEBUGADD(3,("0x%2x 0x%2x %15s\n", namerec->data.nb_flags, namerec->data.wins_flags, inet_ntoa(namerec->data.wins_ip))); + if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) + { + DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno))); + if (background) { + _exit(0); + } + return; + } - if( namerec->data.source == REGISTER_NAME ) { - - /* store the type in the key to make the name unique */ - slprintf(key, sizeof(key), "%s%s#%02x", ENTRY_PREFIX, namerec->name.name, namerec->name.name_type); - - len = tdb_pack(buf, sizeof(buf), "dddfddd", - (int)namerec->data.nb_flags, - (int)(namerec->data.id>>32), - (int)(namerec->data.id&0xffffffff), - inet_ntoa(namerec->data.wins_ip), - (int)namerec->data.death_time, - namerec->data.num_ips, - namerec->data.wins_flags); - - for (i = 0; i < namerec->data.num_ips; i++) - len += tdb_pack(buf+len, sizeof(buf)-len, "f", inet_ntoa(namerec->data.ip[i])); - - kbuf.dsize = strlen(key)+1; - kbuf.dptr = key; - dbuf.dsize = len; - dbuf.dptr = buf; - if (tdb_store(tdb, kbuf, dbuf, TDB_INSERT) != 0) return; + DEBUG(4,("wins_write_database: Dump of WINS name list.\n")); - num_record++; - } - } + x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0); + + for( namerec + = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist ); + namerec; + namerec = (struct name_record *)ubi_trNext( namerec ) ) + { + int i; + struct tm *tm; - /* store the number of records */ - tdb_store_int32(tdb, INFO_COUNT, num_record); + DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) )); - /* get and store the last used ID */ - get_global_id_and_update(&id, False); - tdb_store_int32(tdb, INFO_ID_HIGH, id>>32); - tdb_store_int32(tdb, INFO_ID_LOW, id&0xffffffff); + if( namerec->data.death_time != PERMANENT_TTL ) + { + char *ts, *nl; + + tm = LocalTime(&namerec->data.death_time); + ts = asctime(tm); + nl = strrchr( ts, '\n' ); + if( NULL != nl ) + *nl = '\0'; + DEBUGADD(4,("TTL = %s ", ts )); + } + else + DEBUGADD(4,("TTL = PERMANENT ")); - tdb_close(tdb); + for (i = 0; i < namerec->data.num_ips; i++) + DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) )); + DEBUGADD(4,("%2x\n", namerec->data.nb_flags )); - chmod(fnamenew,0644); - unlink(fname); - rename(fnamenew,fname); + if( namerec->data.source == REGISTER_NAME ) + { + x_fprintf(fp, "\"%s#%02x\" %d ", + namerec->name.name,namerec->name.name_type, /* Ignore scope. */ + (int)namerec->data.death_time); - if (background) - _exit(0); + for (i = 0; i < namerec->data.num_ips; i++) + x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) ); + x_fprintf( fp, "%2xR\n", namerec->data.nb_flags ); + } + } + + x_fclose(fp); + chmod(fnamenew,0644); + unlink(fname); + rename(fnamenew,fname); + if (background) { + _exit(0); + } } /**************************************************************************** diff --git a/source3/nmbd/nmbd_workgroupdb.c b/source3/nmbd/nmbd_workgroupdb.c index b8ea60dec0..2357fd637b 100644 --- a/source3/nmbd/nmbd_workgroupdb.c +++ b/source3/nmbd/nmbd_workgroupdb.c @@ -57,7 +57,7 @@ static struct work_record *create_workgroup(const char *name, int ttl) } memset((char *)work, '\0', sizeof(*work)); - StrnCpy(work->work_group,name,sizeof(work->work_group)-1); + fstrcpy(work->work_group,name); work->serverlist = NULL; work->RunningElection = False; |