⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nmbd_namelistdb.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   NBT netbios routines and daemon - version 2   Copyright (C) Andrew Tridgell 1994-1998   Copyright (C) Luke Kenneth Casson Leighton 1994-1998   Copyright (C) Jeremy Allison 1994-2003      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */#include "includes.h"uint16 samba_nb_type = 0; /* samba's NetBIOS name type *//************************************************************************** Set Samba's NetBIOS name type.***************************************************************************/void set_samba_nb_type(void){	if( lp_wins_support() || wins_srv_count() ) {		samba_nb_type = NB_HFLAG;               /* samba is a 'hybrid' node type. */	} else {		samba_nb_type = NB_BFLAG;           /* samba is broadcast-only node type. */	}}/*************************************************************************** Convert a NetBIOS name to upper case.***************************************************************************/static void upcase_name( struct nmb_name *target, const struct nmb_name *source ){	int i;	unstring targ;	fstring scope;	if( NULL != source ) {		memcpy( target, source, sizeof( struct nmb_name ) );	}	pull_ascii_nstring(targ, sizeof(targ), target->name);	strupper_m( targ );	push_ascii_nstring( target->name, targ);	pull_ascii(scope, target->scope, 64, -1, STR_TERMINATE);	strupper_m( scope );	push_ascii(target->scope, scope, 64, STR_TERMINATE);	/* fudge... We're using a byte-by-byte compare, so we must be sure that	 * unused space doesn't have garbage in it.	 */	for( i = strlen( target->name ); i < sizeof( target->name ); i++ ) {		target->name[i] = '\0';	}	for( i = strlen( target->scope ); i < sizeof( target->scope ); i++ ) {		target->scope[i] = '\0';	}}/************************************************************************** Remove a name from the namelist.***************************************************************************/static void update_name_in_namelist( struct subnet_record *subrec,                              struct name_record   *namerec ){	struct name_record *oldrec = NULL;	ubi_trInsert( subrec->namelist, namerec, &(namerec->name), &oldrec );	if( oldrec ) {		SAFE_FREE( oldrec->data.ip );		SAFE_FREE( oldrec );	}}/************************************************************************** Remove a name from the namelist.***************************************************************************/void remove_name_from_namelist( struct subnet_record *subrec,                                 struct name_record   *namerec ){	ubi_trRemove( subrec->namelist, namerec );	SAFE_FREE(namerec->data.ip);	ZERO_STRUCTP(namerec);	SAFE_FREE(namerec);	subrec->namelist_changed = True;}/************************************************************************** Find a name in a subnet.**************************************************************************/struct name_record *find_name_on_subnet(struct subnet_record *subrec,				const struct nmb_name *nmbname,				BOOL self_only){	struct nmb_name     uc_name[1];	struct name_record *name_ret;	upcase_name( uc_name, nmbname );	name_ret = (struct name_record *)ubi_trFind( subrec->namelist, uc_name );	if( name_ret ) {		/* Self names only - these include permanent names. */		if( self_only && (name_ret->data.source != SELF_NAME) && (name_ret->data.source != PERMANENT_NAME) ) {			DEBUG( 9, ( "find_name_on_subnet: on subnet %s - self name %s NOT FOUND\n",						subrec->subnet_name, nmb_namestr(nmbname) ) );			return( NULL );		}		DEBUG( 9, ("find_name_on_subnet: on subnet %s - found name %s source=%d\n",			subrec->subnet_name, nmb_namestr(nmbname), name_ret->data.source) );		return name_ret;	}	DEBUG( 9, ( "find_name_on_subnet: on subnet %s - name %s NOT FOUND\n",		subrec->subnet_name, nmb_namestr(nmbname) ) );	return NULL;}/************************************************************************** Find a name over all known broadcast subnets.************************************************************************/struct name_record *find_name_for_remote_broadcast_subnet(struct nmb_name *nmbname,						BOOL self_only){	struct subnet_record *subrec;	struct name_record *namerec;	for( subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec) ) {		namerec = find_name_on_subnet(subrec, nmbname, self_only);		if (namerec) {			return namerec;		}	}	return NULL;}  /************************************************************************** Update the ttl of an entry in a subnet name list.***************************************************************************/void update_name_ttl( struct name_record *namerec, int ttl ){	time_t time_now = time(NULL);	if( namerec->data.death_time != PERMANENT_TTL) {		namerec->data.death_time = time_now + ttl;	}	namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);	namerec->subnet->namelist_changed = True;}/************************************************************************** Add an entry to a subnet name list.***********************************************************************/struct name_record *add_name_to_subnet( struct subnet_record *subrec,                                        const char           *name,                                        int                   type,                                        uint16                nb_flags,                                        int                   ttl,                                        enum name_source      source,                                        int                   num_ips,                                        struct in_addr       *iplist){	struct name_record *namerec;	time_t time_now = time(NULL);	namerec = SMB_MALLOC_P(struct name_record);	if( NULL == namerec ) {		DEBUG( 0, ( "add_name_to_subnet: malloc fail.\n" ) );		return( NULL );	}	memset( (char *)namerec, '\0', sizeof(*namerec) );	namerec->data.ip = SMB_MALLOC_ARRAY( struct in_addr, num_ips );	if( NULL == namerec->data.ip ) {		DEBUG( 0, ( "add_name_to_subnet: malloc fail when creating ip_flgs.\n" ) );		ZERO_STRUCTP(namerec);		SAFE_FREE(namerec);		return NULL;	}	namerec->subnet = subrec;	make_nmb_name(&namerec->name, name, type);	upcase_name(&namerec->name, NULL );	/* Enter the name as active. */	namerec->data.nb_flags = nb_flags | NB_ACTIVE;	namerec->data.wins_flags = WINS_ACTIVE;	/* If it's our primary name, flag it as so. */	if (strequal( my_netbios_names(0), name )) {		namerec->data.nb_flags |= NB_PERM;	}	/* Copy the IPs. */	namerec->data.num_ips = num_ips;	memcpy( (namerec->data.ip), iplist, num_ips * sizeof(struct in_addr) );	/* Data source. */	namerec->data.source = source;	/* Setup the death_time and refresh_time. */	if (ttl == PERMANENT_TTL) {		namerec->data.death_time = PERMANENT_TTL;	} else {		namerec->data.death_time = time_now + ttl;	}	namerec->data.refresh_time = time_now + MIN((ttl/2), MAX_REFRESH_TIME);	/* Now add the record to the name list. */    	update_name_in_namelist( subrec, namerec );	DEBUG( 3, ( "add_name_to_subnet: Added netbios name %s with first IP %s \ttl=%d nb_flags=%2x to subnet %s\n",		nmb_namestr( &namerec->name ),		inet_ntoa( *iplist ),		ttl,		(unsigned int)nb_flags,		subrec->subnet_name ) );	subrec->namelist_changed = True;	return(namerec);}/******************************************************************* Utility function automatically called when a name refresh or register  succeeds. By definition this is a SELF_NAME (or we wouldn't be registering it). ******************************************************************/void standard_success_register(struct subnet_record *subrec,                              struct userdata_struct *userdata,                             struct nmb_name *nmbname, uint16 nb_flags, int ttl,                             struct in_addr registered_ip){	struct name_record *namerec;	namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME);	if (namerec == NULL) {		unstring name;		pull_ascii_nstring(name, sizeof(name), nmbname->name);		add_name_to_subnet( subrec, name, nmbname->name_type,			nb_flags, ttl, SELF_NAME, 1, &registered_ip );	} else {		update_name_ttl( namerec, ttl );	}}/******************************************************************* Utility function automatically called when a name refresh or register  fails. Note that this is only ever called on a broadcast subnet with one IP address per name. This is why it can just delete the name  without enumerating the IP adresses. JRA. ******************************************************************/void standard_fail_register( struct subnet_record   *subrec,                             struct response_record *rrec,                             struct nmb_name        *nmbname ){	struct name_record *namerec;	namerec = find_name_on_subnet( subrec, nmbname, FIND_SELF_NAME);	DEBUG( 0, ( "standard_fail_register: Failed to register/refresh name %s \on subnet %s\n", nmb_namestr(nmbname), subrec->subnet_name) );	/* Remove the name from the subnet. */	if( namerec ) {		remove_name_from_namelist(subrec, namerec);	}}/******************************************************************* Utility function to remove an IP address from a name record.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -