static void complete_one(struct sync_record *s, char *sname, uint32 stype, char *comment) { struct work_record *work; struct server_record *servrec; stype &= ~SV_TYPE_LOCAL_LIST_ONLY; if (stype & SV_TYPE_DOMAIN_ENUM) { /* See if we can find the workgroup on this subnet. */ if((work=find_workgroup_on_subnet(unicast_subnet, sname))) { /* We already know about this workgroup - update the ttl. */ update_workgroup_ttl(work,lp_max_ttl()); } else { /* Create the workgroup on the subnet. */ work = create_workgroup_on_subnet(unicast_subnet, sname, lp_max_ttl()); if (work) { /* remember who the master is */ unstrcpy(work->local_master_browser_name, comment); } } return; } work = find_workgroup_on_subnet(unicast_subnet, s->workgroup); if (!work) { DEBUG(3,("workgroup %s doesn't exist on unicast subnet?\n", s->workgroup)); return; } if ((servrec = find_server_in_workgroup( work, sname))) { /* Check that this is not a locally known server - if so ignore the entry. */ if(!(servrec->serv.type & SV_TYPE_LOCAL_LIST_ONLY)) { /* We already know about this server - update the ttl. */ update_server_ttl(servrec, lp_max_ttl()); /* Update the type. */ servrec->serv.type = stype; } return; } /* Create the server in the workgroup. */ create_server_on_workgroup(work, sname,stype, lp_max_ttl(), comment); }
void collect_all_workgroup_names_from_wins_server(time_t t) { static time_t lastrun = 0; struct work_record *work; /* 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, lp_workgroup())) == NULL) { if( DEBUGLVL( 0 ) ) { dbgtext( "collect_all_workgroup_names_from_wins_server:\n" ); dbgtext( "Cannot find my workgroup %s ", lp_workgroup() ); dbgtext( "on subnet %s.\n", unicast_subnet->subnet_name ); } return; } if(!AM_DOMAIN_MASTER_BROWSER(work)) return; if ((lastrun != 0) && (t < lastrun + (15 * 60))) return; lastrun = t; /* First, query for the *<1b> name from the WINS server. */ query_name(unicast_subnet, "*", 0x1b, find_all_domain_master_names_query_success, find_all_domain_master_names_query_fail, NULL); }
void sync_all_dmbs(time_t t) { static time_t lastrun = 0; struct work_record *work; int count=0; /* 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. */ work = find_workgroup_on_subnet(unicast_subnet, lp_workgroup()); if (!work) return; if (!AM_DOMAIN_MASTER_BROWSER(work)) return; 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(lp_workgroup(), work->work_group)) { count++; } } /* sync with a probability of 1/count */ for (work=unicast_subnet->workgrouplist; work; work = work->next) { if (strcmp(lp_workgroup(), work->work_group)) { unstring dmb_name; if (((unsigned)sys_random()) % count != 0) continue; lastrun = t; if (!work->dmb_name.name[0]) { /* we don't know the DMB - assume it is the same as the unicast local master */ make_nmb_name(&work->dmb_name, work->local_master_browser_name, 0x20); } pull_ascii_nstring(dmb_name, sizeof(dmb_name), work->dmb_name.name); DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n", dmb_name, inet_ntoa(work->dmb_addr))); sync_browse_lists(work, dmb_name, work->dmb_name.name_type, work->dmb_addr, False, False); } } }
static void reset_workgroup_state( struct subnet_record *subrec, const char *workgroup_name, bool force_new_election ) { struct work_record *work; struct server_record *servrec; struct nmb_name nmbname; if((work = find_workgroup_on_subnet( subrec, workgroup_name)) == NULL) { DEBUG(0,("reset_workgroup_state: Error - cannot find workgroup %s on \ subnet %s.\n", workgroup_name, subrec->subnet_name )); return; }
void process_workgroup_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf) { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; unstring workgroup_announce_name; unstring master_name; uint32 servertype = IVAL(buf,23); struct work_record *work; unstring source_name; unstring dest_name; START_PROFILE(workgroup_announce); pull_ascii_nstring(workgroup_announce_name,sizeof(workgroup_announce_name),buf+5); pull_ascii_nstring(master_name,sizeof(master_name),buf+31); pull_ascii_nstring(source_name,sizeof(source_name),dgram->source_name.name); pull_ascii_nstring(dest_name,sizeof(dest_name),dgram->dest_name.name); DEBUG(3,("process_workgroup_announce: from %s<%02x> IP %s to \ %s for workgroup %s.\n", source_name, source_name[15], inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name),workgroup_announce_name)); DEBUG(5,("process_workgroup_announce: ttl=%d server type=%08x master browser=%s\n", ttl, servertype, master_name)); /* Workgroup announcements must only go to the MSBROWSE name. */ if (!strequal(dest_name, MSBROWSE) || (dgram->dest_name.name_type != 0x1)) { DEBUG(0,("process_workgroup_announce: from IP %s should be to __MSBROWSE__<0x01> not %s\n", inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name))); goto done; } 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) goto done; } else { /* Update the workgroup death_time. */ update_workgroup_ttl(work, ttl); } if(*work->local_master_browser_name == '\0') { /* Set the master browser name. */ set_workgroup_local_master_browser_name( work, master_name ); } subrec->work_changed = True; done: END_PROFILE(workgroup_announce); }
static void become_domain_master_fail(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name) { struct work_record *work = find_workgroup_on_subnet(subrec, fail_name->name); struct server_record *servrec; if(!work) { DEBUG(0,("become_domain_master_fail: Error - cannot find \ workgroup %s on subnet %s\n", fail_name->name, subrec->subnet_name)); return; }
static void become_logon_server_fail(struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *fail_name) { unstring failname; struct work_record *work; struct server_record *servrec; pull_ascii_nstring(failname, sizeof(failname), fail_name->name); work = find_workgroup_on_subnet(subrec, failname); if(!work) { DEBUG(0,("become_logon_server_fail: Error - cannot find \ workgroup %s on subnet %s\n", failname, subrec->subnet_name)); return; }
void announce_my_lm_server_names(time_t t) { struct subnet_record *subrec; static time_t last_lm_announce_time=0; int announce_interval = lp_lm_interval(); int lm_announce = lp_lm_announce(); if ((announce_interval <= 0) || (lm_announce <= 0)) { /* user absolutely does not want LM announcements to be sent. */ return; } if ((lm_announce >= 2) && (!found_lm_clients)) { /* has been set to 2 (Auto) but no LM clients detected (yet). */ return; } /* Otherwise: must have been set to 1 (Yes), or LM clients *have* been detected. */ for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { struct work_record *work = find_workgroup_on_subnet(subrec, global_myworkgroup); if(work) { struct server_record *servrec; if (last_lm_announce_time && ((t - last_lm_announce_time) < announce_interval )) continue; last_lm_announce_time = t; for (servrec = work->serverlist; servrec; servrec = servrec->next) { if (is_myname(servrec->serv.name)) /* skipping equivalent of announce_server() */ send_lm_host_announcement(subrec, work, servrec, announce_interval); } } /* if work */ } /* for subrec */ }
/**************************************************************************** As a domain master browser, do a sync with a local master browser. **************************************************************************/ static void sync_with_lmb(struct browse_cache_record *browc) { struct work_record *work; if( !(work = find_workgroup_on_subnet(unicast_subnet, browc->work_group)) ) { if( DEBUGLVL( 0 ) ) { dbgtext( "sync_with_lmb:\n" ); dbgtext( "Failed to get a workgroup for a local master browser " ); dbgtext( "cache entry workgroup " ); dbgtext( "%s, server %s\n", browc->work_group, browc->lmb_name ); } return; } /* We should only be doing this if we are a domain master browser for the given workgroup. Ensure this is so. */ if(!AM_DOMAIN_MASTER_BROWSER(work)) { if( DEBUGLVL( 0 ) ) { dbgtext( "sync_with_lmb:\n" ); dbgtext( "We are trying to sync with a local master browser " ); dbgtext( "%s for workgroup %s\n", browc->lmb_name, browc->work_group ); dbgtext( "and we are not a domain master browser on this workgroup.\n" ); dbgtext( "Error!\n" ); } return; } if( DEBUGLVL( 2 ) ) { dbgtext( "sync_with_lmb:\n" ); dbgtext( "Initiating sync with local master browser " ); dbgtext( "%s<0x20> at IP %s ", browc->lmb_name, inet_ntoa(browc->ip) ); dbgtext( "for workgroup %s\n", browc->work_group ); } sync_browse_lists(work, browc->lmb_name, 0x20, browc->ip, True, True); browc->sync_time += (CHECK_TIME_DMB_TO_LMB_SYNC * 60); }
static void check_for_master_browser_fail( struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *question_name, int fail_code) { char *workgroup_name = question_name->name; struct work_record *work = find_workgroup_on_subnet(subrec, workgroup_name); if(work == NULL) { DEBUG(0,("check_for_master_browser_fail: Unable to find workgroup %s on subnet %s.=\n", workgroup_name, subrec->subnet_name )); return; } if (strequal(work->work_group, global_myworkgroup)) { 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, ""); } } }
void announce_my_server_names(time_t t) { struct subnet_record *subrec; for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) { struct work_record *work = find_workgroup_on_subnet(subrec, global_myworkgroup); if(work) { struct server_record *servrec; if (work->needannounce) { /* Drop back to a max 3 minute announce. This is to prevent a single lost packet from breaking things for too long. */ work->announce_interval = MIN(work->announce_interval, CHECK_TIME_MIN_HOST_ANNCE*60); work->lastannounce_time = t - (work->announce_interval+1); work->needannounce = False; } /* Announce every minute at first then progress to every 12 mins */ if ((t - work->lastannounce_time) < work->announce_interval) continue; if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60)) work->announce_interval += 60; work->lastannounce_time = t; for (servrec = work->serverlist; servrec; servrec = servrec->next) { if (is_myname(servrec->serv.name)) announce_server(subrec, work, servrec); } } /* if work */ } /* for subrec */ }
void browse_sync_remote(time_t t) { char *s; const char *ptr; static time_t last_time = 0; char *s2; struct in_addr addr; struct work_record *work; char outbuf[1024]; char *p; unstring myname; TALLOC_CTX *frame = NULL; if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL))) return; last_time = t; s = lp_remote_browse_sync(talloc_tos()); if (!*s) return; /* * We only do this if we are the local master browser * for our workgroup on the firsst subnet. */ if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL) { DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n", lp_workgroup(), 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", lp_workgroup(), FIRST_SUBNET->subnet_name )); return; }
static void find_domain_master_name_query_success(struct subnet_record *subrec, struct userdata_struct *userdata_in, struct nmb_name *q_name, struct in_addr answer_ip, struct res_rec *rrec) { /* * Unfortunately, finding the IP address of the Domain Master Browser, * as we have here, is not enough. We need to now do a sync to the * SERVERNAME<0x20> NetBIOS name, as only recent NT servers will * respond to the SMBSERVER name. To get this name from IP * address we do a Node status request, and look for the first * NAME<0x20> in the response, and take that as the server name. * We also keep a cache of the Domain Master Browser name for this * workgroup in the Workgroup struct, so that if the same IP addess * is returned every time, we don't need to do the node status * request. */ struct work_record *work; struct nmb_name nmbname; struct userdata_struct *userdata; int size = sizeof(struct userdata_struct) + sizeof(fstring)+1; if( !(work = find_workgroup_on_subnet(subrec, q_name->name)) ) { if( DEBUGLVL( 0 ) ) { dbgtext( "find_domain_master_name_query_success:\n" ); dbgtext( "Failed to find workgroup %s\n", q_name->name ); } return; } /* First check if we already have a dmb for this workgroup. */ if(!is_zero_ip(work->dmb_addr) && ip_equal(work->dmb_addr, answer_ip)) { /* Do the local master browser announcement to the domain master browser name and IP. */ announce_local_master_browser_to_domain_master_browser( work ); /* Now synchronise lists with the domain master browser. */ sync_with_dmb(work); return; } else zero_ip(&work->dmb_addr); /* Now initiate the node status request. */ make_nmb_name(&nmbname,"*",0x0); /* Put the workgroup name into the userdata so we know what workgroup we're talking to when the reply comes back. */ /* Setup the userdata_struct - this is copied so we can use a stack variable for this. */ if((userdata = (struct userdata_struct *)malloc(size)) == NULL) { DEBUG(0, ("find_domain_master_name_query_success: malloc fail.\n")); return; } userdata->copy_fn = NULL; userdata->free_fn = NULL; userdata->userdata_len = strlen(work->work_group)+1; pstrcpy(userdata->data, work->work_group); node_status( subrec, &nmbname, answer_ip, domain_master_node_status_success, domain_master_node_status_fail, userdata); zero_free(userdata, size); }
static void domain_master_node_status_success(struct subnet_record *subrec, struct userdata_struct *userdata, struct res_rec *answers, struct in_addr from_ip) { struct work_record *work = find_workgroup_on_subnet( subrec, userdata->data); if( work == NULL ) { if( DEBUGLVL( 0 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Unable to find workgroup " ); dbgtext( "%s on subnet %s.\n", userdata->data, subrec->subnet_name ); } return; } if( DEBUGLVL( 3 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Success in node status for workgroup " ); dbgtext( "%s from ip %s\n", work->work_group, inet_ntoa(from_ip) ); } /* Go through the list of names found at answers->rdata and look for the first SERVER<0x20> name. */ if(answers->rdata != NULL) { char *p = answers->rdata; int numnames = CVAL(p, 0); p += 1; while (numnames--) { char qname[17]; uint16 nb_flags; int name_type; StrnCpy(qname,p,15); name_type = CVAL(p,15); nb_flags = get_nb_flags(&p[16]); trim_string(qname,NULL," "); p += 18; if(!(nb_flags & NB_GROUP) && (name_type == 0x20)) { struct nmb_name nmbname; make_nmb_name(&nmbname, qname, name_type); /* Copy the dmb name and IP address into the workgroup struct. */ work->dmb_name = nmbname; putip((char *)&work->dmb_addr, &from_ip); /* Do the local master browser announcement to the domain master browser name and IP. */ announce_local_master_browser_to_domain_master_browser( work ); /* Now synchronise lists with the domain master browser. */ sync_with_dmb(work); break; } } } else if( DEBUGLVL( 0 ) ) { dbgtext( "domain_master_node_status_success:\n" ); dbgtext( "Failed to find a SERVER<0x20> name in reply from IP " ); dbgtext( "%s.\n", inet_ntoa(from_ip) ); } }
void process_local_master_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf) { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; unstring server_name; uint32 servertype = IVAL(buf,23); fstring comment; unstring work_name; struct work_record *work; struct server_record *servrec; unstring source_name; START_PROFILE(local_master_announce); pull_ascii_nstring(server_name,sizeof(server_name),buf+5); pull_ascii_fstring(comment, buf+31); pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name); DEBUG(3,("process_local_master_announce: from %s<%02x> IP %s to \ %s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name),server_name)); DEBUG(5,("process_local_master_announce: ttl=%d server type=%08x comment=%s\n", ttl, servertype, comment)); /* A local master announcement must be sent to the name WORKGROUP<1e>. */ if(dgram->dest_name.name_type != 0x1e) { DEBUG(0,("process_local_master_announce: incorrect name type for destination from IP %s \ (was %02x) should be 0x1e. Ignoring packet.\n", inet_ntoa(p->ip), dgram->dest_name.name_type)); goto done; } /* Filter servertype to remove impossible bits. */ servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM); /* For a local master announce the workgroup name is the destination name. */ if ((work = find_workgroup_on_subnet(subrec, work_name))==NULL) { /* Don't bother adding if it's a local master release announce. */ if(servertype == 0) goto done; /* We have no record of this workgroup. Add it. */ if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL) goto done; } /* If we think we're the local master browser for this workgroup, we should never have got this packet. We don't see our own packets. */ if(AM_LOCAL_MASTER_BROWSER(work)) { 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)); /* Samba nmbd versions 1.9.17 to 1.9.17p4 have a bug in that when they have become a local master browser once, they will never stop sending local master announcements. To fix this we send them a reset browser packet, with level 0x2 on the __SAMBA__ name that only they should be listening to. */ send_browser_reset( 0x2, "__SAMBA__" , 0x20, p->ip); /* We should demote ourself and force an election. */ unbecome_local_master_browser( subrec, work, True); /* The actual election requests are handled in nmbd_election.c */ goto done; } /* Find the server record on this workgroup. If it doesn't exist, add it. */ if(servertype != 0) { if((servrec = find_server_in_workgroup( work, server_name))==NULL) { /* If this server is not already in the workgroup, add it. */ create_server_on_workgroup(work, server_name, servertype|SV_TYPE_LOCAL_LIST_ONLY, ttl, comment); } else { /* Update the record. */ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY; update_server_ttl(servrec, ttl); fstrcpy(servrec->serv.comment,comment); } set_workgroup_local_master_browser_name( work, server_name ); } else { /* * This server is announcing it is going down. Remove it from the * workgroup. */ if(!is_myname(server_name) && (work != NULL) && ((servrec = find_server_in_workgroup( work, server_name))!=NULL)) { remove_server_from_workgroup( work, servrec); } } subrec->work_changed = True; done: END_PROFILE(local_master_announce); }
static void get_domain_master_name_node_status_success(struct subnet_record *subrec, struct userdata_struct *userdata, struct res_rec *answers, struct in_addr from_ip) { struct work_record *work; fstring server_name; server_name[0] = 0; if( DEBUGLVL( 3 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "Success in node status from ip %s\n", inet_ntoa(from_ip) ); } /* * Go through the list of names found at answers->rdata and look for * the first WORKGROUP<0x1b> name. */ if(answers->rdata != NULL) { char *p = answers->rdata; int numnames = CVAL(p, 0); p += 1; while (numnames--) { char qname[17]; uint16 nb_flags; int name_type; StrnCpy(qname,p,15); name_type = CVAL(p,15); nb_flags = get_nb_flags(&p[16]); trim_string(qname,NULL," "); p += 18; if(!(nb_flags & NB_GROUP) && (name_type == 0x00) && server_name[0] == 0) { /* this is almost certainly the server netbios name */ fstrcpy(server_name, qname); continue; } if(!(nb_flags & NB_GROUP) && (name_type == 0x1b)) { if( DEBUGLVL( 5 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "%s(%s) ", server_name, inet_ntoa(from_ip) ); dbgtext( "is a domain master browser for workgroup " ); dbgtext( "%s. Adding this name.\n", qname ); } /* * If we don't already know about this workgroup, add it * to the workgroup list on the unicast_subnet. */ if((work = find_workgroup_on_subnet( subrec, qname)) == NULL) { struct nmb_name nmbname; /* * Add it - with an hour in the cache. */ if(!(work= create_workgroup_on_subnet(subrec, qname, 60*60))) return; /* remember who the master is */ fstrcpy(work->local_master_browser_name, server_name); make_nmb_name(&nmbname, server_name, 0x20); work->dmb_name = nmbname; work->dmb_addr = from_ip; } break; } } } else if( DEBUGLVL( 0 ) ) { dbgtext( "get_domain_master_name_node_status_success:\n" ); dbgtext( "Failed to find a WORKGROUP<0x1b> name in reply from IP " ); dbgtext( "%s.\n", inet_ntoa(from_ip) ); } }
void process_host_announce(struct subnet_record *subrec, struct packet_struct *p, char *buf) { struct dgram_packet *dgram = &p->packet.dgram; int ttl = IVAL(buf,1)/1000; unstring announce_name; uint32 servertype = IVAL(buf,23); fstring comment; struct work_record *work; struct server_record *servrec; unstring work_name; unstring source_name; START_PROFILE(host_announce); pull_ascii_fstring(comment, buf+31); pull_ascii_nstring(announce_name, sizeof(announce_name), buf+5); pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); DEBUG(3,("process_host_announce: from %s<%02x> IP %s to \ %s for server %s.\n", source_name, source_name[15], inet_ntoa(p->ip), nmb_namestr(&dgram->dest_name),announce_name)); DEBUG(5,("process_host_announce: ttl=%d server type=%08x comment=%s\n", ttl, servertype,comment)); /* Filter servertype to remove impossible bits. */ servertype &= ~(SV_TYPE_LOCAL_LIST_ONLY|SV_TYPE_DOMAIN_ENUM); /* A host announcement must be sent to the name WORKGROUP<1d>. */ if(dgram->dest_name.name_type != 0x1d) { DEBUG(2,("process_host_announce: incorrect name type for destination from IP %s \ (was %02x) should be 0x1d. Allowing packet anyway.\n", inet_ntoa(p->ip), dgram->dest_name.name_type)); /* Change it so it was. */ dgram->dest_name.name_type = 0x1d; } /* For a host announce the workgroup name is the destination name. */ pull_ascii_nstring(work_name, sizeof(work_name), dgram->dest_name.name); /* * Syntax servers version 5.1 send HostAnnounce packets to * *THE WRONG NAME*. They send to LOCAL_MASTER_BROWSER_NAME<00> * instead of WORKGROUP<1d> name. So to fix this we check if * the workgroup name is our own name, and if so change it * to be our primary workgroup name. */ if(strequal(work_name, global_myname())) unstrcpy(work_name,lp_workgroup()); /* * We are being very agressive here in adding a workgroup * name on the basis of a host announcing itself as being * in that workgroup. Maybe we should wait for the workgroup * announce instead ? JRA. */ work = find_workgroup_on_subnet(subrec, work_name); if(servertype != 0) { if (work ==NULL ) { /* We have no record of this workgroup. Add it. */ if((work = create_workgroup_on_subnet(subrec, work_name, ttl))==NULL) goto done; } if((servrec = find_server_in_workgroup( work, announce_name))==NULL) { /* If this server is not already in the workgroup, add it. */ create_server_on_workgroup(work, announce_name, servertype|SV_TYPE_LOCAL_LIST_ONLY, ttl, comment); } else { /* Update the record. */ servrec->serv.type = servertype|SV_TYPE_LOCAL_LIST_ONLY; update_server_ttl( servrec, ttl); fstrcpy(servrec->serv.comment,comment); } } else { /* * This server is announcing it is going down. Remove it from the * workgroup. */ if(!is_myname(announce_name) && (work != NULL) && ((servrec = find_server_in_workgroup( work, announce_name))!=NULL)) { remove_server_from_workgroup( work, servrec); } } subrec->work_changed = True; done: END_PROFILE(host_announce); }