diff -ur ../samba-2.2.9-orig/source/include/proto.h ./source/include/proto.h --- ../samba-2.2.9-orig/source/include/proto.h Sat May 8 05:07:16 2004 +++ ./source/include/proto.h Wed Jul 21 12:44:14 2004 @@ -21,6 +21,8 @@ BOOL allow_access(char *deny_list,char *allow_list, char *cname,char *caddr); +BOOL wrkgroup_access(char *deny_list,char *allow_list, + const char *cname); BOOL check_access(int sock, char *allow_list, char *deny_list); /* The following definitions come from lib/bitmap.c */ Only in ./source/include: proto.h.orig diff -ur ../samba-2.2.9-orig/source/lib/access.c ./source/lib/access.c --- ../samba-2.2.9-orig/source/lib/access.c Sat May 8 05:07:12 2004 +++ ./source/lib/access.c Wed Jul 21 12:44:14 2004 @@ -124,9 +124,17 @@ return (False); } +/* + * simple_match - match word against token, + * this stupid function is written by glebius@cell.sick.ru + */ +static int simple_match(char *tok,const char *item) +{ + return (strcmp(tok, item) == 0) ? (True) : (False); +} /* client_match - match host name and address against token */ -static int client_match(char *tok,char *item) +static int client_match(char *tok,const char *item) { char **client = (char **)item; int match; @@ -155,7 +163,7 @@ /* list_match - match an item against a list of tokens with exceptions */ /* (All modifications are marked with the initials "jkf") */ -static int list_match(char *list,char *item, int (*match_fn)(char *, char *)) +static int list_match(char *list,const char *item, int (*match_fn)(char *, const char *)) { char *tok; char *listcopy; /* jkf */ @@ -249,6 +257,41 @@ return (False); return (True); +} + +/* + * Check if workgroup name is allowed. + * Written by glebius@cell.sick.ru, using previos function allow_access. + */ +BOOL wrkgroup_access(char *deny_list,char *allow_list, const char *cname) +{ + /* if there is no deny list and no allow list then allow access */ + if ((!deny_list || *deny_list == 0) && + (!allow_list || *allow_list == 0)) { + return(True); + } + + /* if there is an allow list but no deny list then allow only hosts + in the allow list */ + if (!deny_list || *deny_list == 0) + return(list_match(allow_list,cname,simple_match)); + + /* if there is a deny list but no allow list then allow + all hosts not on the deny list */ + if (!allow_list || *allow_list == 0) + return(!list_match(deny_list,cname,simple_match)); + + /* if there are both type of list then allow all hosts on the + allow list */ + if (list_match(allow_list,cname,simple_match)) + return (True); + + /* if there are both type of list and it's not on the allow then + allow it if its not on the deny */ + if (list_match(deny_list,cname,simple_match)) + return (False); + + return (True); } /* return true if the char* contains ip addrs only. Used to avoid Only in ./source/lib: access.c.orig diff -ur ../samba-2.2.9-orig/source/lib/util.c ./source/lib/util.c --- ../samba-2.2.9-orig/source/lib/util.c Sat May 8 05:07:11 2004 +++ ./source/lib/util.c Wed Jul 21 12:44:14 2004 @@ -85,6 +85,7 @@ pstring global_myname = ""; fstring global_myworkgroup = ""; char **my_netbios_names; +char **my_workgroups; /**************************************************************************** @@ -1362,6 +1363,23 @@ ret=True; } DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret)); + return(ret); +} + +/******************************************************************* +is the workgroup specified one of mine +returns true is it is equal, false otherwise +********************************************************************/ +BOOL is_mygroup(char *s) +{ + int n; + BOOL ret = False; + + for (n=0; my_workgroups[n]; n++) { + if (strequal(my_workgroups[n], s)) + ret=True; + } + DEBUG(8, ("is_mygroup(\"%s\") returns %d\n", s, ret)); return(ret); } Only in ./source/lib: util.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd.c ./source/nmbd/nmbd.c --- ../samba-2.2.9-orig/source/nmbd/nmbd.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd.c Wed Jul 21 12:44:14 2004 @@ -37,6 +37,7 @@ extern pstring global_myname; extern fstring global_myworkgroup; extern char **my_netbios_names; +extern char **my_workgroups; extern BOOL global_in_nmbd; @@ -634,6 +635,60 @@ for( n=0; my_netbios_names[n]; n++ ) DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) ); + /* Now initialize workgroup names. Ensure that the first entry + is equal to global_myworkgroup. + */ + + ptr = lp_workgroups(); + /* Work out the max number of netbios aliases that we have */ + for( namecount=0; next_token(&ptr,nbname,NULL, sizeof(nbname)); namecount++ ) + ; + if ( *global_myname ) + namecount++; + + /* Allocate space for the workgroup names */ + my_workgroups = (char **)malloc( sizeof(char *) * (namecount+1) ); + if( NULL == my_workgroups ) + { + DEBUG( 0, ( "init_structs: malloc fail.\n" ) ); + return( False ); + } + + /* Use the global_myworkgroup string first */ + namecount=0; + if ( *global_myworkgroup ) + my_workgroups[namecount++] = global_myworkgroup; + + ptr = lp_workgroups(); + while ( next_token( &ptr, nbname, NULL, sizeof(nbname) ) ) + { + strupper( nbname ); + /* Look for duplicates */ + nodup=1; + for( n=0; nwork_group )); Only in ./source/nmbd: nmbd_become_lmb.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd_browsesync.c ./source/nmbd/nmbd_browsesync.c --- ../samba-2.2.9-orig/source/nmbd/nmbd_browsesync.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd_browsesync.c Wed Jul 21 12:44:14 2004 @@ -26,7 +26,7 @@ #include "smb.h" extern pstring global_myname; -extern fstring global_myworkgroup; +extern char **my_workgroups; /* This is our local master browser list database. */ extern ubi_dlList lmb_browserlist[]; @@ -477,7 +477,7 @@ /* * Add it - with an hour in the cache. */ - if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60))) + if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60, from_ip))) return; /* remember who the master is */ @@ -606,38 +606,41 @@ static time_t lastrun = 0; struct work_record *work; struct nmb_name nmbname; + int n; /* Only do this if we are using a WINS server. */ if(we_are_a_wins_client() == False) return; - /* Check to see if we are a domain master browser on the unicast subnet. */ - if((work = find_workgroup_on_subnet( unicast_subnet, global_myworkgroup)) == NULL) - { - if( DEBUGLVL( 0 ) ) + /* Check to see if we are a domain master browser on the unicast subnet. */ + for( n=0; my_workgroups[n]; n++ ) { + if((work = find_workgroup_on_subnet( unicast_subnet, my_workgroups[n])) == NULL) { - dbgtext( "collect_all_workgroup_names_from_wins_server:\n" ); - dbgtext( "Cannot find my workgroup %s ", global_myworkgroup ); - dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name ); + if( DEBUGLVL( 0 ) ) + { + dbgtext( "collect_all_workgroup_names_from_wins_server:\n" ); + dbgtext( "Cannot find workgroup %s ", my_workgroups[n] ); + dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name ); + } + return; } - return; - } - - if(!AM_DOMAIN_MASTER_BROWSER(work)) - return; - - if ((lastrun != 0) && (t < lastrun + (15 * 60))) - return; - - lastrun = t; - - make_nmb_name(&nmbname,"*",0x1b); - - /* First, query for the *<1b> name from the WINS server. */ - query_name(unicast_subnet, nmbname.name, nmbname.name_type, - find_all_domain_master_names_query_success, - find_all_domain_master_names_query_fail, - NULL); + + if(!AM_DOMAIN_MASTER_BROWSER(work)) + return; + + if ((lastrun != 0) && (t < lastrun + (15 * 60))) + return; + + lastrun = t; + + make_nmb_name(&nmbname,"*",0x1b); + + /* First, query for the *<1b> name from the WINS server. */ + query_name(unicast_subnet, nmbname.name, nmbname.name_type, + find_all_domain_master_names_query_success, + find_all_domain_master_names_query_fail, + NULL); + } /* for each workgroup */ } @@ -654,6 +657,7 @@ static time_t lastrun = 0; struct work_record *work; int count=0; + int n; /* Only do this if we are using a WINS server. */ if(we_are_a_wins_client() == False) @@ -661,25 +665,25 @@ /* Check to see if we are a domain master browser on the unicast subnet. */ - work = find_workgroup_on_subnet(unicast_subnet, global_myworkgroup); - if (!work) return; + for( n=0; my_workgroups[n]; n++ ) { + work = find_workgroup_on_subnet(unicast_subnet, my_workgroups[n]); + if (!work) return; - if (!AM_DOMAIN_MASTER_BROWSER(work)) + if (!AM_DOMAIN_MASTER_BROWSER(work)) return; - if ((lastrun != 0) && (t < lastrun + (5 * 60))) + if ((lastrun != 0) && (t < lastrun + (5 * 60))) return; - - /* count how many syncs we might need to do */ - for (work=unicast_subnet->workgrouplist; work; work = work->next) { - if (strcmp(global_myworkgroup, work->work_group)) { + /* count how many syncs we might need to do */ + for (work=unicast_subnet->workgrouplist; work; work = work->next) { + if (strcmp(my_workgroups[n], work->work_group)) { count++; } - } + } - /* sync with a probability of 1/count */ - for (work=unicast_subnet->workgrouplist; work; work = work->next) { - if (strcmp(global_myworkgroup, work->work_group)) { + /* sync with a probability of 1/count */ + for (work=unicast_subnet->workgrouplist; work; work = work->next) { + if (strcmp(my_workgroups[n], work->work_group)) { if (((unsigned)sys_random()) % count != 0) continue; lastrun = t; @@ -693,12 +697,13 @@ } DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n", - work->dmb_name.name, - inet_ntoa(work->dmb_addr))); + work->dmb_name.name, + inet_ntoa(work->dmb_addr))); sync_browse_lists(work, work->dmb_name.name, work->dmb_name.name_type, work->dmb_addr, False, False); } - } -} + } + } +} Only in ./source/nmbd: nmbd_browsesync.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd_elections.c ./source/nmbd/nmbd_elections.c --- ../samba-2.2.9-orig/source/nmbd/nmbd_elections.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd_elections.c Wed Jul 21 12:44:14 2004 @@ -25,7 +25,7 @@ #include "includes.h" extern pstring global_myname; -extern fstring global_myworkgroup; +extern char **my_workgroups; /* Election parameters. */ extern time_t StartupTime; @@ -85,6 +85,7 @@ { char *workgroup_name = question_name->name; struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name); + int n; if(work == NULL) { @@ -93,29 +94,32 @@ return; } - if (strequal(work->work_group, global_myworkgroup)) - { + for( n=0; my_workgroups[n]; n++ ) { + if (strequal(work->work_group, my_workgroups[n])) + { - if (lp_local_master()) - { - /* We have discovered that there is no local master - browser, and we are configured to initiate - an election that we will participate in. - */ - DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n", - work->work_group, subrec->subnet_name )); + if (lp_local_master()) + { + /* We have discovered that there is no local master + browser, and we are configured to initiate + an election that we will participate in. + */ + DEBUG(2,("check_for_master_browser_fail: Forcing election on workgroup %s subnet %s\n", + work->work_group, subrec->subnet_name )); + + /* Setting this means we will participate when the + election is run in run_elections(). */ + work->needelection = True; + } + else + { + /* We need to force an election, because we are configured + not to become the local master, but we still need one, + having detected that one doesn't exist. + */ + send_election_dgram(subrec, work->work_group, 0, 0, ""); + } - /* Setting this means we will participate when the - election is run in run_elections(). */ - work->needelection = True; - } - else - { - /* We need to force an election, because we are configured - not to become the local master, but we still need one, - having detected that one doesn't exist. - */ - send_election_dgram(subrec, work->work_group, 0, 0, ""); } } } @@ -129,7 +133,7 @@ { static time_t lastrun=0; struct subnet_record *subrec; - char *workgroup_name = global_myworkgroup; + int n; if (!lastrun) lastrun = t; @@ -147,13 +151,15 @@ for (work = subrec->workgrouplist; work; work = work->next) { - if (strequal(work->work_group, workgroup_name) && !AM_LOCAL_MASTER_BROWSER(work)) - { - /* Do a name query for the local master browser on this net. */ - query_name( subrec, work->work_group, 0x1d, - check_for_master_browser_success, - check_for_master_browser_fail, - NULL); + for( n=0; my_workgroups[n]; n++ ) { + if (strequal(work->work_group, my_workgroups[n]) && !AM_LOCAL_MASTER_BROWSER(work)) + { + /* Do a name query for the local master browser on this net. */ + query_name( subrec, work->work_group, 0x1d, + check_for_master_browser_success, + check_for_master_browser_fail, + NULL); + } } } } @@ -275,6 +281,7 @@ char *server_name = buf+13; struct work_record *work; char *workgroup_name = dgram->dest_name.name; + int n; START_PROFILE(election); server_name[15] = 0; @@ -291,41 +298,44 @@ goto done; } - if (!strequal(work->work_group, global_myworkgroup)) - { - DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \ + for( n=0; my_workgroups[n]; n++ ) { + if (!strequal(work->work_group, my_workgroups[n])) + { + DEBUG(3,("process_election: ignoring election request for workgroup %s on subnet %s as this \ is not my workgroup.\n", work->work_group, subrec->subnet_name )); - goto done; - } + continue; + } - if (win_election(work, version,criterion,timeup,server_name)) - { - /* We take precedence over the requesting server. */ - if (!work->RunningElection) + if (win_election(work, version,criterion,timeup,server_name)) { - /* We weren't running an election - start running one. */ - - work->needelection = True; - work->ElectionCount=0; - } + /* We take precedence over the requesting server. */ + if (!work->RunningElection) + { + /* We weren't running an election - start running one. */ - /* Note that if we were running an election for this workgroup on this - subnet already, we just ignore the server we take precedence over. */ - } - else - { - /* We lost. Stop participating. */ - work->needelection = False; + work->needelection = True; + work->ElectionCount=0; + } - if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work)) + /* Note that if we were running an election for this workgroup on this + subnet already, we just ignore the server we take precedence over. */ + } + else { - work->RunningElection = False; - DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n", + /* We lost. Stop participating. */ + work->needelection = False; + + if (work->RunningElection || AM_LOCAL_MASTER_BROWSER(work)) + { + work->RunningElection = False; + DEBUG(3,("process_election: >>> Lost election for workgroup %s on subnet %s <<<\n", work->work_group, subrec->subnet_name )); - if (AM_LOCAL_MASTER_BROWSER(work)) - unbecome_local_master_browser(subrec, work, False); + if (AM_LOCAL_MASTER_BROWSER(work)) + unbecome_local_master_browser(subrec, work, False); + } } } + done: END_PROFILE(election); } @@ -393,14 +403,17 @@ void nmbd_message_election(int msg_type, pid_t src, void *buf, size_t len) { struct subnet_record *subrec; + int n; for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { struct work_record *work; for (work = subrec->workgrouplist; work; work = work->next) { - if (strequal(work->work_group, global_myworkgroup)) { + for( n=0; my_workgroups[n]; n++ ) { + if (strequal(work->work_group, my_workgroups[n])) { work->needelection = True; work->ElectionCount=0; work->mst_state = lp_local_master() ? MST_POTENTIAL : MST_NONE; + } } } } Only in ./source/nmbd: nmbd_elections.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd_incomingdgrams.c ./source/nmbd/nmbd_incomingdgrams.c --- ../samba-2.2.9-orig/source/nmbd/nmbd_incomingdgrams.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd_incomingdgrams.c Wed Jul 21 12:44:14 2004 @@ -25,7 +25,7 @@ #include "includes.h" extern pstring global_myname; -extern fstring global_myworkgroup; +extern char **my_workgroups; extern BOOL found_lm_clients; #if 0 @@ -143,7 +143,7 @@ */ if(strequal(work_name, global_myname)) - work_name = global_myworkgroup; + work_name = my_workgroups[0]; /* * We are being very agressive here in adding a workgroup @@ -159,7 +159,7 @@ if (work ==NULL ) { /* We have no record of this workgroup. Add it. */ - if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL) + if((work = create_workgroup_on_subnet(subrec, work_name, ttl, p->ip))==NULL) goto done; } @@ -220,6 +220,13 @@ DEBUG(5,("process_workgroup_announce: ttl=%d server type=%08x master browser=%s\n", ttl, servertype, master_name)); + if (allow_access((char *)lp_denymasters(),(char *)lp_allowmasters(),"", inet_ntoa(p->ip)) == (False)) + { + DEBUG(0,("process_workgroup_announce: ignoring announce for %s from %s\n", + master_name, inet_ntoa(p->ip))); + goto done; + } + /* Workgroup announcements must only go to the MSBROWSE name. */ if (!strequal(dgram->dest_name.name, MSBROWSE) || (dgram->dest_name.name_type != 0x1)) { @@ -231,7 +238,7 @@ if ((work = find_workgroup_on_subnet(subrec, workgroup_announce_name))==NULL) { /* We have no record of this workgroup. Add it. */ - if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl))==NULL) + if((work = create_workgroup_on_subnet(subrec, workgroup_announce_name, ttl, p->ip))==NULL) goto done; } else @@ -277,6 +284,13 @@ DEBUG(5,("process_local_master_announce: ttl=%d server type=%08x comment=%s\n", ttl, servertype, comment)); + if (allow_access((char *)lp_denymasters(),(char *)lp_allowmasters(),"", inet_ntoa(p->ip)) == (False)) + { + DEBUG(0,("process_local_master_announce: ignoring announce for %s from %s\n", + dgram->dest_name.name, inet_ntoa(p->ip))); + goto done; + } + /* A local master announcement must be sent to the name WORKGROUP<1e>. */ if(dgram->dest_name.name_type != 0x1e) { @@ -299,7 +313,7 @@ goto done; /* We have no record of this workgroup. Add it. */ - if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL) + if((work = create_workgroup_on_subnet(subrec, work_name, ttl, p->ip))==NULL) goto done; } @@ -309,6 +323,12 @@ */ if(AM_LOCAL_MASTER_BROWSER(work)) { + if (lp_force_local_master()) { + DEBUG(0,("process_local_master_announce: Server %s at IP %s is announcing itsel f as a local master browser for workgroup %s and we think we are master. But we are ignoring it, due to force local master option.\n", + server_name, inet_ntoa(p->ip), work_name)); + goto done; + }; + DEBUG(0,("process_local_master_announce: Server %s at IP %s is announcing itself as \ a local master browser for workgroup %s and we think we are master. Forcing election.\n", server_name, inet_ntoa(p->ip), work_name)); @@ -383,12 +403,20 @@ char *local_master_name = buf; struct work_record *work; struct browse_cache_record *browrec; + int n; START_PROFILE(master_browser_announce); local_master_name[15] = 0; DEBUG(3,("process_master_browser_announce: Local master announce from %s IP %s.\n", local_master_name, inet_ntoa(p->ip))); + + if (allow_access((char *)lp_denymasters(),(char *)lp_allowmasters(),"", inet_ntoa(p->ip)) == (False)) + { + DEBUG(0,("process_master_browser_announce: ignoring announce from %s\n", + inet_ntoa(p->ip))); + goto done; + } if (!lp_domain_master()) { @@ -396,32 +424,33 @@ master - ignoring master announce.\n")); goto done; } + + for( n=0; my_workgroups[n]; n++ ) { + if((work = find_workgroup_on_subnet(subrec, my_workgroups[n])) == NULL) + { + DEBUG(0,("process_master_browser_announce: Cannot find workgroup %s on subnet %s\n", + my_workgroups[n], subrec->subnet_name)); + continue; + } + if(!AM_DOMAIN_MASTER_BROWSER(work)) + { + DEBUG(0,("process_master_browser_announce: Local master announce made to us from \ + %s IP %s and we are not a domain master browser.\n", local_master_name, inet_ntoa(p->ip))); + continue; + } - if((work = find_workgroup_on_subnet(subrec, global_myworkgroup)) == NULL) - { - DEBUG(0,("process_master_browser_announce: Cannot find workgroup %s on subnet %s\n", - global_myworkgroup, subrec->subnet_name)); - goto done; - } - - if(!AM_DOMAIN_MASTER_BROWSER(work)) - { - DEBUG(0,("process_master_browser_announce: Local master announce made to us from \ -%s IP %s and we are not a domain master browser.\n", local_master_name, inet_ntoa(p->ip))); - goto done; - } - - /* Add this host as a local master browser entry on the browse lists. - This causes a sync request to be made to it at a later date. - */ - - if((browrec = find_browser_in_lmb_cache( local_master_name )) == NULL) - { - /* Add it. */ - create_browser_in_lmb_cache( work->work_group, local_master_name, p->ip); - } - else - update_browser_death_time(browrec); + /* Add this host as a local master browser entry on the browse lists. + This causes a sync request to be made to it at a later date. + */ + + if((browrec = find_browser_in_lmb_cache( local_master_name )) == NULL) + { + /* Add it. */ + create_browser_in_lmb_cache( work->work_group, local_master_name, p->ip); + } + else + update_browser_death_time(browrec); + } done: END_PROFILE(master_browser_announce); } @@ -491,7 +520,7 @@ */ if(strequal(work_name, global_myname)) - work_name = global_myworkgroup; + work_name = my_workgroups[0]; /* * We are being very agressive here in adding a workgroup @@ -507,7 +536,7 @@ if (work == NULL) { /* We have no record of this workgroup. Add it. */ - if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL) + if((work = create_workgroup_on_subnet(subrec, work_name, ttl, p->ip))==NULL) goto done; } @@ -655,6 +684,7 @@ int name_type = dgram->dest_name.name_type; char *workgroup_name = dgram->dest_name.name; struct subnet_record *search_subrec = subrec; + int n; START_PROFILE(get_backup_list); DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n", @@ -664,62 +694,64 @@ /* We have to be a master browser, or a domain master browser for the requested workgroup. That means it must be our workgroup. */ - - if(strequal(workgroup_name, global_myworkgroup) == False) - { - DEBUG(7,("process_get_backup_list_request: Ignoring announce request for workgroup %s.\n", - workgroup_name)); - goto done; - } - - if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL) - { - DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \ -subnet %s.\n", workgroup_name, search_subrec->subnet_name)); - goto done; - } - - /* - * If the packet was sent to WORKGROUP<1b> instead - * of WORKGROUP<1d> then it was unicast to us a domain master - * browser. Change search subrec to unicast. - */ - - if(name_type == 0x1b) - { - /* We must be a domain master browser in order to - process this packet. */ - - if(!AM_DOMAIN_MASTER_BROWSER(work)) - { - DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \ -and I am not a domain master browser.\n", workgroup_name)); - goto done; - } - - search_subrec = unicast_subnet; - } - else if (name_type == 0x1d) - { - /* We must be a local master browser in order to - process this packet. */ - - if(!AM_LOCAL_MASTER_BROWSER(work)) - { - DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \ -and I am not a local master browser.\n", workgroup_name)); - goto done; - } - } - else - { - DEBUG(0,("process_get_backup_list_request: Invalid name type %x - should be 0x1b or 0x1d.\n", - name_type)); - goto done; + for( n=0; my_workgroups[n]; n++ ) { + if(strequal(workgroup_name, my_workgroups[n]) == False) + { + DEBUG(7,("process_get_backup_list_request: Ignoring announce request for workgroup %s.\n", + workgroup_name)); + continue; + } + + if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL) + { + DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \ + subnet %s.\n", workgroup_name, search_subrec->subnet_name)); + continue; + } + + /* + * If the packet was sent to WORKGROUP<1b> instead + * of WORKGROUP<1d> then it was unicast to us a domain master + * browser. Change search subrec to unicast. + */ + + if(name_type == 0x1b) + { + /* We must be a domain master browser in order to + process this packet. */ + + if(!AM_DOMAIN_MASTER_BROWSER(work)) + { + DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \ + and I am not a domain master browser.\n", workgroup_name)); + continue; + } + + search_subrec = unicast_subnet; + } + else if (name_type == 0x1d) + { + /* We must be a local master browser in order to + process this packet. */ + + if(!AM_LOCAL_MASTER_BROWSER(work)) + { + DEBUG(0,("process_get_backup_list_request: domain list requested for workgroup %s \ + and I am not a local master browser.\n", workgroup_name)); + continue; + } + } + else + { + DEBUG(0,("process_get_backup_list_request: Invalid name type %x - should be 0x1b or 0x1d.\n", + name_type)); + continue; + } + + send_backup_list_response(subrec, work, &dgram->source_name, + max_number_requested, token, p->ip, p->port); } - send_backup_list_response(subrec, work, &dgram->source_name, - max_number_requested, token, p->ip, p->port); done: END_PROFILE(get_backup_list); } @@ -794,6 +826,7 @@ struct dgram_packet *dgram = &p->packet.dgram; struct work_record *work; char *workgroup_name = dgram->dest_name.name; + int n; START_PROFILE(announce_request); DEBUG(3,("process_announce_request: Announce request from %s IP %s to %s.\n", @@ -801,21 +834,23 @@ nmb_namestr(&dgram->dest_name))); /* We only send announcement requests on our workgroup. */ - if(strequal(workgroup_name, global_myworkgroup) == False) - { - DEBUG(7,("process_announce_request: Ignoring announce request for workgroup %s.\n", - workgroup_name)); - goto done; - } - - if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL) - { - DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n", - workgroup_name)); - goto done; + for ( n = 0; my_workgroups[n]; n++ ) { + if(strequal(workgroup_name, my_workgroups[n]) == False) + { + DEBUG(7,("process_announce_request: Ignoring announce request for workgroup %s. \n", + workgroup_name)); + continue; + } + + if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL) + { + DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n", + workgroup_name)); + continue; + } + + work->needannounce = True; } - - work->needannounce = True; done: END_PROFILE(lm_host_announce); } @@ -833,6 +868,7 @@ { struct dgram_packet *dgram = &p->packet.dgram; char *workgroup_name = dgram->dest_name.name; + int n; START_PROFILE(lm_announce_request); DEBUG(3,("process_lm_announce_request: Announce request from %s IP %s to %s.\n", @@ -840,21 +876,23 @@ nmb_namestr(&dgram->dest_name))); /* We only send announcement requests on our workgroup. */ - if(strequal(workgroup_name, global_myworkgroup) == False) - { - DEBUG(7,("process_lm_announce_request: Ignoring announce request for workgroup %s.\n", - workgroup_name)); - goto done; - } - - if(find_workgroup_on_subnet(subrec, workgroup_name) == NULL) - { - DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n", - workgroup_name)); - goto done; + for (n=0; my_workgroups[n]; n++) { + if(strequal(workgroup_name, my_workgroups[n]) == False) + { + DEBUG(7,("process_lm_announce_request: Ignoring announce request for workgroup %s.\n", + workgroup_name)); + continue; + } + + if(find_workgroup_on_subnet(subrec, workgroup_name) == NULL) + { + DEBUG(0,("process_announce_request: Unable to find workgroup %s on subnet !\n", + workgroup_name)); + continue; + } + + found_lm_clients = True; } - - found_lm_clients = True; done: END_PROFILE(lm_host_announce); } Only in ./source/nmbd: nmbd_incomingdgrams.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd_mynames.c ./source/nmbd/nmbd_mynames.c --- ../samba-2.2.9-orig/source/nmbd/nmbd_mynames.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd_mynames.c Wed Jul 21 12:44:14 2004 @@ -25,7 +25,7 @@ #include "includes.h" extern char **my_netbios_names; -extern fstring global_myworkgroup; +extern char **my_workgroups; extern uint16 samba_nb_type; /* Samba's NetBIOS type. */ @@ -47,24 +47,27 @@ **************************************************************************/ void register_my_workgroup_one_subnet(struct subnet_record *subrec) { - int i; + int i, n; + struct in_addr myip; struct work_record *work; - /* Create the workgroup on the subnet. */ - if((work = create_workgroup_on_subnet(subrec, global_myworkgroup, - PERMANENT_TTL)) == NULL) { - DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \ -Exiting.\n", global_myworkgroup, subrec->subnet_name)); - return; - } - - /* Each subnet entry, except for the wins_server_subnet has - the magic Samba names. */ - add_samba_names_to_subnet(subrec); + inet_aton("127.0.0.1", &myip); + /* Create workgroups on the subnet. */ + for (n=0; my_workgroups[n]; n++ ) { + if((work = create_workgroup_on_subnet(subrec, my_workgroups[n], + PERMANENT_TTL, myip)) == NULL) { + DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \ +Exiting.\n", my_workgroups[n], subrec->subnet_name)); + return; + } + + /* Each subnet entry, except for the wins_server_subnet has + the magic Samba names. */ + add_samba_names_to_subnet(subrec); - /* Register all our names including aliases. */ - for (i=0; my_netbios_names[i]; i++) { + /* Register all our names including aliases. */ + for (i=0; my_netbios_names[i]; i++) { register_name(subrec, my_netbios_names[i],0x20,samba_nb_type, NULL, my_name_register_failed, NULL); @@ -74,10 +77,11 @@ register_name(subrec, my_netbios_names[i],0x00,samba_nb_type, NULL, my_name_register_failed, NULL); - } + } - /* Initiate election processing, register the workgroup names etc. */ - initiate_myworkgroup_startup(subrec, work); + /* Initiate election processing, register the workgroup names etc. */ + initiate_myworkgroup_startup(subrec, work); + } } /******************************************************************* @@ -118,7 +122,7 @@ BOOL register_my_workgroup_and_names(void) { struct subnet_record *subrec; - int i; + int i, n; for(subrec = FIRST_SUBNET; subrec; @@ -166,10 +170,12 @@ */ struct nmb_name nmbname; - make_nmb_name(&nmbname, global_myworkgroup, 0x0); + for (n=0; my_workgroups[n]; n++) + make_nmb_name(&nmbname, my_workgroups[n], 0x0); insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP); - make_nmb_name(&nmbname, global_myworkgroup, 0x1e); + for (n=0; my_workgroups[n]; n++) + make_nmb_name(&nmbname, my_workgroups[n], 0x1e); insert_refresh_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP); } Only in ./source/nmbd: nmbd_mynames.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd_sendannounce.c ./source/nmbd/nmbd_sendannounce.c --- ../samba-2.2.9-orig/source/nmbd/nmbd_sendannounce.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd_sendannounce.c Wed Jul 21 12:44:14 2004 @@ -28,8 +28,8 @@ #include "includes.h" extern pstring global_myname; -extern fstring global_myworkgroup; extern char **my_netbios_names; +extern char **my_workgroups; extern int updatecount; extern BOOL found_lm_clients; @@ -278,10 +278,12 @@ void announce_my_server_names(time_t t) { struct subnet_record *subrec; + int n; for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) + for (n=0; my_workgroups[n]; n++) { - struct work_record *work = find_workgroup_on_subnet(subrec, global_myworkgroup); + struct work_record *work = find_workgroup_on_subnet(subrec, my_workgroups[n]); if(work) { @@ -327,6 +329,7 @@ static time_t last_lm_announce_time=0; int announce_interval = lp_lm_interval(); int lm_announce = lp_lm_announce(); + int n; if ((announce_interval <= 0) || (lm_announce <= 0)) { @@ -344,8 +347,9 @@ been detected. */ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) + for (n=0; my_workgroups[n]; n++) { - struct work_record *work = find_workgroup_on_subnet(subrec, global_myworkgroup); + struct work_record *work = find_workgroup_on_subnet(subrec, my_workgroups[n]); if(work) { @@ -483,6 +487,7 @@ Do all the "remote" announcements. These are used to put ourselves on a remote browse list. They are done blind, no checking is done to see if there is actually a local master browser at the other end. + We announce as a member of our primary workgroup. **************************************************************************/ void announce_remote(time_t t) @@ -517,7 +522,7 @@ if (wgroup) *wgroup++ = 0; if (!wgroup || !*wgroup) - wgroup = global_myworkgroup; + wgroup = my_workgroups[0]; addr = *interpret_addr2(s2); @@ -559,6 +564,7 @@ struct work_record *work; pstring outbuf; char *p; + int n; if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL))) return; @@ -574,38 +580,40 @@ * for our workgroup on the firsst subnet. */ - if((work = find_workgroup_on_subnet(FIRST_SUBNET, global_myworkgroup)) == NULL) - { - DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n", - global_myworkgroup, FIRST_SUBNET->subnet_name )); - return; - } - - if(!AM_LOCAL_MASTER_BROWSER(work)) - { - DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \ -for workgroup %s on subnet %s.\n", global_myworkgroup, FIRST_SUBNET->subnet_name )); - return; - } - - memset(outbuf,'\0',sizeof(outbuf)); - p = outbuf; - SCVAL(p,0,ANN_MasterAnnouncement); - p++; - - StrnCpy(p,global_myname,15); - strupper(p); - p = skip_string(p,1); - - for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) - { - /* The entries are of the form a.b.c.d */ - addr = *interpret_addr2(s2); - - DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n", - global_myname, inet_ntoa(addr) )); - - send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf), - global_myname, 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT); + for (n=0; my_workgroups[n]; n++) { + if((work = find_workgroup_on_subnet(FIRST_SUBNET, my_workgroups[n])) == NULL) + { + DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n", + my_workgroups[n], FIRST_SUBNET->subnet_name )); + continue; + } + + if(!AM_LOCAL_MASTER_BROWSER(work)) + { + DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \ + for workgroup %s on subnet %s.\n", my_workgroups[n], FIRST_SUBNET->subnet_name )); + continue; + } + + memset(outbuf,'\0',sizeof(outbuf)); + p = outbuf; + SCVAL(p,0,ANN_MasterAnnouncement); + p++; + + StrnCpy(p,global_myname,15); + strupper(p); + p = skip_string(p,1); + + for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) + { + /* The entries are of the form a.b.c.d */ + addr = *interpret_addr2(s2); + + DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n", + global_myname, inet_ntoa(addr) )); + + send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf), + global_myname, 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT); + } } } Only in ./source/nmbd: nmbd_sendannounce.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd_serverlistdb.c ./source/nmbd/nmbd_serverlistdb.c --- ../samba-2.2.9-orig/source/nmbd/nmbd_serverlistdb.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd_serverlistdb.c Wed Jul 21 12:44:14 2004 @@ -27,8 +27,8 @@ extern int ClientNMB; -extern fstring global_myworkgroup; extern char **my_netbios_names; +extern char **my_workgroups; int updatecount = 0; @@ -133,13 +133,21 @@ int ttl,char *comment) { struct server_record *servrec; - + int i; + if (name[0] == '*') { DEBUG(7,("create_server_on_workgroup: not adding name starting with '*' (%s)\n", name)); return (NULL); } + + for (i = 0; i < strlen(name); i++) + if (!isprint(name[i])) { + DEBUG(7,("create_server_on_workgroup: not adding name containing non-printable chars(%s)\n", + name)); + return (NULL); + } if((servrec = find_server_in_workgroup(work, name)) != NULL) { @@ -257,7 +265,7 @@ /******************************************************************* Decide if we should write out a workgroup record for this workgroup. - We return zero if we should not. Don't write out global_myworkgroup (we've + We return zero if we should not. Don't write out my_workgroups[n] (we've already done it) and also don't write out a second workgroup record on the unicast subnet that we've already written out on one of the broadcast subnets. @@ -267,9 +275,11 @@ struct work_record *work) { struct subnet_record *ssub; + int n; - if(strequal(global_myworkgroup, work->work_group)) - return 0; + for (n=0; my_workgroups[n]; n++) + if(strequal(my_workgroups[n], work->work_group)) + return 0; /* This is a workgroup we have seen on a broadcast subnet. All these have the same type. */ @@ -320,6 +330,7 @@ FILE *fp; BOOL list_changed = force_write; static time_t lasttime = 0; + int n; /* Always dump if we're being told to by a signal. */ if(force_write == False) @@ -369,79 +380,83 @@ * subnet. */ - if((work = find_workgroup_on_subnet(FIRST_SUBNET, global_myworkgroup)) == NULL) - { - DEBUG(0,("write_browse_list: Fatal error - cannot find my workgroup %s\n", - global_myworkgroup)); - fclose(fp); - return; - } - - write_browse_list_entry(fp, work->work_group, SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY, - work->local_master_browser_name, work->work_group); - - /* - * We need to do something special for our own names. - * This is due to the fact that we may be a local master browser on - * one of our broadcast subnets, and a domain master on the unicast - * subnet. We iterate over the subnets and only write out the name - * once. - */ - - for (i=0; my_netbios_names[i]; i++) + for (n=0; my_workgroups[n]; n++) { - stype = 0; - for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) - { - if((work = find_workgroup_on_subnet( subrec, global_myworkgroup )) == NULL) - continue; - if((servrec = find_server_in_workgroup( work, my_netbios_names[i])) == NULL) - continue; - - stype |= servrec->serv.type; - } - - /* Output server details, plus what workgroup they're in. */ - write_browse_list_entry(fp, my_netbios_names[i], stype, - string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), - global_myworkgroup); - + if((work = find_workgroup_on_subnet(FIRST_SUBNET, my_workgroups[n])) == NULL) + { + DEBUG(0,("write_browse_list: Fatal error - cannot find my workgroup %s\n", + my_workgroups[n])); + fclose(fp); + return; + } + + write_browse_list_entry(fp, work->work_group, SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT|SV_TYPE_LOCAL_LIST_ONLY, + work->local_master_browser_name, work->work_group); + + /* + * We need to do something special for our own names. + * This is due to the fact that we may be a local master browser on + * one of our broadcast subnets, and a domain master on the unicast + * subnet. We iterate over the subnets and only write out the name + * once. + */ + + for (i=0; my_netbios_names[i]; i++) + { + stype = 0; + for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) + { + if((work = find_workgroup_on_subnet( subrec, my_workgroups[n] )) == NULL) + continue; + if((servrec = find_server_in_workgroup( work, my_netbios_names[i])) == NULL) + continue; + + stype |= servrec->serv.type; + } + + /* Output server details, plus what workgroup they're in. */ + write_browse_list_entry(fp, my_netbios_names[i], stype, + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH), + my_workgroups[n]); + + } + + for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) + { + subrec->work_changed = False; + + for (work = subrec->workgrouplist; work ; work = work->next) + { + /* Write out a workgroup record for a workgroup. */ + uint32 wg_type = write_this_workgroup_name( subrec, work); + + if(wg_type) + write_browse_list_entry(fp, work->work_group, wg_type, + work->local_master_browser_name, + work->work_group); + + /* Now write out any server records a workgroup may have. */ + + for (servrec = work->serverlist; servrec ; servrec = servrec->next) + { + uint32 serv_type; + + /* We have already written our names here. */ + if(is_myname(servrec->serv.name)) + continue; + + serv_type = write_this_server_name(subrec, work, servrec); + + /* Output server details, plus what workgroup they're in. */ + if(serv_type) + write_browse_list_entry(fp, servrec->serv.name, serv_type, + servrec->serv.comment, work->work_group); + } + } + } } - - for (subrec = FIRST_SUBNET; subrec ; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) - { - subrec->work_changed = False; - - for (work = subrec->workgrouplist; work ; work = work->next) - { - /* Write out a workgroup record for a workgroup. */ - uint32 wg_type = write_this_workgroup_name( subrec, work); - - if(wg_type) - write_browse_list_entry(fp, work->work_group, wg_type, - work->local_master_browser_name, - work->work_group); - - /* Now write out any server records a workgroup may have. */ - for (servrec = work->serverlist; servrec ; servrec = servrec->next) - { - uint32 serv_type; - /* We have already written our names here. */ - if(is_myname(servrec->serv.name)) - continue; - - serv_type = write_this_server_name(subrec, work, servrec); - - /* Output server details, plus what workgroup they're in. */ - if(serv_type) - write_browse_list_entry(fp, servrec->serv.name, serv_type, - servrec->serv.comment, work->work_group); - } - } - } - fclose(fp); unlink(fname); chmod(fnamenew,0644); Only in ./source/nmbd: nmbd_serverlistdb.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd_synclists.c ./source/nmbd/nmbd_synclists.c --- ../samba-2.2.9-orig/source/nmbd/nmbd_synclists.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd_synclists.c Wed Jul 21 12:44:14 2004 @@ -205,7 +205,7 @@ } else { /* Create the workgroup on the subnet. */ work = create_workgroup_on_subnet(unicast_subnet, - sname, lp_max_ttl()); + sname, lp_max_ttl(), s->ip); if (work) { /* remember who the master is */ fstrcpy(work->local_master_browser_name, Only in ./source/nmbd: nmbd_synclists.c.orig diff -ur ../samba-2.2.9-orig/source/nmbd/nmbd_workgroupdb.c ./source/nmbd/nmbd_workgroupdb.c --- ../samba-2.2.9-orig/source/nmbd/nmbd_workgroupdb.c Sat May 8 05:07:15 2004 +++ ./source/nmbd/nmbd_workgroupdb.c Wed Jul 21 12:44:14 2004 @@ -28,8 +28,8 @@ extern int ClientNMB; extern pstring global_myname; -extern fstring global_myworkgroup; extern char **my_netbios_names; +extern char **my_workgroups; extern uint16 samba_nb_type; int workgroup_count = 0; /* unique index key: one for each workgroup */ @@ -177,22 +177,30 @@ **************************************************************************/ struct work_record *create_workgroup_on_subnet(struct subnet_record *subrec, - const char *name, int ttl) + const char *name, int ttl, struct in_addr ip) { struct work_record *work = NULL; - DEBUG(4,("create_workgroup_on_subnet: creating group %s on subnet %s\n", - name, subrec->subnet_name)); - - if ((work = create_workgroup(name, ttl))) - { - add_workgroup(subrec, work); + /* first check my own groups, then check allowed */ + if (wrkgroup_access(NULL, lp_workgroups(),name) || + wrkgroup_access(lp_denywrkgroups(),lp_allowwrkgroups(),name)) { - subrec->work_changed = True; + DEBUG(4,("create_workgroup_on_subnet: creating group %s on subnet %s\n", + name, subrec->subnet_name)); + + if ((work = create_workgroup(name, ttl))) + { + add_workgroup(subrec, work); - return(work); - } + subrec->work_changed = True; + return(work); + } + + } else { + DEBUG(0,("create_workgroup_on_subnet: denied registration of group %s from %s\n", + name, inet_ntoa(ip))); + } return NULL; } @@ -225,49 +233,49 @@ void initiate_myworkgroup_startup(struct subnet_record *subrec, struct work_record *work) { - int i; - - if(!strequal(global_myworkgroup, work->work_group)) - return; + int i, n; - /* If this is a broadcast subnet then start elections on it - if we are so configured. */ - - if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) && - (subrec != wins_server_subnet) && lp_preferred_master() && - lp_local_master()) - { - DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \ -workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name)); - work->needelection = True; - work->ElectionCriterion |= (1<<3); - } - - /* Register the WORKGROUP<0> and WORKGROUP<1e> names on the network. */ - - register_name(subrec,global_myworkgroup,0x0,samba_nb_type|NB_GROUP, - NULL, - fail_register,NULL); - - register_name(subrec,global_myworkgroup,0x1e,samba_nb_type|NB_GROUP, - NULL, - fail_register,NULL); - - for( i = 0; my_netbios_names[i]; i++) - { - char *name = my_netbios_names[i]; - int stype = lp_default_server_announce() | (lp_local_master() ? - SV_TYPE_POTENTIAL_BROWSER : 0 ); - - if(!strequal(global_myname, name)) - stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER| - SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER); - - create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY, - PERMANENT_TTL, - string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); - DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \ -on subnet %s\n", name, subrec->subnet_name)); + for (n=0; my_workgroups[n];n++) { + if(!strequal(my_workgroups[n], work->work_group)) + continue; + + /* If this is a broadcast subnet then start elections on it + if we are so configured. */ + + if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) && + (subrec != wins_server_subnet) && lp_preferred_master() && + lp_local_master()) + { + DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \ + workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name)); + work->needelection = True; + work->ElectionCriterion |= (1<<3); + } + + /* Register the WORKGROUP<0> and WORKGROUP<1e> names on the network. */ + + register_name(subrec,my_workgroups[n],0x0,samba_nb_type|NB_GROUP, + NULL, + fail_register,NULL); + + register_name(subrec,my_workgroups[n],0x1e,samba_nb_type|NB_GROUP, + NULL, + fail_register,NULL); + + for( i = 0; my_netbios_names[i]; i++) + { + char *name = my_netbios_names[i]; + int stype = lp_default_server_announce() | (lp_local_master() ? + SV_TYPE_POTENTIAL_BROWSER : 0 ); + if(!strequal(global_myname, name)) + stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER| + SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER); + create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY, + PERMANENT_TTL, + string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH)); + DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \ + on subnet %s\n", name, subrec->subnet_name)); + } } } Only in ./source/nmbd: nmbd_workgroupdb.c.orig diff -ur ../samba-2.2.9-orig/source/param/loadparm.c ./source/param/loadparm.c --- ../samba-2.2.9-orig/source/param/loadparm.c Sat May 8 05:07:10 2004 +++ ./source/param/loadparm.c Wed Jul 21 12:44:14 2004 @@ -108,6 +108,10 @@ char *szDeletePrinterCommand; char *szOs2DriverMap; char *szLockDir; + char *szAllowWrkGroups; + char *szDenyWrkGroups; + char *szAllowMasters; + char *szDenyMasters; char *szPidDir; char *szRootdir; char *szDefaultService; @@ -129,6 +133,7 @@ char *szSocketOptions; char *szValidChars; char *szWorkGroup; + char *szWorkGroups; char *szDomainAdminGroup; char *szDomainGuestGroup; char *szDomainHostsallow; @@ -246,6 +251,7 @@ BOOL bWINSsupport; BOOL bWINSproxy; BOOL bLocalMaster; + BOOL bForceLocalMaster; BOOL bPreferredMaster; BOOL bDomainMaster; BOOL bDomainLogons; @@ -723,6 +729,7 @@ {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_DOS_STRING}, {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_DOS_STRING}, {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC | FLAG_DOS_STRING | FLAG_WIZARD}, + {"workgroups", P_USTRING, P_GLOBAL, &Globals.szWorkGroups, NULL, NULL, FLAG_BASIC | FLAG_DOS_STRING | FLAG_WIZARD}, {"netbios name", P_UGSTRING, P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC | FLAG_DOS_STRING | FLAG_WIZARD}, {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_DOS_STRING}, {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, FLAG_DOS_STRING}, @@ -995,6 +1002,7 @@ {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC}, {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE}, {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC}, + {"force local master", P_BOOL, P_GLOBAL, &Globals.bForceLocalMaster, NULL, NULL, FLAG_BASIC}, {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC}, {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0}, {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT}, @@ -1048,6 +1056,14 @@ {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_DOS_STRING}, {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0}, + {"allow workgroups", P_STRING, P_GLOBAL, &Globals.szAllowWrkGroups, NULL, NULL, FLAG_DOS_STRING}, + {"workgroups allow", P_STRING, P_GLOBAL, &Globals.szAllowWrkGroups, NULL, NULL, FLAG_DOS_STRING}, + {"deny workgroups", P_STRING, P_GLOBAL, &Globals.szDenyWrkGroups, NULL, NULL, FLAG_DOS_STRING}, + {"workgroups deny", P_STRING, P_GLOBAL, &Globals.szDenyWrkGroups, NULL, NULL, FLAG_DOS_STRING}, + {"allow masters", P_STRING, P_GLOBAL, &Globals.szAllowMasters, NULL, NULL, 0}, + {"masters allow", P_STRING, P_GLOBAL, &Globals.szAllowMasters, NULL, NULL, 0}, + {"deny masters", P_STRING, P_GLOBAL, &Globals.szDenyMasters, NULL, NULL, 0}, + {"masters deny", P_STRING, P_GLOBAL, &Globals.szDenyMasters, NULL, NULL, 0}, {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, 0}, #ifdef WITH_UTMP {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0}, @@ -1438,6 +1454,7 @@ Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */ Globals.os_level = 20; Globals.bLocalMaster = True; + Globals.bForceLocalMaster = False; Globals.bDomainMaster = Auto; /* depending on bDomainLogons */ Globals.bDomainLogons = False; Globals.bBrowseList = True; @@ -1555,6 +1572,10 @@ FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand) FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap) FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir) +FN_GLOBAL_STRING(lp_allowwrkgroups, &Globals.szAllowWrkGroups) +FN_GLOBAL_STRING(lp_denywrkgroups, &Globals.szDenyWrkGroups) +FN_GLOBAL_STRING(lp_allowmasters, &Globals.szAllowMasters) +FN_GLOBAL_STRING(lp_denymasters, &Globals.szDenyMasters) FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir) #ifdef WITH_UTMP FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir) @@ -1573,6 +1594,7 @@ FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer) FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder) FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkGroup) +FN_GLOBAL_STRING(lp_workgroups, &Globals.szWorkGroups) FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap) #ifdef USING_GROUPNAME_MAP FN_GLOBAL_STRING(lp_groupname_map, &Globals.szGroupnameMap) @@ -1642,6 +1664,7 @@ FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport) FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy) FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster) +FN_GLOBAL_BOOL(lp_force_local_master, &Globals.bForceLocalMaster) FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons) FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters) FN_GLOBAL_BOOL(lp_use_rhosts, &Globals.bUseRhosts) Only in ./source/param: loadparm.c.orig