nmbd/nmbd_winsserver.c

ソースコードを見る。

関数

static void wins_delete_all_tmp_in_memory_records (void)
static struct name_recordwins_record_to_name_record (TDB_DATA key, TDB_DATA data)
static TDB_DATA name_record_to_wins_record (const struct name_record *namerec)
static TDB_DATA name_to_key (const struct nmb_name *nmbname)
name_recordfind_name_on_wins_subnet (const struct nmb_name *nmbname, BOOL self_only)
static BOOL store_or_replace_wins_namerec (const struct name_record *namerec, int tdb_flag)
BOOL wins_store_changed_namerec (const struct name_record *namerec)
BOOL add_name_to_wins_subnet (const struct name_record *namerec)
BOOL remove_name_from_wins_namelist (struct name_record *namerec)
static int traverse_fn (TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
void dump_wins_subnet_namelist (XFILE *fp)
static void update_wins_owner (struct name_record *namerec, struct in_addr wins_ip)
static void update_wins_flag (struct name_record *namerec, int flags)
static void get_global_id_and_update (SMB_BIG_UINT *current_id, BOOL update)
static void wins_hook (const char *operation, struct name_record *namerec, int ttl)
BOOL packet_is_for_wins_server (struct packet_struct *packet)
static int get_ttl_from_packet (struct nmb_packet *nmb)
BOOL initialise_wins (void)
static void send_wins_wack_response (int ttl, struct packet_struct *p)
static void send_wins_name_registration_response (int rcode, int ttl, struct packet_struct *p)
void wins_process_name_refresh_request (struct subnet_record *subrec, struct packet_struct *p)
static void wins_register_query_success (struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *question_name, struct in_addr ip, struct res_rec *answers)
static void wins_register_query_fail (struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *question_name, int rcode)
void wins_process_name_registration_request (struct subnet_record *subrec, struct packet_struct *p)
static void wins_multihomed_register_query_success (struct subnet_record *subrec, struct userdata_struct *userdata, struct nmb_name *question_name, struct in_addr ip, struct res_rec *answers)
static void wins_multihomed_register_query_fail (struct subnet_record *subrec, struct response_record *rrec, struct nmb_name *question_name, int rcode)
void wins_process_multihomed_name_registration_request (struct subnet_record *subrec, struct packet_struct *p)
static int fetch_1b_traverse_fn (TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
void fetch_all_active_wins_1b_names (void)
static void process_wins_dmb_query_request (struct subnet_record *subrec, struct packet_struct *p)
void send_wins_name_query_response (int rcode, struct packet_struct *p, struct name_record *namerec)
void wins_process_name_query_request (struct subnet_record *subrec, struct packet_struct *p)
static void send_wins_name_release_response (int rcode, struct packet_struct *p)
void wins_process_name_release_request (struct subnet_record *subrec, struct packet_struct *p)
static int wins_processing_traverse_fn (TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
void initiate_wins_processing (time_t t)
void wins_write_name_record (struct name_record *namerec, XFILE *fp)
static int wins_writedb_traverse_fn (TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
void wins_write_database (time_t t, BOOL background)
Until winsrepl is done void nmbd_wins_new_entry (int msg_type, struct process_id src, void *buf, size_t len, void *private_data)

変数

TDB_CONTEXTwins_tdb


関数

static void wins_delete_all_tmp_in_memory_records ( void   )  [static]

nmbd_winsserver.c41 行で定義されています。

参照先 name_record::datanmb_data::ipsubnet_record::namelistname_record::nextwins_server_subnet.

参照元 initiate_wins_processing()process_wins_dmb_query_request().

00042 {
00043         struct name_record *nr = NULL;
00044         struct name_record *nrnext = NULL;
00045 
00046         /* Delete all temporary name records on the wins subnet linked list. */
00047         for( nr = wins_server_subnet->namelist; nr; nr = nrnext) {
00048                 nrnext = nr->next;
00049                 DLIST_REMOVE(wins_server_subnet->namelist, nr);
00050                 SAFE_FREE(nr->data.ip);
00051                 SAFE_FREE(nr);
00052         }
00053 }

static struct name_record* wins_record_to_name_record ( TDB_DATA  key,
TDB_DATA  data 
) [static]

nmbd_winsserver.c59 行で定義されています。

参照先 name_record::datanmb_data::death_timeTDB_DATA::dptrglobal_scope()nmb_data::idnmb_data::iplennmb_name::namename_record::namenmb_name::name_typenmb_data::nb_flagsnmb_data::num_ipspush_ascii()push_ascii_nstring()nmb_data::refresh_timenmb_name::scopenmb_data::sourcename_record::subnettdb_unpack()nmb_data::wins_flagsnmb_data::wins_ipwins_server_subnet.

参照元 fetch_1b_traverse_fn()find_name_on_wins_subnet()traverse_fn()wins_processing_traverse_fn()wins_writedb_traverse_fn().

00060 {
00061         struct name_record *namerec = NULL;
00062         uint16 nb_flags;
00063         unsigned char nr_src;
00064         uint32 death_time, refresh_time;
00065         uint32 id_low, id_high;
00066         uint32 saddr;
00067         uint32 wins_flags;
00068         uint32 num_ips;
00069         size_t len;
00070         int i;
00071 
00072         if (data.dptr == NULL || data.dsize == 0) {
00073                 return NULL;
00074         }
00075 
00076         /* Min size is "wbddddddd" + 1 ip address (4). */
00077         if (data.dsize < 2 + 1 + (7*4) + 4) {
00078                 return NULL;
00079         }
00080 
00081         len = tdb_unpack(data.dptr, data.dsize,
00082                         "wbddddddd",
00083                         &nb_flags,
00084                         &nr_src,
00085                         &death_time,
00086                         &refresh_time,
00087                         &id_low,
00088                         &id_high,
00089                         &saddr,
00090                         &wins_flags,
00091                         &num_ips );
00092 
00093         namerec = SMB_MALLOC_P(struct name_record);
00094         if (!namerec) {
00095                 return NULL;
00096         }
00097         ZERO_STRUCTP(namerec);
00098 
00099         namerec->data.ip = SMB_MALLOC_ARRAY(struct in_addr, num_ips);
00100         if (!namerec->data.ip) {
00101                 SAFE_FREE(namerec);
00102                 return NULL;
00103         }
00104 
00105         namerec->subnet = wins_server_subnet;
00106         push_ascii_nstring(namerec->name.name, key.dptr);
00107         namerec->name.name_type = key.dptr[sizeof(unstring)];
00108         /* Add the scope. */
00109         push_ascii(namerec->name.scope, global_scope(), 64, STR_TERMINATE);
00110 
00111         /* We're using a byte-by-byte compare, so we must be sure that
00112          * unused space doesn't have garbage in it.
00113          */
00114                                                                                                                                
00115         for( i = strlen( namerec->name.name ); i < sizeof( namerec->name.name ); i++ ) {
00116                 namerec->name.name[i] = '\0';
00117         }
00118         for( i = strlen( namerec->name.scope ); i < sizeof( namerec->name.scope ); i++ ) {
00119                 namerec->name.scope[i] = '\0';
00120         }
00121 
00122         namerec->data.nb_flags = nb_flags;
00123         namerec->data.source = (enum name_source)nr_src;
00124         namerec->data.death_time = (time_t)death_time;
00125         namerec->data.refresh_time = (time_t)refresh_time;
00126         namerec->data.id = id_low;
00127 #if defined(HAVE_LONGLONG)
00128         namerec->data.id |= ((SMB_BIG_UINT)id_high << 32);
00129 #endif
00130         namerec->data.wins_ip.s_addr = saddr;
00131         namerec->data.wins_flags = wins_flags,
00132         namerec->data.num_ips = num_ips;
00133 
00134         for (i = 0; i < num_ips; i++) {
00135                 namerec->data.ip[i].s_addr = IVAL(data.dptr, len + (i*4));
00136         }
00137 
00138         return namerec;
00139 }

static TDB_DATA name_record_to_wins_record ( const struct name_record namerec  )  [static]

nmbd_winsserver.c145 行で定義されています。

参照先 name_record::datanmb_data::death_timenmb_data::idnmb_data::iplennmb_data::nb_flagsnmb_data::num_ipsnmb_data::refresh_timenmb_data::sourcetdb_pack()nmb_data::wins_flagsnmb_data::wins_ip.

参照元 store_or_replace_wins_namerec().

00146 {
00147         TDB_DATA data;
00148         size_t len = 0;
00149         int i;
00150         uint32 id_low = (namerec->data.id & 0xFFFFFFFF);
00151 #if defined(HAVE_LONGLONG)
00152         uint32 id_high = (namerec->data.id >> 32) & 0xFFFFFFFF;
00153 #else
00154         uint32 id_high = 0;
00155 #endif
00156 
00157         ZERO_STRUCT(data);
00158 
00159         len = (2 + 1 + (7*4)); /* "wbddddddd" */
00160         len += (namerec->data.num_ips * 4);
00161 
00162         data.dptr = (char *)SMB_MALLOC(len);
00163         if (!data.dptr) {
00164                 return data;
00165         }
00166         data.dsize = len;
00167 
00168         len = tdb_pack(data.dptr, data.dsize, "wbddddddd",
00169                         namerec->data.nb_flags,
00170                         (unsigned char)namerec->data.source,
00171                         (uint32)namerec->data.death_time,
00172                         (uint32)namerec->data.refresh_time,
00173                         id_low,
00174                         id_high,
00175                         (uint32)namerec->data.wins_ip.s_addr,
00176                         (uint32)namerec->data.wins_flags,
00177                         (uint32)namerec->data.num_ips );
00178 
00179         for (i = 0; i < namerec->data.num_ips; i++) {
00180                 SIVAL(data.dptr, len + (i*4), namerec->data.ip[i].s_addr);
00181         }
00182 
00183         return data;
00184 }

static TDB_DATA name_to_key ( const struct nmb_name nmbname  )  [static]

nmbd_winsserver.c190 行で定義されています。

参照先 nmb_name::namenmb_name::name_typepull_ascii_nstring()strupper_m().

参照元 find_name_on_wins_subnet()remove_name_from_wins_namelist()store_or_replace_wins_namerec().

00191 {
00192         static char keydata[sizeof(unstring) + 1];
00193         TDB_DATA key;
00194 
00195         memset(keydata, '\0', sizeof(keydata));
00196 
00197         pull_ascii_nstring(keydata, sizeof(unstring), nmbname->name);
00198         strupper_m(keydata);
00199         keydata[sizeof(unstring)] = nmbname->name_type;
00200         key.dptr = keydata;
00201         key.dsize = sizeof(keydata);
00202 
00203         return key;
00204 }

struct name_record* find_name_on_wins_subnet ( const struct nmb_name nmbname,
BOOL  self_only 
)

nmbd_winsserver.c211 行で定義されています。

参照先 name_record::datanmb_data::ipname_record::namenmb_name::namename_to_key()subnet_record::namelistname_record::nextnmb_namestr()PERMANENT_NAMESELF_NAMEnmb_data::sourcetdb_fetch()wins_record_to_name_record()wins_server_subnetwins_tdb.

参照元 find_name_on_subnet().

00212 {
00213         TDB_DATA data, key;
00214         struct name_record *nr = NULL;
00215         struct name_record *namerec = NULL;
00216 
00217         if (!wins_tdb) {
00218                 return NULL;
00219         }
00220 
00221         key = name_to_key(nmbname);
00222         data = tdb_fetch(wins_tdb, key);
00223 
00224         if (data.dsize == 0) {
00225                 return NULL;
00226         }
00227 
00228         namerec = wins_record_to_name_record(key, data);
00229 
00230         /* done with the this */
00231 
00232         SAFE_FREE( data.dptr );
00233 
00234         if (!namerec) {
00235                 return NULL;
00236         }
00237 
00238         /* Self names only - these include permanent names. */
00239         if( self_only && (namerec->data.source != SELF_NAME) && (namerec->data.source != PERMANENT_NAME) ) {
00240                 DEBUG( 9, ( "find_name_on_wins_subnet: self name %s NOT FOUND\n", nmb_namestr(nmbname) ) );
00241                 SAFE_FREE(namerec->data.ip);
00242                 SAFE_FREE(namerec);
00243                 return NULL;
00244         }
00245 
00246         /* Search for this name record on the list. Replace it if found. */
00247 
00248         for( nr = wins_server_subnet->namelist; nr; nr = nr->next) {
00249                 if (memcmp(nmbname->name, nr->name.name, 16) == 0) {
00250                         /* Delete it. */
00251                         DLIST_REMOVE(wins_server_subnet->namelist, nr);
00252                         SAFE_FREE(nr->data.ip);
00253                         SAFE_FREE(nr);
00254                         break;
00255                 }
00256         }
00257         
00258         DLIST_ADD(wins_server_subnet->namelist, namerec);
00259         return namerec;
00260 }

static BOOL store_or_replace_wins_namerec ( const struct name_record namerec,
int  tdb_flag 
) [static]

nmbd_winsserver.c266 行で定義されています。

参照先 name_record::dataname_record::namename_record_to_wins_record()name_to_key()tdb_store()wins_tdb.

参照元 add_name_to_wins_subnet()wins_store_changed_namerec().

00267 {
00268         TDB_DATA key, data;
00269         int ret;
00270 
00271         if (!wins_tdb) {
00272                 return False;
00273         }
00274 
00275         key = name_to_key(&namerec->name);
00276         data = name_record_to_wins_record(namerec);
00277 
00278         if (data.dptr == NULL) {
00279                 return False;
00280         }
00281 
00282         ret = tdb_store(wins_tdb, key, data, tdb_flag);
00283 
00284         SAFE_FREE(data.dptr);
00285         return (ret == 0) ? True : False;
00286 }

BOOL wins_store_changed_namerec ( const struct name_record namerec  ) 

nmbd_winsserver.c292 行で定義されています。

参照先 store_or_replace_wins_namerec().

参照元 add_ip_to_name_record()remove_nth_ip_in_record()update_name_ttl()wins_hook()wins_processing_traverse_fn().

00293 {
00294         return store_or_replace_wins_namerec(namerec, TDB_REPLACE);
00295 }

BOOL add_name_to_wins_subnet ( const struct name_record namerec  ) 

nmbd_winsserver.c301 行で定義されています。

参照先 store_or_replace_wins_namerec().

参照元 add_name_to_subnet().

00302 {
00303         return store_or_replace_wins_namerec(namerec, TDB_INSERT);
00304 }

BOOL remove_name_from_wins_namelist ( struct name_record namerec  ) 

nmbd_winsserver.c311 行で定義されています。

参照先 name_record::namename_to_key()subnet_record::namelisttdb_delete()wins_server_subnetwins_tdb.

参照元 remove_name_from_namelist()wins_processing_traverse_fn().

00312 {
00313         TDB_DATA key;
00314         int ret;
00315 
00316         if (!wins_tdb) {
00317                 return False;
00318         }
00319 
00320         key = name_to_key(&namerec->name);
00321         ret = tdb_delete(wins_tdb, key);
00322 
00323         DLIST_REMOVE(wins_server_subnet->namelist, namerec);
00324 
00325         /* namerec must be freed by the caller */
00326 
00327         return (ret == 0) ? True : False;
00328 }

static int traverse_fn ( TDB_CONTEXT tdb,
TDB_DATA  kbuf,
TDB_DATA  dbuf,
void *  state 
) [static]

nmbd_winsserver.c334 行で定義されています。

参照先 name_record::dataTDB_DATA::dsizedump_name_record()fpnmb_data::ipwins_record_to_name_record().

00335 {
00336         struct name_record *namerec = NULL;
00337         XFILE *fp = (XFILE *)state;
00338 
00339         if (kbuf.dsize != sizeof(unstring) + 1) {
00340                 return 0;
00341         }
00342 
00343         namerec = wins_record_to_name_record(kbuf, dbuf);
00344         if (!namerec) {
00345                 return 0;
00346         }
00347 
00348         dump_name_record(namerec, fp);
00349 
00350         SAFE_FREE(namerec->data.ip);
00351         SAFE_FREE(namerec);
00352         return 0;
00353 }

void dump_wins_subnet_namelist ( XFILE fp  ) 

nmbd_winsserver.c355 行で定義されています。

参照先 fptdb_traverse()traverse_fn()wins_tdb.

参照元 dump_all_namelists().

00356 {
00357         tdb_traverse(wins_tdb, traverse_fn, (void *)fp);
00358 }

static void update_wins_owner ( struct name_record namerec,
struct in_addr  wins_ip 
) [static]

nmbd_winsserver.c364 行で定義されています。

参照先 name_record::datanmb_data::wins_ip.

参照元 nmbd_wins_new_entry()wins_multihomed_register_query_success()wins_process_multihomed_name_registration_request()wins_process_name_refresh_request()wins_process_name_registration_request().

00365 {
00366         namerec->data.wins_ip=wins_ip;
00367 }

static void update_wins_flag ( struct name_record namerec,
int  flags 
) [static]

nmbd_winsserver.c373 行で定義されています。

参照先 name_record::datanmb_data::death_timename_record::namenmb_name::name_typenmb_data::nb_flagsnmb_data::num_ipsnmb_data::wins_flags.

参照元 nmbd_wins_new_entry()wins_multihomed_register_query_success()wins_process_multihomed_name_registration_request()wins_process_name_registration_request().

00374 {
00375         namerec->data.wins_flags=0x0;
00376 
00377         /* if it's a group, it can be a normal or a special one */
00378         if (namerec->data.nb_flags & NB_GROUP) {
00379                 if (namerec->name.name_type==0x1C) {
00380                         namerec->data.wins_flags|=WINS_SGROUP;
00381                 } else {
00382                         if (namerec->data.num_ips>1) {
00383                                 namerec->data.wins_flags|=WINS_SGROUP;
00384                         } else {
00385                                 namerec->data.wins_flags|=WINS_NGROUP;
00386                         }
00387                 }
00388         } else {
00389                 /* can be unique or multi-homed */
00390                 if (namerec->data.num_ips>1) {
00391                         namerec->data.wins_flags|=WINS_MHOMED;
00392                 } else {
00393                         namerec->data.wins_flags|=WINS_UNIQUE;
00394                 }
00395         }
00396 
00397         /* the node type are the same bits */
00398         namerec->data.wins_flags|=namerec->data.nb_flags&NB_NODETYPEMASK;
00399 
00400         /* the static bit is elsewhere */
00401         if (namerec->data.death_time == PERMANENT_TTL) {
00402                 namerec->data.wins_flags|=WINS_STATIC;
00403         }
00404 
00405         /* and add the given bits */
00406         namerec->data.wins_flags|=flags;
00407 
00408         DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n", 
00409                  namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
00410 }

static void get_global_id_and_update ( SMB_BIG_UINT *  current_id,
BOOL  update 
) [static]

nmbd_winsserver.c416 行で定義されています。

参照元 nmbd_wins_new_entry()wins_multihomed_register_query_success()wins_process_multihomed_name_registration_request()wins_process_name_refresh_request()wins_process_name_registration_request()wins_processing_traverse_fn().

00417 {
00418         /*
00419          * it's kept as a static here, to prevent people from messing
00420          * with the value directly
00421          */
00422 
00423         static SMB_BIG_UINT general_id = 1;
00424 
00425         DEBUG(5,("get_global_id_and_update: updating version ID: %d\n", (int)general_id));
00426         
00427         *current_id = general_id;
00428         
00429         if (update) {
00430                 general_id++;
00431         }
00432 }

static void wins_hook ( const char *  operation,
struct name_record namerec,
int  ttl 
) [static]

nmbd_winsserver.c439 行で定義されています。

参照先 name_record::datanmb_data::ipnmb_name::namename_record::namenmb_name::name_typenmb_namestr()nmb_data::num_ipssmbrun()strchr_m()wins_store_changed_namerec().

参照元 wins_multihomed_register_query_success()wins_process_multihomed_name_registration_request()wins_process_name_refresh_request()wins_process_name_registration_request()wins_process_name_release_request().

00440 {
00441         pstring command;
00442         char *cmd = lp_wins_hook();
00443         char *p, *namestr;
00444         int i;
00445 
00446         wins_store_changed_namerec(namerec);
00447 
00448         if (!cmd || !*cmd) {
00449                 return;
00450         }
00451 
00452         for (p=namerec->name.name; *p; p++) {
00453                 if (!(isalnum((int)*p) || strchr_m("._-",*p))) {
00454                         DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
00455                         return;
00456                 }
00457         }
00458         
00459         /* Use the name without the nametype (and scope) appended */
00460 
00461         namestr = nmb_namestr(&namerec->name);
00462         if ((p = strchr(namestr, '<'))) {
00463                 *p = 0;
00464         }
00465 
00466         p = command;
00467         p += slprintf(p, sizeof(command)-1, "%s %s %s %02x %d", 
00468                       cmd,
00469                       operation, 
00470                       namestr,
00471                       namerec->name.name_type,
00472                       ttl);
00473 
00474         for (i=0;i<namerec->data.num_ips;i++) {
00475                 p += slprintf(p, sizeof(command) - (p-command) -1, " %s", inet_ntoa(namerec->data.ip[i]));
00476         }
00477 
00478         DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
00479         smbrun(command, NULL);
00480 }

BOOL packet_is_for_wins_server ( struct packet_struct packet  ) 

nmbd_winsserver.c486 行で定義されています。

参照先 nmb_packet::headernmb_packet::nm_flagsnmb_packet::opcodepacketnmb_packet::questionnmb_packet::question_typenmb_packet::responsewins_server_subnet.

参照元 find_subnet_for_nmb_packet().

00487 {
00488         struct nmb_packet *nmb = &packet->packet.nmb;
00489 
00490         /* Only unicast packets go to a WINS server. */
00491         if((wins_server_subnet == NULL) || (nmb->header.nm_flags.bcast == True)) {
00492                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #1.\n"));
00493                 return False;
00494         }
00495 
00496         /* Check for node status requests. */
00497         if (nmb->question.question_type != QUESTION_TYPE_NB_QUERY) {
00498                 return False;
00499         }
00500 
00501         switch(nmb->header.opcode) { 
00502                 /*
00503                  * A WINS server issues WACKS, not receives them.
00504                  */
00505                 case NMB_WACK_OPCODE:
00506                         DEBUG(10, ("packet_is_for_wins_server: failing WINS test #2 (WACK).\n"));
00507                         return False;
00508                 /*
00509                  * A WINS server only processes registration and
00510                  * release requests, not responses.
00511                  */
00512                 case NMB_NAME_REG_OPCODE:
00513                 case NMB_NAME_MULTIHOMED_REG_OPCODE:
00514                 case NMB_NAME_REFRESH_OPCODE_8: /* ambiguity in rfc1002 about which is correct. */
00515                 case NMB_NAME_REFRESH_OPCODE_9: /* WinNT uses 8 by default. */
00516                         if(nmb->header.response) {
00517                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #3 (response = 1).\n"));
00518                                 return False;
00519                         }
00520                         break;
00521 
00522                 case NMB_NAME_RELEASE_OPCODE:
00523                         if(nmb->header.response) {
00524                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #4 (response = 1).\n"));
00525                                 return False;
00526                         }
00527                         break;
00528 
00529                 /*
00530                  * Only process unicast name queries with rd = 1.
00531                  */
00532                 case NMB_NAME_QUERY_OPCODE:
00533                         if(!nmb->header.response && !nmb->header.nm_flags.recursion_desired) {
00534                                 DEBUG(10, ("packet_is_for_wins_server: failing WINS test #5 (response = 1).\n"));
00535                                 return False;
00536                         }
00537                         break;
00538         }
00539 
00540         return True;
00541 }

static int get_ttl_from_packet ( struct nmb_packet nmb  )  [static]

nmbd_winsserver.c547 行で定義されています。

参照先 nmb_packet::additionalres_rec::ttl.

参照元 wins_multihomed_register_query_success()wins_process_multihomed_name_registration_request()wins_process_name_refresh_request()wins_process_name_registration_request().

00548 {
00549         int ttl = nmb->additional->ttl;
00550 
00551         if (ttl < lp_min_wins_ttl()) {
00552                 ttl = lp_min_wins_ttl();
00553         }
00554 
00555         if (ttl > lp_max_wins_ttl()) {
00556                 ttl = lp_max_wins_ttl();
00557         }
00558 
00559         return ttl;
00560 }

BOOL initialise_wins ( void   ) 

nmbd_winsserver.c566 行で定義されています。

参照先 add_name_to_subnet()add_samba_names_to_subnet()errnofgets_slash()fpinterpret_addr2()linelock_path()namenext_token()REGISTER_NAMEstrerror()tdb_open_log()tdb_store_int32()typewins_server_subnetwins_tdbx_fclose()x_feof()x_fopen().

参照元 main().

00567 {
00568         time_t time_now = time(NULL);
00569         XFILE *fp;
00570         pstring line;
00571 
00572         if(!lp_we_are_a_wins_server()) {
00573                 return True;
00574         }
00575 
00576         /* Open the wins.tdb. */
00577         wins_tdb = tdb_open_log(lock_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_CREAT|O_RDWR, 0600);
00578         if (!wins_tdb) {
00579                 DEBUG(0,("initialise_wins: failed to open wins.tdb. Error was %s\n",
00580                         strerror(errno) ));
00581                 return False;
00582         }
00583 
00584         tdb_store_int32(wins_tdb, "WINSDB_VERSION", WINSDB_VERSION);
00585 
00586         add_samba_names_to_subnet(wins_server_subnet);
00587 
00588         if((fp = x_fopen(lock_path(WINS_LIST),O_RDONLY,0)) == NULL) {
00589                 DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
00590                         WINS_LIST, strerror(errno) ));
00591                 return True;
00592         }
00593 
00594         while (!x_feof(fp)) {
00595                 pstring name_str, ip_str, ttl_str, nb_flags_str;
00596                 unsigned int num_ips;
00597                 pstring name;
00598                 struct in_addr *ip_list;
00599                 int type = 0;
00600                 int nb_flags;
00601                 int ttl;
00602                 const char *ptr;
00603                 char *p;
00604                 BOOL got_token;
00605                 BOOL was_ip;
00606                 int i;
00607                 unsigned int hash;
00608                 int version;
00609 
00610                 /* Read a line from the wins.dat file. Strips whitespace
00611                         from the beginning and end of the line.  */
00612                 if (!fgets_slash(line,sizeof(pstring),fp))
00613                         continue;
00614       
00615                 if (*line == '#')
00616                         continue;
00617 
00618                 if (strncmp(line,"VERSION ", 8) == 0) {
00619                         if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
00620                                                 version != WINS_VERSION) {
00621                                 DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
00622                                 x_fclose(fp);
00623                                 return True;
00624                         }
00625                         continue;
00626                 }
00627 
00628                 ptr = line;
00629 
00630                 /* 
00631                  * Now we handle multiple IP addresses per name we need
00632                  * to iterate over the line twice. The first time to
00633                  * determine how many IP addresses there are, the second
00634                  * time to actually parse them into the ip_list array.
00635                  */
00636 
00637                 if (!next_token(&ptr,name_str,NULL,sizeof(name_str))) {
00638                         DEBUG(0,("initialise_wins: Failed to parse name when parsing line %s\n", line ));
00639                         continue;
00640                 }
00641 
00642                 if (!next_token(&ptr,ttl_str,NULL,sizeof(ttl_str))) {
00643                         DEBUG(0,("initialise_wins: Failed to parse time to live when parsing line %s\n", line ));
00644                         continue;
00645                 }
00646 
00647                 /*
00648                  * Determine the number of IP addresses per line.
00649                  */
00650                 num_ips = 0;
00651                 do {
00652                         got_token = next_token(&ptr,ip_str,NULL,sizeof(ip_str));
00653                         was_ip = False;
00654 
00655                         if(got_token && strchr(ip_str, '.')) {
00656                                 num_ips++;
00657                                 was_ip = True;
00658                         }
00659                 } while( got_token && was_ip);
00660 
00661                 if(num_ips == 0) {
00662                         DEBUG(0,("initialise_wins: Missing IP address when parsing line %s\n", line ));
00663                         continue;
00664                 }
00665 
00666                 if(!got_token) {
00667                         DEBUG(0,("initialise_wins: Missing nb_flags when parsing line %s\n", line ));
00668                         continue;
00669                 }
00670 
00671                 /* Allocate the space for the ip_list. */
00672                 if((ip_list = SMB_MALLOC_ARRAY( struct in_addr, num_ips)) == NULL) {
00673                         DEBUG(0,("initialise_wins: Malloc fail !\n"));
00674                         x_fclose(fp);
00675                         return False;
00676                 }
00677  
00678                 /* Reset and re-parse the line. */
00679                 ptr = line;
00680                 next_token(&ptr,name_str,NULL,sizeof(name_str)); 
00681                 next_token(&ptr,ttl_str,NULL,sizeof(ttl_str));
00682                 for(i = 0; i < num_ips; i++) {
00683                         next_token(&ptr, ip_str, NULL, sizeof(ip_str));
00684                         ip_list[i] = *interpret_addr2(ip_str);
00685                 }
00686                 next_token(&ptr,nb_flags_str,NULL, sizeof(nb_flags_str));
00687 
00688                 /* 
00689                  * Deal with SELF or REGISTER name encoding. Default is REGISTER
00690                  * for compatibility with old nmbds.
00691                  */
00692 
00693                 if(nb_flags_str[strlen(nb_flags_str)-1] == 'S') {
00694                         DEBUG(5,("initialise_wins: Ignoring SELF name %s\n", line));
00695                         SAFE_FREE(ip_list);
00696                         continue;
00697                 }
00698       
00699                 if(nb_flags_str[strlen(nb_flags_str)-1] == 'R') {
00700                         nb_flags_str[strlen(nb_flags_str)-1] = '\0';
00701                 }
00702       
00703                 /* Netbios name. # divides the name from the type (hex): netbios#xx */
00704                 pstrcpy(name,name_str);
00705       
00706                 if((p = strchr(name,'#')) != NULL) {
00707                         *p = 0;
00708                         sscanf(p+1,"%x",&type);
00709                 }
00710       
00711                 /* Decode the netbios flags (hex) and the time-to-live (in seconds). */
00712                 sscanf(nb_flags_str,"%x",&nb_flags);
00713                 sscanf(ttl_str,"%d",&ttl);
00714 
00715                 /* add all entries that have 60 seconds or more to live */
00716                 if ((ttl - 60) > time_now || ttl == PERMANENT_TTL) {
00717                         if(ttl != PERMANENT_TTL) {
00718                                 ttl -= time_now;
00719                         }
00720     
00721                         DEBUG( 4, ("initialise_wins: add name: %s#%02x ttl = %d first IP %s flags = %2x\n",
00722                                 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
00723 
00724                         (void)add_name_to_subnet( wins_server_subnet, name, type, nb_flags, 
00725                                         ttl, REGISTER_NAME, num_ips, ip_list );
00726                 } else {
00727                         DEBUG(4, ("initialise_wins: not adding name (ttl problem) "
00728                                 "%s#%02x ttl = %d first IP %s flags = %2x\n",
00729                                 name, type, ttl, inet_ntoa(ip_list[0]), nb_flags));
00730                 }
00731 
00732                 SAFE_FREE(ip_list);
00733         } 
00734     
00735         x_fclose(fp);
00736         return True;
00737 }

static void send_wins_wack_response ( int  ttl,
struct packet_struct p 
) [static]

nmbd_winsserver.c743 行で定義されています。

参照先 nmb_packet::headernmb_packet::nm_flagspacket_struct::nmbNMB_WAIT_ACKnmb_packet::opcodepacket_struct::packetreply_netbios_packet()nmb_packet::response.

参照元 wins_process_multihomed_name_registration_request()wins_process_name_registration_request().

00744 {
00745         struct nmb_packet *nmb = &p->packet.nmb;
00746         unsigned char rdata[2];
00747 
00748         rdata[0] = rdata[1] = 0;
00749 
00750         /* Taken from nmblib.c - we need to send back almost
00751                 identical bytes from the requesting packet header. */
00752 
00753         rdata[0] = (nmb->header.opcode & 0xF) << 3;
00754         if (nmb->header.nm_flags.authoritative && nmb->header.response) {
00755                 rdata[0] |= 0x4;
00756         }
00757         if (nmb->header.nm_flags.trunc) {
00758                 rdata[0] |= 0x2;
00759         }
00760         if (nmb->header.nm_flags.recursion_desired) {
00761                 rdata[0] |= 0x1;
00762         }
00763         if (nmb->header.nm_flags.recursion_available && nmb->header.response) {
00764                 rdata[1] |= 0x80;
00765         }
00766         if (nmb->header.nm_flags.bcast) {
00767                 rdata[1] |= 0x10;
00768         }
00769 
00770         reply_netbios_packet(p,                                /* Packet to reply to. */
00771                                 0,                             /* Result code. */
00772                                 NMB_WAIT_ACK,                  /* nmbd type code. */
00773                                 NMB_WACK_OPCODE,               /* opcode. */
00774                                 ttl,                           /* ttl. */
00775                                 (char *)rdata,                 /* data to send. */
00776                                 2);                            /* data length. */
00777 }

static void send_wins_name_registration_response ( int  rcode,
int  ttl,
struct packet_struct p 
) [static]

nmbd_winsserver.c783 行で定義されています。

参照先 nmb_packet::additionalpacket_struct::nmbpacket_struct::packetres_rec::rdatareply_netbios_packet()WINS_REG.

参照元 wins_multihomed_register_query_fail()wins_multihomed_register_query_success()wins_process_multihomed_name_registration_request()wins_process_name_refresh_request()wins_process_name_registration_request()wins_register_query_success().

00784 {
00785         struct nmb_packet *nmb = &p->packet.nmb;
00786         char rdata[6];
00787 
00788         memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
00789 
00790         reply_netbios_packet(p,                                /* Packet to reply to. */
00791                                 rcode,                         /* Result code. */
00792                                 WINS_REG,                      /* nmbd type code. */
00793                                 NMB_NAME_REG_OPCODE,           /* opcode. */
00794                                 ttl,                           /* ttl. */
00795                                 rdata,                         /* data to send. */
00796                                 6);                            /* data length. */
00797 }

void wins_process_name_refresh_request ( struct subnet_record subrec,
struct packet_struct p 
)

nmbd_winsserver.c803 行で定義されています。

参照先 nmb_packet::additionaldbgtext()find_ip_in_name_record()find_name_on_subnet()get_global_id_and_update()get_nb_flags()get_ttl_from_packet()nmb_packet::headerinterpret_addr2()nmb_name::name_typenmb_packet::nm_flagspacket_struct::nmbnmb_namestr()packet_struct::packetnmb_packet::questionnmb_packet::question_nameres_rec::rdataremove_name_from_namelist()send_wins_name_registration_response()subnet_record::subnet_nameupdate_name_ttl()update_wins_owner()wins_hook()wins_process_name_registration_request().

参照元 process_nmb_request().

00805 {
00806         struct nmb_packet *nmb = &p->packet.nmb;
00807         struct nmb_name *question = &nmb->question.question_name;
00808         BOOL bcast = nmb->header.nm_flags.bcast;
00809         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
00810         BOOL group = (nb_flags & NB_GROUP) ? True : False;
00811         struct name_record *namerec = NULL;
00812         int ttl = get_ttl_from_packet(nmb);
00813         struct in_addr from_ip;
00814         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
00815 
00816         putip( (char *)&from_ip, &nmb->additional->rdata[2] );
00817 
00818         if(bcast) {
00819                 /*
00820                  * We should only get unicast name refresh packets here.
00821                  * Anyone trying to refresh broadcast should not be going
00822                  * to a WINS server.  Log an error here.
00823                  */
00824                 if( DEBUGLVL( 0 ) ) {
00825                         dbgtext( "wins_process_name_refresh_request: " );
00826                         dbgtext( "Broadcast name refresh request received " );
00827                         dbgtext( "for name %s ", nmb_namestr(question) );
00828                         dbgtext( "from IP %s ", inet_ntoa(from_ip) );
00829                         dbgtext( "on subnet %s.  ", subrec->subnet_name );
00830                         dbgtext( "Error - Broadcasts should not be sent " );
00831                         dbgtext( "to a WINS server\n" );
00832                 }
00833                 return;
00834         }
00835 
00836         if( DEBUGLVL( 3 ) ) {
00837                 dbgtext( "wins_process_name_refresh_request: " );
00838                 dbgtext( "Name refresh for name %s IP %s\n",
00839                          nmb_namestr(question), inet_ntoa(from_ip) );
00840         }
00841 
00842         /* 
00843          * See if the name already exists.
00844          * If not, handle it as a name registration and return.
00845          */
00846         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
00847 
00848         /*
00849          * If this is a refresh request and the name doesn't exist then
00850          * treat it like a registration request. This allows us to recover 
00851          * from errors (tridge)
00852          */
00853         if(namerec == NULL) {
00854                 if( DEBUGLVL( 3 ) ) {
00855                         dbgtext( "wins_process_name_refresh_request: " );
00856                         dbgtext( "Name refresh for name %s ",
00857                                  nmb_namestr( question ) );
00858                         dbgtext( "and the name does not exist.  Treating " );
00859                         dbgtext( "as registration.\n" );
00860                 }
00861                 wins_process_name_registration_request(subrec,p);
00862                 return;
00863         }
00864 
00865         /*
00866          * if the name is present but not active, simply remove it
00867          * and treat the refresh request as a registration & return.
00868          */
00869         if (namerec != NULL && !WINS_STATE_ACTIVE(namerec)) {
00870                 if( DEBUGLVL( 5 ) ) {
00871                         dbgtext( "wins_process_name_refresh_request: " );
00872                         dbgtext( "Name (%s) in WINS ", nmb_namestr(question) );
00873                         dbgtext( "was not active - removing it.\n" );
00874                 }
00875                 remove_name_from_namelist( subrec, namerec );
00876                 namerec = NULL;
00877                 wins_process_name_registration_request( subrec, p );
00878                 return;
00879         }
00880 
00881         /*
00882          * Check that the group bits for the refreshing name and the
00883          * name in our database match.  If not, refuse the refresh.
00884          * [crh:  Why RFS_ERR instead of ACT_ERR? Is this what MS does?]
00885          */
00886         if( (namerec != NULL) &&
00887             ( (group && !NAME_GROUP(namerec))
00888            || (!group && NAME_GROUP(namerec)) ) ) {
00889                 if( DEBUGLVL( 3 ) ) {
00890                         dbgtext( "wins_process_name_refresh_request: " );
00891                         dbgtext( "Name %s ", nmb_namestr(question) );
00892                         dbgtext( "group bit = %s does not match ",
00893                                  group ? "True" : "False" );
00894                         dbgtext( "group bit in WINS for this name.\n" );
00895                 }
00896                 send_wins_name_registration_response(RFS_ERR, 0, p);
00897                 return;
00898         }
00899 
00900         /*
00901          * For a unique name check that the person refreshing the name is
00902          * one of the registered IP addresses. If not - fail the refresh.
00903          * Do the same for group names with a type of 0x1c.
00904          * Just return success for unique 0x1d refreshes. For normal group
00905          * names update the ttl and return success.
00906          */
00907         if( (!group || (group && (question->name_type == 0x1c)))
00908                         && find_ip_in_name_record(namerec, from_ip) ) {
00909                 /*
00910                  * Update the ttl.
00911                  */
00912                 update_name_ttl(namerec, ttl);
00913 
00914                 /*
00915                  * if the record is a replica:
00916                  * we take ownership and update the version ID.
00917                  */
00918                 if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
00919                         update_wins_owner(namerec, our_fake_ip);
00920                         get_global_id_and_update(&namerec->data.id, True);
00921                 }
00922 
00923                 send_wins_name_registration_response(0, ttl, p);
00924                 wins_hook("refresh", namerec, ttl);
00925                 return;
00926         } else if((group && (question->name_type == 0x1c))) {
00927                 /*
00928                  * Added by crh for bug #1079.
00929                  * Fix from Bert Driehuis
00930                  */
00931                 if( DEBUGLVL( 3 ) ) {
00932                         dbgtext( "wins_process_name_refresh_request: " );
00933                         dbgtext( "Name refresh for name %s, ",
00934                                  nmb_namestr(question) );
00935                         dbgtext( "but IP address %s ", inet_ntoa(from_ip) );
00936                         dbgtext( "is not yet associated with " );
00937                         dbgtext( "that name. Treating as registration.\n" );
00938                 }
00939                 wins_process_name_registration_request(subrec,p);
00940                 return;
00941         } else if(group) {
00942                 /* 
00943                  * Normal groups are all registered with an IP address of
00944                  * 255.255.255.255  so we can't search for the IP address.
00945                  */
00946                 update_name_ttl(namerec, ttl);
00947                 wins_hook("refresh", namerec, ttl);
00948                 send_wins_name_registration_response(0, ttl, p);
00949                 return;
00950         } else if(!group && (question->name_type == 0x1d)) {
00951                 /*
00952                  * Special name type - just pretend the refresh succeeded.
00953                  */
00954                 send_wins_name_registration_response(0, ttl, p);
00955                 return;
00956         } else {
00957                 /*
00958                  * Fail the refresh.
00959                  */
00960                 if( DEBUGLVL( 3 ) ) {
00961                         dbgtext( "wins_process_name_refresh_request: " );
00962                         dbgtext( "Name refresh for name %s with IP %s ",
00963                                  nmb_namestr(question), inet_ntoa(from_ip) );
00964                         dbgtext( "and is IP is not known to the name.\n" );
00965                 }
00966                 send_wins_name_registration_response(RFS_ERR, 0, p);
00967                 return;
00968         }
00969 }

static void wins_register_query_success ( struct subnet_record subrec,
struct userdata_struct userdata,
struct nmb_name question_name,
struct in_addr  ip,
struct res_rec answers 
) [static]

nmbd_winsserver.c981 行で定義されています。

参照先 userdata_struct::datafree_packet()nmb_namestr()send_wins_name_registration_response().

参照元 wins_process_name_registration_request().

00986 {
00987         struct packet_struct *orig_reg_packet;
00988 
00989         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
00990 
00991         DEBUG(3,("wins_register_query_success: Original client at IP %s still wants the \
00992 name %s. Rejecting registration request.\n", inet_ntoa(ip), nmb_namestr(question_name) ));
00993 
00994         send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
00995 
00996         orig_reg_packet->locked = False;
00997         free_packet(orig_reg_packet);
00998 }

static void wins_register_query_fail ( struct subnet_record subrec,
struct response_record rrec,
struct nmb_name question_name,
int  rcode 
) [static]

nmbd_winsserver.c1010 行で定義されています。

参照先 name_record::datauserdata_struct::datafind_name_on_subnet()free_packet()nmb_data::ippacket_struct::ipnmb_namestr()response_record::packetREGISTER_NAMEremove_name_from_namelist()nmb_data::sourceresponse_record::userdatawins_process_name_registration_request().

参照元 wins_process_name_registration_request().

01014 {
01015         struct userdata_struct *userdata = rrec->userdata;
01016         struct packet_struct *orig_reg_packet;
01017         struct name_record *namerec = NULL;
01018 
01019         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
01020 
01021         /*
01022          * We want to just add the name, as we now know the original owner
01023          * didn't want it. But we can't just do that as an arbitary
01024          * amount of time may have taken place between the name query
01025          * request and this timeout/error response. So we check that
01026          * the name still exists and is in the same state - if so
01027          * we remove it and call wins_process_name_registration_request()
01028          * as we know it will do the right thing now.
01029          */
01030 
01031         namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
01032 
01033         if ((namerec != NULL) && (namerec->data.source == REGISTER_NAME) &&
01034                         ip_equal(rrec->packet->ip, *namerec->data.ip)) {
01035                 remove_name_from_namelist( subrec, namerec);
01036                 namerec = NULL;
01037         }
01038 
01039         if(namerec == NULL) {
01040                 wins_process_name_registration_request(subrec, orig_reg_packet);
01041         } else {
01042                 DEBUG(2,("wins_register_query_fail: The state of the WINS database changed between "
01043                         "querying for name %s in order to replace it and this reply.\n",
01044                         nmb_namestr(question_name) ));
01045         }
01046 
01047         orig_reg_packet->locked = False;
01048         free_packet(orig_reg_packet);
01049 }

void wins_process_name_registration_request ( struct subnet_record subrec,
struct packet_struct p 
)

nmbd_winsserver.c1108 行で定義されています。

参照先 add_ip_to_name_record()add_name_to_subnet()nmb_packet::additionaluserdata_struct::copy_fnuserdata_struct::dataname_record::dataDNS_NAMEDNSFAIL_NAMEfind_ip_in_name_record()find_name_on_subnet()userdata_struct::free_fnget_global_id_and_update()get_nb_flags()get_ttl_from_packet()nmb_packet::headernmb_data::idinterpret_addr2()nmb_data::ippacket_struct::ipis_myname()ismyip()packet_struct::lockednmb_name::namename_record::namenamenmb_name::name_typenmb_packet::nm_flagspacket_struct::nmbnmb_namestr()nmb_data::num_ipspacket_struct::packetpull_ascii_nstring()query_name_from_wins_server()nmb_packet::questionnmb_packet::question_nameres_rec::rdataREGISTER_NAMEremove_name_from_namelist()send_wins_name_registration_response()send_wins_wack_response()nmb_data::sourcesubnet_record::subnet_nameupdate_name_ttl()update_wins_flag()update_wins_owner()userdata_struct::userdata_lenwins_hook()nmb_data::wins_ipwins_register_query_fail()wins_register_query_success().

参照元 process_nmb_request()wins_process_name_refresh_request()wins_register_query_fail().

01110 {
01111         unstring name;
01112         struct nmb_packet *nmb = &p->packet.nmb;
01113         struct nmb_name *question = &nmb->question.question_name;
01114         BOOL bcast = nmb->header.nm_flags.bcast;
01115         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
01116         int ttl = get_ttl_from_packet(nmb);
01117         struct name_record *namerec = NULL;
01118         struct in_addr from_ip;
01119         BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
01120         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
01121 
01122         putip((char *)&from_ip,&nmb->additional->rdata[2]);
01123 
01124         if(bcast) {
01125                 /*
01126                  * We should only get unicast name registration packets here.
01127                  * Anyone trying to register broadcast should not be going to a WINS
01128                  * server. Log an error here.
01129                  */
01130 
01131                 DEBUG(0,("wins_process_name_registration_request: broadcast name registration request \
01132 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
01133                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
01134                 return;
01135         }
01136 
01137         DEBUG(3,("wins_process_name_registration_request: %s name registration for name %s \
01138 IP %s\n", registering_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
01139 
01140         /*
01141          * See if the name already exists.
01142          */
01143 
01144         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
01145 
01146         /*
01147          * if the record exists but NOT in active state,
01148          * consider it dead.
01149          */
01150         if ( (namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
01151                 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
01152 not active - removing it.\n", nmb_namestr(question) ));
01153                 remove_name_from_namelist( subrec, namerec );
01154                 namerec = NULL;
01155         }
01156 
01157         /*
01158          * Deal with the case where the name found was a dns entry.
01159          * Remove it as we now have a NetBIOS client registering the
01160          * name.
01161          */
01162 
01163         if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
01164                 DEBUG(5,("wins_process_name_registration_request: Name (%s) in WINS was \
01165 a dns lookup - removing it.\n", nmb_namestr(question) ));
01166                 remove_name_from_namelist( subrec, namerec );
01167                 namerec = NULL;
01168         }
01169 
01170         /*
01171          * Reject if the name exists and is not a REGISTER_NAME.
01172          * (ie. Don't allow any static names to be overwritten.
01173          */
01174 
01175         if((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) {
01176                 DEBUG( 3, ( "wins_process_name_registration_request: Attempt \
01177 to register name %s. Name already exists in WINS with source type %d.\n",
01178                         nmb_namestr(question), namerec->data.source ));
01179                 send_wins_name_registration_response(RFS_ERR, 0, p);
01180                 return;
01181         }
01182 
01183         /*
01184          * Special policy decisions based on MS documentation.
01185          * 1). All group names (except names ending in 0x1c) are added as 255.255.255.255.
01186          * 2). All unique names ending in 0x1d are ignored, although a positive response is sent.
01187          */
01188 
01189         /*
01190          * A group name is always added as the local broadcast address, except
01191          * for group names ending in 0x1c.
01192          * Group names with type 0x1c are registered with individual IP addresses.
01193          */
01194 
01195         if(registering_group_name && (question->name_type != 0x1c)) {
01196                 from_ip = *interpret_addr2("255.255.255.255");
01197         }
01198 
01199         /*
01200          * Ignore all attempts to register a unique 0x1d name, although return success.
01201          */
01202 
01203         if(!registering_group_name && (question->name_type == 0x1d)) {
01204                 DEBUG(3,("wins_process_name_registration_request: Ignoring request \
01205 to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
01206                 send_wins_name_registration_response(0, ttl, p);
01207                 return;
01208         }
01209 
01210         /*
01211          * Next two cases are the 'if statement' mentioned above.
01212          */
01213 
01214         if((namerec != NULL) && NAME_GROUP(namerec)) {
01215                 if(registering_group_name) {
01216                         /*
01217                          * If we are adding a group name, the name exists and is also a group entry just add this
01218                          * IP address to it and update the ttl.
01219                          */
01220 
01221                         DEBUG(3,("wins_process_name_registration_request: Adding IP %s to group name %s.\n",
01222                                 inet_ntoa(from_ip), nmb_namestr(question) ));
01223 
01224                         /* 
01225                          * Check the ip address is not already in the group.
01226                          */
01227 
01228                         if(!find_ip_in_name_record(namerec, from_ip)) {
01229                                 add_ip_to_name_record(namerec, from_ip);
01230                                 /* we need to update the record for replication */
01231                                 get_global_id_and_update(&namerec->data.id, True);
01232 
01233                                 /*
01234                                  * if the record is a replica, we must change
01235                                  * the wins owner to us to make the replication updates
01236                                  * it on the other wins servers.
01237                                  * And when the partner will receive this record,
01238                                  * it will update its own record.
01239                                  */
01240 
01241                                 update_wins_owner(namerec, our_fake_ip);
01242                         }
01243                         update_name_ttl(namerec, ttl);
01244                         wins_hook("refresh", namerec, ttl);
01245                         send_wins_name_registration_response(0, ttl, p);
01246                         return;
01247                 } else {
01248 
01249                         /*
01250                          * If we are adding a unique name, the name exists in the WINS db 
01251                          * and is a group name then reject the registration.
01252                          *
01253                          * explanation: groups have a higher priority than unique names.
01254                          */
01255 
01256                         DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
01257 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
01258                         send_wins_name_registration_response(RFS_ERR, 0, p);
01259                         return;
01260                 } 
01261         }
01262 
01263         /*
01264          * From here on down we know that if the name exists in the WINS db it is
01265          * a unique name, not a group name.
01266          */
01267 
01268         /* 
01269          * If the name exists and is one of our names then check the
01270          * registering IP address. If it's not one of ours then automatically
01271          * reject without doing the query - we know we will reject it.
01272          */
01273 
01274         if ( namerec != NULL ) {
01275                 pull_ascii_nstring(name, sizeof(name), namerec->name.name);
01276                 if( is_myname(name) ) {
01277                         if(!ismyip(from_ip)) {
01278                                 DEBUG(3,("wins_process_name_registration_request: Attempt to register name %s. Name \
01279 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
01280                                 send_wins_name_registration_response(RFS_ERR, 0, p);
01281                                 return;
01282                         } else {
01283                                 /*
01284                                  * It's one of our names and one of our IP's - update the ttl.
01285                                  */
01286                                 update_name_ttl(namerec, ttl);
01287                                 wins_hook("refresh", namerec, ttl);
01288                                 send_wins_name_registration_response(0, ttl, p);
01289                                 return;
01290                         }
01291                 }
01292         } else {
01293                 name[0] = '\0';
01294         }
01295 
01296         /*
01297          * If the name exists and it is a unique registration and the registering IP 
01298          * is the same as the (single) already registered IP then just update the ttl.
01299          *
01300          * But not if the record is an active replica. IF it's a replica, it means it can be
01301          * the same client which has moved and not yet expired. So we don't update
01302          * the ttl in this case and go beyond to do a WACK and query the old client
01303          */
01304 
01305         if( !registering_group_name
01306                         && (namerec != NULL)
01307                         && (namerec->data.num_ips == 1)
01308                         && ip_equal( namerec->data.ip[0], from_ip )
01309                         && ip_equal(namerec->data.wins_ip, our_fake_ip) ) {
01310                 update_name_ttl( namerec, ttl );
01311                 wins_hook("refresh", namerec, ttl);
01312                 send_wins_name_registration_response( 0, ttl, p );
01313                 return;
01314         }
01315 
01316         /*
01317          * Finally if the name exists do a query to the registering machine 
01318          * to see if they still claim to have the name.
01319          */
01320 
01321         if( namerec != NULL ) {
01322                 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
01323                 struct userdata_struct *userdata = (struct userdata_struct *)ud;
01324 
01325                 /*
01326                  * First send a WACK to the registering machine.
01327                  */
01328 
01329                 send_wins_wack_response(60, p);
01330 
01331                 /*
01332                  * When the reply comes back we need the original packet.
01333                  * Lock this so it won't be freed and then put it into
01334                  * the userdata structure.
01335                  */
01336 
01337                 p->locked = True;
01338 
01339                 userdata = (struct userdata_struct *)ud;
01340 
01341                 userdata->copy_fn = NULL;
01342                 userdata->free_fn = NULL;
01343                 userdata->userdata_len = sizeof(struct packet_struct *);
01344                 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
01345 
01346                 /*
01347                  * Use the new call to send a query directly to an IP address.
01348                  * This sends the query directly to the IP address, and ensures
01349                  * the recursion desired flag is not set (you were right Luke :-).
01350                  * This function should *only* be called from the WINS server
01351                  * code. JRA.
01352                  */
01353 
01354                 pull_ascii_nstring(name, sizeof(name), question->name);
01355                 query_name_from_wins_server( *namerec->data.ip,
01356                                 name,
01357                                 question->name_type, 
01358                                 wins_register_query_success,
01359                                 wins_register_query_fail,
01360                                 userdata );
01361                 return;
01362         }
01363 
01364         /*
01365          * Name did not exist - add it.
01366          */
01367 
01368         pull_ascii_nstring(name, sizeof(name), question->name);
01369         add_name_to_subnet( subrec, name, question->name_type,
01370                         nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
01371 
01372         if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
01373                 get_global_id_and_update(&namerec->data.id, True);
01374                 update_wins_owner(namerec, our_fake_ip);
01375                 update_wins_flag(namerec, WINS_ACTIVE);
01376                 wins_hook("add", namerec, ttl);
01377         }
01378 
01379         send_wins_name_registration_response(0, ttl, p);
01380 }

static void wins_multihomed_register_query_success ( struct subnet_record subrec,
struct userdata_struct userdata,
struct nmb_name question_name,
struct in_addr  ip,
struct res_rec answers 
) [static]

nmbd_winsserver.c1390 行で定義されています。

参照先 add_ip_to_name_record()nmb_packet::additionalname_record::datauserdata_struct::datafind_ip_in_name_record()find_name_on_subnet()free_packet()get_global_id_and_update()get_ttl_from_packet()nmb_data::idinterpret_addr2()nmb_namestr()res_rec::rdataREGISTER_NAMEsend_wins_name_registration_response()nmb_data::sourceupdate_name_ttl()update_wins_flag()update_wins_owner()wins_hook().

参照元 wins_process_multihomed_name_registration_request().

01395 {
01396         struct packet_struct *orig_reg_packet;
01397         struct nmb_packet *nmb;
01398         struct name_record *namerec = NULL;
01399         struct in_addr from_ip;
01400         int ttl;
01401         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
01402 
01403         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
01404 
01405         nmb = &orig_reg_packet->packet.nmb;
01406 
01407         putip((char *)&from_ip,&nmb->additional->rdata[2]);
01408         ttl = get_ttl_from_packet(nmb);
01409 
01410         /*
01411          * We want to just add the new IP, as we now know the requesting
01412          * machine claims to own it. But we can't just do that as an arbitary
01413          * amount of time may have taken place between the name query
01414          * request and this response. So we check that
01415          * the name still exists and is in the same state - if so
01416          * we just add the extra IP and update the ttl.
01417          */
01418 
01419         namerec = find_name_on_subnet(subrec, question_name, FIND_ANY_NAME);
01420 
01421         if( (namerec == NULL) || (namerec->data.source != REGISTER_NAME) || !WINS_STATE_ACTIVE(namerec) ) {
01422                 DEBUG(3,("wins_multihomed_register_query_success: name %s is not in the correct state to add \
01423 a subsequent IP address.\n", nmb_namestr(question_name) ));
01424                 send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
01425 
01426                 orig_reg_packet->locked = False;
01427                 free_packet(orig_reg_packet);
01428 
01429                 return;
01430         }
01431 
01432         if(!find_ip_in_name_record(namerec, from_ip)) {
01433                 add_ip_to_name_record(namerec, from_ip);
01434         }
01435 
01436         get_global_id_and_update(&namerec->data.id, True);
01437         update_wins_owner(namerec, our_fake_ip);
01438         update_wins_flag(namerec, WINS_ACTIVE);
01439         update_name_ttl(namerec, ttl);
01440         wins_hook("add", namerec, ttl);
01441         send_wins_name_registration_response(0, ttl, orig_reg_packet);
01442 
01443         orig_reg_packet->locked = False;
01444         free_packet(orig_reg_packet);
01445 }

static void wins_multihomed_register_query_fail ( struct subnet_record subrec,
struct response_record rrec,
struct nmb_name question_name,
int  rcode 
) [static]

nmbd_winsserver.c1455 行で定義されています。

参照先 userdata_struct::datafree_packet()nmb_namestr()send_wins_name_registration_response()response_record::userdata.

参照元 wins_process_multihomed_name_registration_request().

01459 {
01460         struct userdata_struct *userdata = rrec->userdata;
01461         struct packet_struct *orig_reg_packet;
01462 
01463         memcpy((char *)&orig_reg_packet, userdata->data, sizeof(struct packet_struct *));
01464 
01465         DEBUG(3,("wins_multihomed_register_query_fail: Registering machine at IP %s failed to answer \
01466 query successfully for name %s.\n", inet_ntoa(orig_reg_packet->ip), nmb_namestr(question_name) ));
01467         send_wins_name_registration_response(RFS_ERR, 0, orig_reg_packet);
01468 
01469         orig_reg_packet->locked = False;
01470         free_packet(orig_reg_packet);
01471         return;
01472 }

void wins_process_multihomed_name_registration_request ( struct subnet_record subrec,
struct packet_struct p 
)

nmbd_winsserver.c1479 行で定義されています。

参照先 add_ip_to_name_record()add_name_to_subnet()nmb_packet::additionaluserdata_struct::copy_fnuserdata_struct::dataname_record::dataDNS_NAMEDNSFAIL_NAMEfind_ip_in_name_record()find_name_on_subnet()userdata_struct::free_fnget_global_id_and_update()get_nb_flags()get_ttl_from_packet()nmb_packet::headernmb_data::idinterpret_addr2()nmb_data::ippacket_struct::ipis_myname()ismyip()packet_struct::lockednmb_name::namename_record::namenmb_name::name_typenmb_packet::nm_flagspacket_struct::nmbnmb_namestr()packet_struct::packetpull_ascii_nstring()query_name_from_wins_server()nmb_packet::questionnmb_packet::question_nameres_rec::rdataREGISTER_NAMEremove_name_from_namelist()send_wins_name_registration_response()send_wins_wack_response()nmb_data::sourcesubnet_record::subnet_nameupdate_name_ttl()update_wins_flag()update_wins_owner()userdata_struct::userdata_lenwins_hook()wins_multihomed_register_query_fail()wins_multihomed_register_query_success().

参照元 process_nmb_request().

01481 {
01482         struct nmb_packet *nmb = &p->packet.nmb;
01483         struct nmb_name *question = &nmb->question.question_name;
01484         BOOL bcast = nmb->header.nm_flags.bcast;
01485         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
01486         int ttl = get_ttl_from_packet(nmb);
01487         struct name_record *namerec = NULL;
01488         struct in_addr from_ip;
01489         BOOL group = (nb_flags & NB_GROUP) ? True : False;
01490         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
01491         unstring qname;
01492 
01493         putip((char *)&from_ip,&nmb->additional->rdata[2]);
01494 
01495         if(bcast) {
01496                 /*
01497                  * We should only get unicast name registration packets here.
01498                  * Anyone trying to register broadcast should not be going to a WINS
01499                  * server. Log an error here.
01500                  */
01501 
01502                 DEBUG(0,("wins_process_multihomed_name_registration_request: broadcast name registration request \
01503 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
01504                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
01505                 return;
01506         }
01507 
01508         /*
01509          * Only unique names should be registered multihomed.
01510          */
01511 
01512         if(group) {
01513                 DEBUG(0,("wins_process_multihomed_name_registration_request: group name registration request \
01514 received for name %s from IP %s on subnet %s. Errror - group names should not be multihomed.\n",
01515                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
01516                 return;
01517         }
01518 
01519         DEBUG(3,("wins_process_multihomed_name_registration_request: name registration for name %s \
01520 IP %s\n", nmb_namestr(question), inet_ntoa(from_ip) ));
01521 
01522         /*
01523          * Deal with policy regarding 0x1d names.
01524          */
01525 
01526         if(question->name_type == 0x1d) {
01527                 DEBUG(3,("wins_process_multihomed_name_registration_request: Ignoring request \
01528 to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
01529                 send_wins_name_registration_response(0, ttl, p);  
01530                 return;
01531         }
01532 
01533         /*
01534          * See if the name already exists.
01535          */
01536 
01537         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
01538 
01539         /*
01540          * if the record exists but NOT in active state,
01541          * consider it dead.
01542          */
01543 
01544         if ((namerec != NULL) && !WINS_STATE_ACTIVE(namerec)) {
01545                 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was not active - removing it.\n", nmb_namestr(question)));
01546                 remove_name_from_namelist(subrec, namerec);
01547                 namerec = NULL;
01548         }
01549   
01550         /*
01551          * Deal with the case where the name found was a dns entry.
01552          * Remove it as we now have a NetBIOS client registering the
01553          * name.
01554          */
01555 
01556         if( (namerec != NULL) && ( (namerec->data.source == DNS_NAME) || (namerec->data.source == DNSFAIL_NAME) ) ) {
01557                 DEBUG(5,("wins_process_multihomed_name_registration_request: Name (%s) in WINS was a dns lookup \
01558 - removing it.\n", nmb_namestr(question) ));
01559                 remove_name_from_namelist( subrec, namerec);
01560                 namerec = NULL;
01561         }
01562 
01563         /*
01564          * Reject if the name exists and is not a REGISTER_NAME.
01565          * (ie. Don't allow any static names to be overwritten.
01566          */
01567 
01568         if( (namerec != NULL) && (namerec->data.source != REGISTER_NAME) ) {
01569                 DEBUG( 3, ( "wins_process_multihomed_name_registration_request: Attempt \
01570 to register name %s. Name already exists in WINS with source type %d.\n",
01571                         nmb_namestr(question), namerec->data.source ));
01572                 send_wins_name_registration_response(RFS_ERR, 0, p);
01573                 return;
01574         }
01575 
01576         /*
01577          * Reject if the name exists and is a GROUP name and is active.
01578          */
01579 
01580         if((namerec != NULL) && NAME_GROUP(namerec) && WINS_STATE_ACTIVE(namerec)) {
01581                 DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
01582 already exists in WINS as a GROUP name.\n", nmb_namestr(question) ));
01583                 send_wins_name_registration_response(RFS_ERR, 0, p);
01584                 return;
01585         } 
01586 
01587         /*
01588          * From here on down we know that if the name exists in the WINS db it is
01589          * a unique name, not a group name.
01590          */
01591 
01592         /*
01593          * If the name exists and is one of our names then check the
01594          * registering IP address. If it's not one of ours then automatically
01595          * reject without doing the query - we know we will reject it.
01596          */
01597 
01598         if((namerec != NULL) && (is_myname(namerec->name.name)) ) {
01599                 if(!ismyip(from_ip)) {
01600                         DEBUG(3,("wins_process_multihomed_name_registration_request: Attempt to register name %s. Name \
01601 is one of our (WINS server) names. Denying registration.\n", nmb_namestr(question) ));
01602                         send_wins_name_registration_response(RFS_ERR, 0, p);
01603                         return;
01604                 } else {
01605                         /*
01606                          * It's one of our names and one of our IP's. Ensure the IP is in the record and
01607                          *  update the ttl. Update the version ID to force replication.
01608                          */
01609                         update_name_ttl(namerec, ttl);
01610 
01611                         if(!find_ip_in_name_record(namerec, from_ip)) {
01612                                 get_global_id_and_update(&namerec->data.id, True);
01613                                 update_wins_owner(namerec, our_fake_ip);
01614                                 update_wins_flag(namerec, WINS_ACTIVE);
01615 
01616                                 add_ip_to_name_record(namerec, from_ip);
01617                         }
01618 
01619                         wins_hook("refresh", namerec, ttl);
01620                         send_wins_name_registration_response(0, ttl, p);
01621                         return;
01622                 }
01623         }
01624 
01625         /*
01626          * If the name exists and is active, check if the IP address is already registered
01627          * to that name. If so then update the ttl and reply success.
01628          */
01629 
01630         if((namerec != NULL) && find_ip_in_name_record(namerec, from_ip) && WINS_STATE_ACTIVE(namerec)) {
01631                 update_name_ttl(namerec, ttl);
01632 
01633                 /*
01634                  * If it's a replica, we need to become the wins owner
01635                  * to force the replication
01636                  */
01637                 if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
01638                         get_global_id_and_update(&namerec->data.id, True);
01639                         update_wins_owner(namerec, our_fake_ip);
01640                         update_wins_flag(namerec, WINS_ACTIVE);
01641                 }
01642     
01643                 wins_hook("refresh", namerec, ttl);
01644                 send_wins_name_registration_response(0, ttl, p);
01645                 return;
01646         }
01647 
01648         /*
01649          * If the name exists do a query to the owner
01650          * to see if they still want the name.
01651          */
01652 
01653         if(namerec != NULL) {
01654                 long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
01655                 struct userdata_struct *userdata = (struct userdata_struct *)ud;
01656 
01657                 /*
01658                  * First send a WACK to the registering machine.
01659                  */
01660 
01661                 send_wins_wack_response(60, p);
01662 
01663                 /*
01664                  * When the reply comes back we need the original packet.
01665                  * Lock this so it won't be freed and then put it into
01666                  * the userdata structure.
01667                  */
01668 
01669                 p->locked = True;
01670 
01671                 userdata = (struct userdata_struct *)ud;
01672 
01673                 userdata->copy_fn = NULL;
01674                 userdata->free_fn = NULL;
01675                 userdata->userdata_len = sizeof(struct packet_struct *);
01676                 memcpy(userdata->data, (char *)&p, sizeof(struct packet_struct *) );
01677 
01678                 /* 
01679                  * Use the new call to send a query directly to an IP address.
01680                  * This sends the query directly to the IP address, and ensures
01681                  * the recursion desired flag is not set (you were right Luke :-).
01682                  * This function should *only* be called from the WINS server
01683                  * code. JRA.
01684                  *
01685                  * Note that this packet is sent to the current owner of the name,
01686                  * not the person who sent the packet 
01687                  */
01688 
01689                 pull_ascii_nstring( qname, sizeof(qname), question->name);
01690                 query_name_from_wins_server( namerec->data.ip[0],
01691                                 qname,
01692                                 question->name_type, 
01693                                 wins_multihomed_register_query_success,
01694                                 wins_multihomed_register_query_fail,
01695                                 userdata );
01696 
01697                 return;
01698         }
01699 
01700         /*
01701          * Name did not exist - add it.
01702          */
01703 
01704         pull_ascii_nstring( qname, sizeof(qname), question->name);
01705         add_name_to_subnet( subrec, qname, question->name_type,
01706                         nb_flags, ttl, REGISTER_NAME, 1, &from_ip);
01707 
01708         if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
01709                 get_global_id_and_update(&namerec->data.id, True);
01710                 update_wins_owner(namerec, our_fake_ip);
01711                 update_wins_flag(namerec, WINS_ACTIVE);
01712                 wins_hook("add", namerec, ttl);
01713         }
01714 
01715         send_wins_name_registration_response(0, ttl, p);
01716 }

static int fetch_1b_traverse_fn ( TDB_CONTEXT tdb,
TDB_DATA  kbuf,
TDB_DATA  dbuf,
void *  state 
) [static]

nmbd_winsserver.c1722 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizesubnet_record::namelistwins_record_to_name_record()wins_server_subnet.

参照元 fetch_all_active_wins_1b_names().

01723 {
01724         struct name_record *namerec = NULL;
01725 
01726         if (kbuf.dsize != sizeof(unstring) + 1) {
01727                 return 0;
01728         }
01729 
01730         /* Filter out all non-1b names. */
01731         if (kbuf.dptr[sizeof(unstring)] != 0x1b) {
01732                 return 0;
01733         }
01734 
01735         namerec = wins_record_to_name_record(kbuf, dbuf);
01736         if (!namerec) {
01737                 return 0;
01738         }
01739 
01740         DLIST_ADD(wins_server_subnet->namelist, namerec);
01741         return 0;
01742 }

void fetch_all_active_wins_1b_names ( void   ) 

nmbd_winsserver.c1744 行で定義されています。

参照先 fetch_1b_traverse_fn()tdb_traverse()wins_tdb.

参照元 process_wins_dmb_query_request().

01745 {
01746         tdb_traverse(wins_tdb, fetch_1b_traverse_fn, NULL);
01747 }

static void process_wins_dmb_query_request ( struct subnet_record subrec,
struct packet_struct p 
) [static]

nmbd_winsserver.c1753 行で定義されています。

参照先 name_record::datafetch_all_active_wins_1b_names()nmb_data::ipname_record::namenmb_name::name_typesubnet_record::namelistnmb_data::nb_flagsname_record::nextnmb_data::num_ipsreply_netbios_packet()send_wins_name_query_response()set_nb_flags()wins_delete_all_tmp_in_memory_records()WINS_QUERY.

参照元 wins_process_name_query_request().

01755 {  
01756         struct name_record *namerec = NULL;
01757         char *prdata;
01758         int num_ips;
01759 
01760         /*
01761          * Go through all the ACTIVE names in the WINS db looking for those
01762          * ending in <1b>. Use this to calculate the number of IP
01763          * addresses we need to return.
01764          */
01765 
01766         num_ips = 0;
01767 
01768         /* First, clear the in memory list - we're going to re-populate
01769            it with the tdb_traversal in fetch_all_active_wins_1b_names. */
01770 
01771         wins_delete_all_tmp_in_memory_records();
01772 
01773         fetch_all_active_wins_1b_names();
01774 
01775         for( namerec = subrec->namelist; namerec; namerec = namerec->next ) {
01776                 if( WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
01777                         num_ips += namerec->data.num_ips;
01778                 }
01779         }
01780 
01781         if(num_ips == 0) {
01782                 /*
01783                  * There are no 0x1b names registered. Return name query fail.
01784                  */
01785                 send_wins_name_query_response(NAM_ERR, p, NULL);
01786                 return;
01787         }
01788 
01789         if((prdata = (char *)SMB_MALLOC( num_ips * 6 )) == NULL) {
01790                 DEBUG(0,("process_wins_dmb_query_request: Malloc fail !.\n"));
01791                 return;
01792         }
01793 
01794         /*
01795          * Go through all the names again in the WINS db looking for those
01796          * ending in <1b>. Add their IP addresses into the list we will
01797          * return.
01798          */ 
01799 
01800         num_ips = 0;
01801         for( namerec = subrec->namelist; namerec; namerec = namerec->next ) {
01802                 if( WINS_STATE_ACTIVE(namerec) && namerec->name.name_type == 0x1b) {
01803                         int i;
01804                         for(i = 0; i < namerec->data.num_ips; i++) {
01805                                 set_nb_flags(&prdata[num_ips * 6],namerec->data.nb_flags);
01806                                 putip((char *)&prdata[(num_ips * 6) + 2], &namerec->data.ip[i]);
01807                                 num_ips++;
01808                         }
01809                 }
01810         }
01811 
01812         /*
01813          * Send back the reply containing the IP list.
01814          */
01815 
01816         reply_netbios_packet(p,                                /* Packet to reply to. */
01817                                 0,                             /* Result code. */
01818                                 WINS_QUERY,                    /* nmbd type code. */
01819                                 NMB_NAME_QUERY_OPCODE,         /* opcode. */
01820                                 lp_min_wins_ttl(),             /* ttl. */
01821                                 prdata,                        /* data to send. */
01822                                 num_ips*6);                    /* data length. */
01823 
01824         SAFE_FREE(prdata);
01825 }

void send_wins_name_query_response ( int  rcode,
struct packet_struct p,
struct name_record namerec 
)

nmbd_winsserver.c1831 行で定義されています。

参照先 name_record::datanmb_data::death_timepacket_struct::ipnmb_data::ipnmb_data::nb_flagsnmb_data::num_ipsreply_netbios_packet()set_nb_flags()sort_query_replies()packet_struct::timestampWINS_QUERY.

参照元 process_wins_dmb_query_request()run_dns_queue()wins_process_name_query_request().

01833 {
01834         char rdata[6];
01835         char *prdata = rdata;
01836         int reply_data_len = 0;
01837         int ttl = 0;
01838         int i;
01839 
01840         memset(rdata,'\0',6);
01841 
01842         if(rcode == 0) {
01843                 ttl = (namerec->data.death_time != PERMANENT_TTL) ?  namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
01844 
01845                 /* Copy all known ip addresses into the return data. */
01846                 /* Optimise for the common case of one IP address so we don't need a malloc. */
01847 
01848                 if( namerec->data.num_ips == 1 ) {
01849                         prdata = rdata;
01850                 } else {
01851                         if((prdata = (char *)SMB_MALLOC( namerec->data.num_ips * 6 )) == NULL) {
01852                                 DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
01853                                 return;
01854                         }
01855                 }
01856 
01857                 for(i = 0; i < namerec->data.num_ips; i++) {
01858                         set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
01859                         putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
01860                 }
01861 
01862                 sort_query_replies(prdata, i, p->ip);
01863                 reply_data_len = namerec->data.num_ips * 6;
01864         }
01865 
01866         reply_netbios_packet(p,                                /* Packet to reply to. */
01867                                 rcode,                         /* Result code. */
01868                                 WINS_QUERY,                    /* nmbd type code. */
01869                                 NMB_NAME_QUERY_OPCODE,         /* opcode. */
01870                                 ttl,                           /* ttl. */
01871                                 prdata,                        /* data to send. */
01872                                 reply_data_len);               /* data length. */
01873 
01874         if(prdata != rdata) {
01875                 SAFE_FREE(prdata);
01876         }
01877 }

void wins_process_name_query_request ( struct subnet_record subrec,
struct packet_struct p 
)

nmbd_winsserver.c1883 行で定義されています。

参照先 name_record::datanmb_data::death_timeDNSFAIL_NAMEfind_name_on_subnet()nmb_data::ippacket_struct::ipnmb_name::namenmb_name::name_typepacket_struct::nmbnmb_namestr()packet_struct::packetprocess_wins_dmb_query_request()pull_ascii_nstring()nmb_packet::questionnmb_packet::question_namequeue_dns_query()send_wins_name_query_response()nmb_data::sourcestrequal()packet_struct::timestamp.

参照元 process_nmb_request().

01885 {
01886         struct nmb_packet *nmb = &p->packet.nmb;
01887         struct nmb_name *question = &nmb->question.question_name;
01888         struct name_record *namerec = NULL;
01889         unstring qname;
01890 
01891         DEBUG(3,("wins_process_name_query: name query for name %s from IP %s\n", 
01892                 nmb_namestr(question), inet_ntoa(p->ip) ));
01893 
01894         /*
01895          * Special name code. If the queried name is *<1b> then search
01896          * the entire WINS database and return a list of all the IP addresses
01897          * registered to any <1b> name. This is to allow domain master browsers
01898          * to discover other domains that may not have a presence on their subnet.
01899          */
01900 
01901         pull_ascii_nstring(qname, sizeof(qname), question->name);
01902         if(strequal( qname, "*") && (question->name_type == 0x1b)) {
01903                 process_wins_dmb_query_request( subrec, p);
01904                 return;
01905         }
01906 
01907         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
01908 
01909         if(namerec != NULL) {
01910                 /*
01911                  * If the name is not anymore in active state then reply not found.
01912                  * it's fair even if we keep it in the cache for days.
01913                  */
01914                 if (!WINS_STATE_ACTIVE(namerec)) {
01915                         DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
01916                                 nmb_namestr(question) ));
01917                         send_wins_name_query_response(NAM_ERR, p, namerec);
01918                         return;
01919                 }
01920 
01921                 /* 
01922                  * If it's a DNSFAIL_NAME then reply name not found.
01923                  */
01924 
01925                 if( namerec->data.source == DNSFAIL_NAME ) {
01926                         DEBUG(3,("wins_process_name_query: name query for name %s returning DNS fail.\n",
01927                                 nmb_namestr(question) ));
01928                         send_wins_name_query_response(NAM_ERR, p, namerec);
01929                         return;
01930                 }
01931 
01932                 /*
01933                  * If the name has expired then reply name not found.
01934                  */
01935 
01936                 if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < p->timestamp) ) {
01937                         DEBUG(3,("wins_process_name_query: name query for name %s - name expired. Returning fail.\n",
01938                                         nmb_namestr(question) ));
01939                         send_wins_name_query_response(NAM_ERR, p, namerec);
01940                         return;
01941                 }
01942 
01943                 DEBUG(3,("wins_process_name_query: name query for name %s returning first IP %s.\n",
01944                                 nmb_namestr(question), inet_ntoa(namerec->data.ip[0]) ));
01945 
01946                 send_wins_name_query_response(0, p, namerec);
01947                 return;
01948         }
01949 
01950         /* 
01951          * Name not found in WINS - try a dns query if it's a 0x20 name.
01952          */
01953 
01954         if(lp_dns_proxy() && ((question->name_type == 0x20) || question->name_type == 0)) {
01955                 DEBUG(3,("wins_process_name_query: name query for name %s not found - doing dns lookup.\n",
01956                                 nmb_namestr(question) ));
01957 
01958                 queue_dns_query(p, question);
01959                 return;
01960         }
01961 
01962         /*
01963          * Name not found - return error.
01964          */
01965 
01966         send_wins_name_query_response(NAM_ERR, p, NULL);
01967 }

static void send_wins_name_release_response ( int  rcode,
struct packet_struct p 
) [static]

nmbd_winsserver.c1973 行で定義されています。

参照先 nmb_packet::additionalpacket_struct::nmbNMB_RELpacket_struct::packetres_rec::rdatareply_netbios_packet().

参照元 wins_process_name_release_request().

01974 {
01975         struct nmb_packet *nmb = &p->packet.nmb;
01976         char rdata[6];
01977 
01978         memcpy(&rdata[0], &nmb->additional->rdata[0], 6);
01979 
01980         reply_netbios_packet(p,                               /* Packet to reply to. */
01981                                 rcode,                        /* Result code. */
01982                                 NMB_REL,                      /* nmbd type code. */
01983                                 NMB_NAME_RELEASE_OPCODE,      /* opcode. */
01984                                 0,                            /* ttl. */
01985                                 rdata,                        /* data to send. */
01986                                 6);                           /* data length. */
01987 }

void wins_process_name_release_request ( struct subnet_record subrec,
struct packet_struct p 
)

nmbd_winsserver.c1993 行で定義されています。

参照先 nmb_packet::additionalname_record::datafind_ip_in_name_record()find_name_on_subnet()get_nb_flags()nmb_packet::headerpacket_struct::ipnmb_name::name_typenmb_packet::nm_flagspacket_struct::nmbnmb_namestr()nmb_data::num_ipspacket_struct::packetnmb_packet::questionnmb_packet::question_nameres_rec::rdataREGISTER_NAMEremove_ip_from_name_record()send_wins_name_release_response()nmb_data::sourcesubnet_record::subnet_nameupdate_name_ttl()nmb_data::wins_flagswins_hook().

参照元 process_nmb_request().

01995 {
01996         struct nmb_packet *nmb = &p->packet.nmb;
01997         struct nmb_name *question = &nmb->question.question_name;
01998         BOOL bcast = nmb->header.nm_flags.bcast;
01999         uint16 nb_flags = get_nb_flags(nmb->additional->rdata);
02000         struct name_record *namerec = NULL;
02001         struct in_addr from_ip;
02002         BOOL releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
02003 
02004         putip((char *)&from_ip,&nmb->additional->rdata[2]);
02005 
02006         if(bcast) {
02007                 /*
02008                  * We should only get unicast name registration packets here.
02009                  * Anyone trying to register broadcast should not be going to a WINS
02010                  * server. Log an error here.
02011                  */
02012 
02013                 DEBUG(0,("wins_process_name_release_request: broadcast name registration request \
02014 received for name %s from IP %s on subnet %s. Error - should not be sent to WINS server\n",
02015                         nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
02016                 return;
02017         }
02018   
02019         DEBUG(3,("wins_process_name_release_request: %s name release for name %s \
02020 IP %s\n", releasing_group_name ? "Group" : "Unique", nmb_namestr(question), inet_ntoa(from_ip) ));
02021     
02022         /*
02023          * Deal with policy regarding 0x1d names.
02024          */
02025 
02026         if(!releasing_group_name && (question->name_type == 0x1d)) {
02027                 DEBUG(3,("wins_process_name_release_request: Ignoring request \
02028 to release name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
02029                 send_wins_name_release_response(0, p);
02030                 return;
02031         }
02032 
02033         /*
02034          * See if the name already exists.
02035          */
02036     
02037         namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME);
02038 
02039         if( (namerec == NULL) || ((namerec != NULL) && (namerec->data.source != REGISTER_NAME)) ) {
02040                 send_wins_name_release_response(NAM_ERR, p);
02041                 return;
02042         }
02043 
02044         /* 
02045          * Check that the sending machine has permission to release this name.
02046          * If it's a group name not ending in 0x1c then just say yes and let
02047          * the group time out.
02048          */
02049 
02050         if(releasing_group_name && (question->name_type != 0x1c)) {
02051                 send_wins_name_release_response(0, p);
02052                 return;
02053         }
02054 
02055         /* 
02056          * Check that the releasing node is on the list of IP addresses
02057          * for this name. Disallow the release if not.
02058          */
02059 
02060         if(!find_ip_in_name_record(namerec, from_ip)) {
02061                 DEBUG(3,("wins_process_name_release_request: Refusing request to \
02062 release name %s as IP %s is not one of the known IP's for this name.\n",
02063                         nmb_namestr(question), inet_ntoa(from_ip) ));
02064                 send_wins_name_release_response(NAM_ERR, p);
02065                 return;
02066         }
02067 
02068         /*
02069          * Check if the record is active. IF it's already released
02070          * or tombstoned, refuse the release.
02071          */
02072 
02073         if (!WINS_STATE_ACTIVE(namerec)) {
02074                 DEBUG(3,("wins_process_name_release_request: Refusing request to \
02075 release name %s as this record is not active anymore.\n", nmb_namestr(question) ));
02076                 send_wins_name_release_response(NAM_ERR, p);
02077                 return;
02078         }    
02079 
02080         /*
02081          * Check if the record is a 0x1c group
02082          * and has more then one ip
02083          * remove only this address.
02084          */
02085 
02086         if(releasing_group_name && (question->name_type == 0x1c) && (namerec->data.num_ips > 1)) {
02087                 remove_ip_from_name_record(namerec, from_ip);
02088                 DEBUG(3,("wins_process_name_release_request: Remove IP %s from NAME: %s\n",
02089                                 inet_ntoa(from_ip),nmb_namestr(question)));
02090                 wins_hook("delete", namerec, 0);
02091                 send_wins_name_release_response(0, p);
02092                 return;
02093         }
02094 
02095         /* 
02096          * Send a release response.
02097          * Flag the name as released and update the ttl
02098          */
02099 
02100         namerec->data.wins_flags |= WINS_RELEASED;
02101         update_name_ttl(namerec, EXTINCTION_INTERVAL);
02102 
02103         wins_hook("delete", namerec, 0);
02104         send_wins_name_release_response(0, p);
02105 }

static int wins_processing_traverse_fn ( TDB_CONTEXT tdb,
TDB_DATA  kbuf,
TDB_DATA  dbuf,
void *  state 
) [static]

nmbd_winsserver.c2111 行で定義されています。

参照先 name_record::datanmb_data::death_timeDNS_NAMEDNSFAIL_NAMETDB_DATA::dsizeget_global_id_and_update()nmb_data::idinterpret_addr2()nmb_data::ipname_record::namenmb_namestr()remove_name_from_wins_namelist()SELF_NAMEnmb_data::sourcesubnet_record::subnet_nametnmb_data::wins_flagsnmb_data::wins_ipwins_record_to_name_record()wins_server_subnetwins_store_changed_namerec().

参照元 initiate_wins_processing().

02112 {
02113         time_t t = *(time_t *)state;
02114         BOOL store_record = False;
02115         struct name_record *namerec = NULL;
02116         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
02117 
02118         if (kbuf.dsize != sizeof(unstring) + 1) {
02119                 return 0;
02120         }
02121 
02122         namerec = wins_record_to_name_record(kbuf, dbuf);
02123         if (!namerec) {
02124                 return 0;
02125         }
02126 
02127         if( (namerec->data.death_time != PERMANENT_TTL) && (namerec->data.death_time < t) ) {
02128                 if( namerec->data.source == SELF_NAME ) {
02129                         DEBUG( 3, ( "wins_processing_traverse_fn: Subnet %s not expiring SELF name %s\n", 
02130                                    wins_server_subnet->subnet_name, nmb_namestr(&namerec->name) ) );
02131                         namerec->data.death_time += 300;
02132                         store_record = True;
02133                         goto done;
02134                 } else if (namerec->data.source == DNS_NAME || namerec->data.source == DNSFAIL_NAME) {
02135                         DEBUG(3,("wins_processing_traverse_fn: deleting timed out DNS name %s\n",
02136                                         nmb_namestr(&namerec->name)));
02137                         remove_name_from_wins_namelist(namerec );
02138                         goto done;
02139                 }
02140 
02141                 /* handle records, samba is the wins owner */
02142                 if (ip_equal(namerec->data.wins_ip, our_fake_ip)) {
02143                         switch (namerec->data.wins_flags & WINS_STATE_MASK) {
02144                                 case WINS_ACTIVE:
02145                                         namerec->data.wins_flags&=~WINS_STATE_MASK;
02146                                         namerec->data.wins_flags|=WINS_RELEASED;
02147                                         namerec->data.death_time = t + EXTINCTION_INTERVAL;
02148                                         DEBUG(3,("wins_processing_traverse_fn: expiring %s\n",
02149                                                 nmb_namestr(&namerec->name)));
02150                                         store_record = True;
02151                                         goto done;
02152                                 case WINS_RELEASED:
02153                                         namerec->data.wins_flags&=~WINS_STATE_MASK;
02154                                         namerec->data.wins_flags|=WINS_TOMBSTONED;
02155                                         namerec->data.death_time = t + EXTINCTION_TIMEOUT;
02156                                         get_global_id_and_update(&namerec->data.id, True);
02157                                         DEBUG(3,("wins_processing_traverse_fn: tombstoning %s\n",
02158                                                 nmb_namestr(&namerec->name)));
02159                                         store_record = True;
02160                                         goto done;
02161                                 case WINS_TOMBSTONED:
02162                                         DEBUG(3,("wins_processing_traverse_fn: deleting %s\n",
02163                                                 nmb_namestr(&namerec->name)));
02164                                         remove_name_from_wins_namelist(namerec );
02165                                         goto done;
02166                         }
02167                 } else {
02168                         switch (namerec->data.wins_flags & WINS_STATE_MASK) {
02169                                 case WINS_ACTIVE:
02170                                         /* that's not as MS says it should be */
02171                                         namerec->data.wins_flags&=~WINS_STATE_MASK;
02172                                         namerec->data.wins_flags|=WINS_TOMBSTONED;
02173                                         namerec->data.death_time = t + EXTINCTION_TIMEOUT;
02174                                         DEBUG(3,("wins_processing_traverse_fn: tombstoning %s\n",
02175                                                 nmb_namestr(&namerec->name)));
02176                                         store_record = True;
02177                                         goto done;
02178                                 case WINS_TOMBSTONED:
02179                                         DEBUG(3,("wins_processing_traverse_fn: deleting %s\n",
02180                                                 nmb_namestr(&namerec->name)));
02181                                         remove_name_from_wins_namelist(namerec );
02182                                         goto done;
02183                                 case WINS_RELEASED:
02184                                         DEBUG(0,("wins_processing_traverse_fn: %s is in released state and\
02185 we are not the wins owner !\n", nmb_namestr(&namerec->name)));
02186                                         goto done;
02187                         }
02188                 }
02189         }
02190 
02191   done:
02192 
02193         if (store_record) {
02194                 wins_store_changed_namerec(namerec);
02195         }
02196 
02197         SAFE_FREE(namerec->data.ip);
02198         SAFE_FREE(namerec);
02199 
02200         return 0;
02201 }

void initiate_wins_processing ( time_t  t  ) 

nmbd_winsserver.c2207 行で定義されています。

参照先 tdb_traverse()wins_delete_all_tmp_in_memory_records()wins_processing_traverse_fn()wins_tdbwins_write_database().

参照元 process().

02208 {
02209         static time_t lasttime = 0;
02210 
02211         if (!lasttime) {
02212                 lasttime = t;
02213         }
02214         if (t - lasttime < 20) {
02215                 return;
02216         }
02217 
02218         if(!lp_we_are_a_wins_server()) {
02219                 lasttime = t;
02220                 return;
02221         }
02222 
02223         tdb_traverse(wins_tdb, wins_processing_traverse_fn, &t);
02224 
02225         wins_delete_all_tmp_in_memory_records();
02226 
02227         wins_write_database(t, True);
02228 
02229         lasttime = t;
02230 }

void wins_write_name_record ( struct name_record namerec,
XFILE fp 
)

nmbd_winsserver.c2236 行で定義されています。

参照先 name_record::datanmb_data::death_timefpnmb_data::iplocaltime()nmb_name::namenamename_record::namenmb_name::name_typenmb_data::nb_flagsnmb_namestr()nmb_data::num_ipspull_ascii_nstring()REGISTER_NAMEnmb_data::sourcex_fprintf().

参照元 wins_writedb_traverse_fn().

02237 {
02238         int i;
02239         struct tm *tm;
02240 
02241         DEBUGADD(4,("%-19s ", nmb_namestr(&namerec->name) ));
02242 
02243         if( namerec->data.death_time != PERMANENT_TTL ) {
02244                 char *ts, *nl;
02245 
02246                 tm = localtime(&namerec->data.death_time);
02247                 if (!tm) {
02248                         return;
02249                 }
02250                 ts = asctime(tm);
02251                 if (!ts) {
02252                         return;
02253                 }
02254                 nl = strrchr( ts, '\n' );
02255                 if( NULL != nl ) {
02256                         *nl = '\0';
02257                 }
02258                 DEBUGADD(4,("TTL = %s  ", ts ));
02259         } else {
02260                 DEBUGADD(4,("TTL = PERMANENT                 "));
02261         }
02262 
02263         for (i = 0; i < namerec->data.num_ips; i++) {
02264                 DEBUGADD(4,("%15s ", inet_ntoa(namerec->data.ip[i]) ));
02265         }
02266         DEBUGADD(4,("%2x\n", namerec->data.nb_flags ));
02267 
02268         if( namerec->data.source == REGISTER_NAME ) {
02269                 unstring name;
02270                 pull_ascii_nstring(name, sizeof(name), namerec->name.name);
02271                 x_fprintf(fp, "\"%s#%02x\" %d ", name,namerec->name.name_type, /* Ignore scope. */
02272                         (int)namerec->data.death_time);
02273 
02274                 for (i = 0; i < namerec->data.num_ips; i++)
02275                         x_fprintf( fp, "%s ", inet_ntoa( namerec->data.ip[i] ) );
02276                 x_fprintf( fp, "%2xR\n", namerec->data.nb_flags );
02277         }
02278 }

static int wins_writedb_traverse_fn ( TDB_CONTEXT tdb,
TDB_DATA  kbuf,
TDB_DATA  dbuf,
void *  state 
) [static]

nmbd_winsserver.c2284 行で定義されています。

参照先 name_record::dataTDB_DATA::dsizefpnmb_data::ipwins_record_to_name_record()wins_write_name_record().

参照元 wins_write_database().

02285 {
02286         struct name_record *namerec = NULL;
02287         XFILE *fp = (XFILE *)state;
02288 
02289         if (kbuf.dsize != sizeof(unstring) + 1) {
02290                 return 0;
02291         }
02292 
02293         namerec = wins_record_to_name_record(kbuf, dbuf);
02294         if (!namerec) {
02295                 return 0;
02296         }
02297 
02298         wins_write_name_record(namerec, fp);
02299 
02300         SAFE_FREE(namerec->data.ip);
02301         SAFE_FREE(namerec);
02302         return 0;
02303 }

void wins_write_database ( time_t  t,
BOOL  background 
)

nmbd_winsserver.c2306 行で定義されています。

参照先 all_string_sub()CatchChild()errnofpstrerror()sys_fork()sys_getpid()tdb_reopen()tdb_traverse()wins_tdbwins_writedb_traverse_fn()x_fclose()x_fopen()x_fprintf().

参照元 initiate_wins_processing()terminate().

02307 {
02308         static time_t last_write_time = 0;
02309         pstring fname, fnamenew;
02310 
02311         XFILE *fp;
02312    
02313         if (background) {
02314                 if (!last_write_time) {
02315                         last_write_time = t;
02316                 }
02317                 if (t - last_write_time < 120) {
02318                         return;
02319                 }
02320 
02321         }
02322 
02323         if(!lp_we_are_a_wins_server()) {
02324                 return;
02325         }
02326 
02327         /* We will do the writing in a child process to ensure that the parent doesn't block while this is done */
02328         if (background) {
02329                 CatchChild();
02330                 if (sys_fork()) {
02331                         return;
02332                 }
02333                 if (tdb_reopen(wins_tdb)) {
02334                         DEBUG(0,("wins_write_database: tdb_reopen failed. Error was %s\n",
02335                                 strerror(errno)));
02336                         _exit(0);
02337                         return;
02338                 }
02339         }
02340 
02341         slprintf(fname,sizeof(fname)-1,"%s/%s", lp_lockdir(), WINS_LIST);
02342         all_string_sub(fname,"//", "/", 0);
02343         slprintf(fnamenew,sizeof(fnamenew)-1,"%s.%u", fname, (unsigned int)sys_getpid());
02344 
02345         if((fp = x_fopen(fnamenew,O_WRONLY|O_CREAT,0644)) == NULL) {
02346                 DEBUG(0,("wins_write_database: Can't open %s. Error was %s\n", fnamenew, strerror(errno)));
02347                 if (background) {
02348                         _exit(0);
02349                 }
02350                 return;
02351         }
02352 
02353         DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
02354 
02355         x_fprintf(fp,"VERSION %d %u\n", WINS_VERSION, 0);
02356  
02357         tdb_traverse(wins_tdb, wins_writedb_traverse_fn, fp);
02358 
02359         x_fclose(fp);
02360         chmod(fnamenew,0644);
02361         unlink(fname);
02362         rename(fnamenew,fname);
02363         if (background) {
02364                 _exit(0);
02365         }
02366 }

Until winsrepl is done void nmbd_wins_new_entry ( int  msg_type,
struct process_id  src,
void *  buf,
size_t  len,
void *  private_data 
)

nmbd_winsserver.c2374 行で定義されています。

参照先 add_ip_to_name_record()add_name_to_subnet()name_record::datafind_ip_in_name_record()find_name_on_subnet()get_global_id_and_update()nmb_data::id_WINS_RECORD::idinterpret_addr2()nmb_data::ip_WINS_RECORD::ipmake_nmb_name()_WINS_RECORD::namesubnet_record::namelist_changed_WINS_RECORD::nb_flags_WINS_RECORD::num_ipsREGISTER_NAME_WINS_RECORD::typeupdate_wins_flag()update_wins_owner()nmb_data::wins_flags_WINS_RECORD::wins_flagsnmb_data::wins_ip_WINS_RECORD::wins_ipwins_server_subnet.

参照元 main().

02376 {
02377         WINS_RECORD *record;
02378         struct name_record *namerec = NULL;
02379         struct name_record *new_namerec = NULL;
02380         struct nmb_name question;
02381         BOOL overwrite=False;
02382         struct in_addr our_fake_ip = *interpret_addr2("0.0.0.0");
02383         int i;
02384 
02385         if (buf==NULL) {
02386                 return;
02387         }
02388         
02389         /* Record should use UNIX codepage. Ensure this is so in the wrepld code. JRA. */
02390         record=(WINS_RECORD *)buf;
02391         
02392         make_nmb_name(&question, record->name, record->type);
02393 
02394         namerec = find_name_on_subnet(wins_server_subnet, &question, FIND_ANY_NAME);
02395 
02396         /* record doesn't exist, add it */
02397         if (namerec == NULL) {
02398                 DEBUG(3,("nmbd_wins_new_entry: adding new replicated record: %s<%02x> for wins server: %s\n", 
02399                           record->name, record->type, inet_ntoa(record->wins_ip)));
02400 
02401                 new_namerec=add_name_to_subnet( wins_server_subnet,
02402                                                 record->name,
02403                                                 record->type,
02404                                                 record->nb_flags, 
02405                                                 EXTINCTION_INTERVAL,
02406                                                 REGISTER_NAME,
02407                                                 record->num_ips,
02408                                                 record->ip);
02409 
02410                 if (new_namerec!=NULL) {
02411                                 update_wins_owner(new_namerec, record->wins_ip);
02412                                 update_wins_flag(new_namerec, record->wins_flags);
02413                                 new_namerec->data.id=record->id;
02414 
02415                                 wins_server_subnet->namelist_changed = True;
02416                         }
02417         }
02418 
02419         /* check if we have a conflict */
02420         if (namerec != NULL) {
02421                 /* both records are UNIQUE */
02422                 if (namerec->data.wins_flags&WINS_UNIQUE && record->wins_flags&WINS_UNIQUE) {
02423 
02424                         /* the database record is a replica */
02425                         if (!ip_equal(namerec->data.wins_ip, our_fake_ip)) {
02426                                 if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED) {
02427                                         if (ip_equal(namerec->data.wins_ip, record->wins_ip))
02428                                                 overwrite=True;
02429                                 } else
02430                                         overwrite=True;
02431                         } else {
02432                         /* we are the wins owner of the database record */
02433                                 /* the 2 records have the same IP address */
02434                                 if (ip_equal(namerec->data.ip[0], record->ip[0])) {
02435                                         if (namerec->data.wins_flags&WINS_ACTIVE && record->wins_flags&WINS_TOMBSTONED)
02436                                                 get_global_id_and_update(&namerec->data.id, True);
02437                                         else
02438                                                 overwrite=True;
02439                                 
02440                                 } else {
02441                                 /* the 2 records have different IP address */
02442                                         if (namerec->data.wins_flags&WINS_ACTIVE) {
02443                                                 if (record->wins_flags&WINS_TOMBSTONED)
02444                                                         get_global_id_and_update(&namerec->data.id, True);
02445                                                 if (record->wins_flags&WINS_ACTIVE)
02446                                                         /* send conflict challenge to the replica node */
02447                                                         ;
02448                                         } else
02449                                                 overwrite=True;
02450                                 }
02451 
02452                         }
02453                 }
02454                 
02455                 /* the replica is a standard group */
02456                 if (record->wins_flags&WINS_NGROUP || record->wins_flags&WINS_SGROUP) {
02457                         /* if the database record is unique and active force a name release */
02458                         if (namerec->data.wins_flags&WINS_UNIQUE)
02459                                 /* send a release name to the unique node */
02460                                 ;
02461                         overwrite=True;
02462                 
02463                 }
02464         
02465                 /* the replica is a special group */
02466                 if (record->wins_flags&WINS_SGROUP && namerec->data.wins_flags&WINS_SGROUP) {
02467                         if (namerec->data.wins_flags&WINS_ACTIVE) {
02468                                 for (i=0; i<record->num_ips; i++)
02469                                         if(!find_ip_in_name_record(namerec, record->ip[i]))
02470                                                 add_ip_to_name_record(namerec, record->ip[i]);
02471                         } else {
02472                                 overwrite=True;
02473                         }
02474                 }
02475                 
02476                 /* the replica is a multihomed host */
02477                 
02478                 /* I'm giving up on multi homed. Too much complex to understand */
02479                 
02480                 if (record->wins_flags&WINS_MHOMED) {
02481                         if (! (namerec->data.wins_flags&WINS_ACTIVE)) {
02482                                 if ( !(namerec->data.wins_flags&WINS_RELEASED) && !(namerec->data.wins_flags&WINS_NGROUP))
02483                                         overwrite=True;
02484                         }
02485                         else {
02486                                 if (ip_equal(record->wins_ip, namerec->data.wins_ip))
02487                                         overwrite=True;
02488                                 
02489                                 if (ip_equal(namerec->data.wins_ip, our_fake_ip))
02490                                         if (namerec->data.wins_flags&WINS_UNIQUE)
02491                                                 get_global_id_and_update(&namerec->data.id, True);
02492                                 
02493                         }
02494                         
02495                         if (record->wins_flags&WINS_ACTIVE && namerec->data.wins_flags&WINS_ACTIVE)
02496                                 if (namerec->data.wins_flags&WINS_UNIQUE ||
02497                                     namerec->data.wins_flags&WINS_MHOMED)
02498                                         if (ip_equal(record->wins_ip, namerec->data.wins_ip))
02499                                                 overwrite=True;
02500                                 
02501                 }
02502 
02503                 if (overwrite == False)
02504                         DEBUG(3, ("nmbd_wins_new_entry: conflict in adding record: %s<%02x> from wins server: %s\n", 
02505                                   record->name, record->type, inet_ntoa(record->wins_ip)));
02506                 else {
02507                         DEBUG(3, ("nmbd_wins_new_entry: replacing record: %s<%02x> from wins server: %s\n", 
02508                                   record->name, record->type, inet_ntoa(record->wins_ip)));
02509 
02510                         /* remove the old record and add a new one */
02511                         remove_name_from_namelist( wins_server_subnet, namerec );
02512                         new_namerec=add_name_to_subnet( wins_server_subnet, record->name, record->type, record->nb_flags, 
02513                                                 EXTINCTION_INTERVAL, REGISTER_NAME, record->num_ips, record->ip);
02514                         if (new_namerec!=NULL) {
02515                                 update_wins_owner(new_namerec, record->wins_ip);
02516                                 update_wins_flag(new_namerec, record->wins_flags);
02517                                 new_namerec->data.id=record->id;
02518 
02519                                 wins_server_subnet->namelist_changed = True;
02520                         }
02521 
02522                         wins_server_subnet->namelist_changed = True;
02523                 }
02524 
02525         }
02526 }


変数

TDB_CONTEXT* wins_tdb

nmbd_winsserver.c35 行で定義されています。

参照元 dump_wins_subnet_namelist()fetch_all_active_wins_1b_names()find_name_on_wins_subnet()initialise_wins()initiate_wins_processing()remove_name_from_wins_namelist()store_or_replace_wins_namerec()wins_write_database().


Sambaに対してSat Aug 29 21:23:54 2009に生成されました。  doxygen 1.4.7