📄 nmbd_namelistdb.c
字号:
******************************************************************/static void remove_nth_ip_in_record( struct name_record *namerec, int ind){ if( ind != namerec->data.num_ips ) { memmove( (char *)(&namerec->data.ip[ind]), (char *)(&namerec->data.ip[ind+1]), ( namerec->data.num_ips - ind - 1) * sizeof(struct in_addr) ); } namerec->data.num_ips--; namerec->subnet->namelist_changed = True;}/******************************************************************* Utility function to check if an IP address exists in a name record. ******************************************************************/BOOL find_ip_in_name_record( struct name_record *namerec, struct in_addr ip ){ int i; for(i = 0; i < namerec->data.num_ips; i++) { if(ip_equal( namerec->data.ip[i], ip)) { return True; } } return False;}/******************************************************************* Utility function to add an IP address to a name record. ******************************************************************/void add_ip_to_name_record( struct name_record *namerec, struct in_addr new_ip ){ struct in_addr *new_list; /* Don't add one we already have. */ if( find_ip_in_name_record( namerec, new_ip )) { return; } new_list = SMB_MALLOC_ARRAY( struct in_addr, namerec->data.num_ips + 1); if( NULL == new_list ) { DEBUG(0,("add_ip_to_name_record: Malloc fail !\n")); return; } memcpy( (char *)new_list, (char *)namerec->data.ip, namerec->data.num_ips * sizeof(struct in_addr) ); new_list[namerec->data.num_ips] = new_ip; SAFE_FREE(namerec->data.ip); namerec->data.ip = new_list; namerec->data.num_ips += 1; namerec->subnet->namelist_changed = True;}/******************************************************************* Utility function to remove an IP address from a name record. ******************************************************************/void remove_ip_from_name_record( struct name_record *namerec, struct in_addr remove_ip ){ /* Try and find the requested ip address - remove it. */ int i; int orig_num = namerec->data.num_ips; for(i = 0; i < orig_num; i++) { if( ip_equal( remove_ip, namerec->data.ip[i]) ) { remove_nth_ip_in_record( namerec, i); break; } }}/******************************************************************* Utility function that release_name callers can plug into as the success function when a name release is successful. Used to save duplication of success_function code. ******************************************************************/void standard_success_release( struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *nmbname, struct in_addr released_ip ){ struct name_record *namerec; namerec = find_name_on_subnet( subrec, nmbname, FIND_ANY_NAME ); if( namerec == NULL ) { DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \on subnet %s. Name was not found on subnet.\n", nmb_namestr(nmbname), inet_ntoa(released_ip), subrec->subnet_name) ); return; } else { int orig_num = namerec->data.num_ips; remove_ip_from_name_record( namerec, released_ip ); if( namerec->data.num_ips == orig_num ) { DEBUG( 0, ( "standard_success_release: Name release for name %s IP %s \on subnet %s. This ip is not known for this name.\n", nmb_namestr(nmbname), inet_ntoa(released_ip), subrec->subnet_name ) ); } } if( namerec->data.num_ips == 0 ) { remove_name_from_namelist( subrec, namerec ); }}/******************************************************************* Expires old names in a subnet namelist.******************************************************************/void expire_names_on_subnet(struct subnet_record *subrec, time_t t){ struct name_record *namerec; struct name_record *next_namerec; for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec; namerec = next_namerec ) { next_namerec = (struct name_record *)ubi_trNext( namerec ); if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < t) ) { if( namerec->data.source == SELF_NAME ) { DEBUG( 3, ( "expire_names_on_subnet: Subnet %s not expiring SELF \name %s\n", subrec->subnet_name, nmb_namestr(&namerec->name) ) ); namerec->data.death_time += 300; namerec->subnet->namelist_changed = True; continue; } DEBUG(3,("expire_names_on_subnet: Subnet %s - removing expired name %s\n", subrec->subnet_name, nmb_namestr(&namerec->name))); remove_name_from_namelist(subrec, namerec ); } }}/******************************************************************* Expires old names in all subnet namelists.******************************************************************/void expire_names(time_t t){ struct subnet_record *subrec; for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) ) { expire_names_on_subnet( subrec, t ); }}/**************************************************************************** Add the magic samba names, useful for finding samba servers. These go directly into the name list for a particular subnet, without going through the normal registration process. When adding them to the unicast subnet, add them as a list of all broadcast subnet IP addresses.**************************************************************************/void add_samba_names_to_subnet( struct subnet_record *subrec ){ struct in_addr *iplist = &subrec->myip; int num_ips = 1; /* These names are added permanently (ttl of zero) and will NOT be refreshed. */ if( (subrec == unicast_subnet) || (subrec == wins_server_subnet) || (subrec == remote_broadcast_subnet) ) { struct subnet_record *bcast_subrecs; int i; /* Create an IP list containing all our known subnets. */ num_ips = iface_count(); iplist = SMB_MALLOC_ARRAY( struct in_addr, num_ips); if( NULL == iplist ) { DEBUG(0,("add_samba_names_to_subnet: Malloc fail !\n")); return; } for( bcast_subrecs = FIRST_SUBNET, i = 0; bcast_subrecs; bcast_subrecs = NEXT_SUBNET_EXCLUDING_UNICAST(bcast_subrecs), i++ ) iplist[i] = bcast_subrecs->myip; } add_name_to_subnet(subrec,"*",0x0,samba_nb_type, PERMANENT_TTL, PERMANENT_NAME, num_ips, iplist); add_name_to_subnet(subrec,"*",0x20,samba_nb_type,PERMANENT_TTL, PERMANENT_NAME, num_ips, iplist); add_name_to_subnet(subrec,"__SAMBA__",0x20,samba_nb_type,PERMANENT_TTL, PERMANENT_NAME, num_ips, iplist); add_name_to_subnet(subrec,"__SAMBA__",0x00,samba_nb_type,PERMANENT_TTL, PERMANENT_NAME, num_ips, iplist); if(iplist != &subrec->myip) { SAFE_FREE(iplist); }}/**************************************************************************** Dump a name_record struct.**************************************************************************/static void dump_subnet_namelist( struct subnet_record *subrec, XFILE *fp){ struct name_record *namerec; const char *src_type; struct tm *tm; int i; x_fprintf(fp, "Subnet %s\n----------------------\n", subrec->subnet_name); for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist ); namerec; namerec = (struct name_record *)ubi_trNext( namerec ) ) { x_fprintf(fp,"\tName = %s\t", nmb_namestr(&namerec->name)); switch(namerec->data.source) { case LMHOSTS_NAME: src_type = "LMHOSTS_NAME"; break; case WINS_PROXY_NAME: src_type = "WINS_PROXY_NAME"; break; case REGISTER_NAME: src_type = "REGISTER_NAME"; break; case SELF_NAME: src_type = "SELF_NAME"; break; case DNS_NAME: src_type = "DNS_NAME"; break; case DNSFAIL_NAME: src_type = "DNSFAIL_NAME"; break; case PERMANENT_NAME: src_type = "PERMANENT_NAME"; break; default: src_type = "unknown!"; break; } x_fprintf(fp,"Source = %s\nb_flags = %x\t", src_type, namerec->data.nb_flags); if(namerec->data.death_time != PERMANENT_TTL) { tm = localtime(&namerec->data.death_time); x_fprintf(fp, "death_time = %s\t", asctime(tm)); } else { x_fprintf(fp, "death_time = PERMANENT\t"); } if(namerec->data.refresh_time != PERMANENT_TTL) { tm = localtime(&namerec->data.refresh_time); x_fprintf(fp, "refresh_time = %s\n", asctime(tm)); } else { x_fprintf(fp, "refresh_time = PERMANENT\n"); } x_fprintf(fp, "\t\tnumber of IPS = %d", namerec->data.num_ips); for(i = 0; i < namerec->data.num_ips; i++) { x_fprintf(fp, "\t%s", inet_ntoa(namerec->data.ip[i])); } x_fprintf(fp, "\n\n"); }}/**************************************************************************** Dump the contents of the namelists on all the subnets (including unicast) into a file. Initiated by SIGHUP - used to debug the state of the namelists.**************************************************************************/void dump_all_namelists(void){ XFILE *fp; struct subnet_record *subrec; fp = x_fopen(lock_path("namelist.debug"),O_WRONLY|O_CREAT|O_TRUNC, 0644); if (!fp) { DEBUG(0,("dump_all_namelists: Can't open file %s. Error was %s\n", "namelist.debug",strerror(errno))); return; } for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec) ) dump_subnet_namelist( subrec, fp ); if( !we_are_a_wins_client() ) dump_subnet_namelist( unicast_subnet, fp ); if( remote_broadcast_subnet->namelist != NULL ) dump_subnet_namelist( remote_broadcast_subnet, fp ); if( wins_server_subnet != NULL ) dump_subnet_namelist( wins_server_subnet, fp ); x_fclose( fp );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -