static void wins_delete_all_tmp_in_memory_records | ( | void | ) | [static] |
nmbd_winsserver.c の 41 行で定義されています。
参照先 name_record::data・nmb_data::ip・subnet_record::namelist・name_record::next・wins_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.c の 59 行で定義されています。
参照先 name_record::data・nmb_data::death_time・TDB_DATA::dptr・global_scope()・nmb_data::id・nmb_data::ip・len・nmb_name::name・name_record::name・nmb_name::name_type・nmb_data::nb_flags・nmb_data::num_ips・push_ascii()・push_ascii_nstring()・nmb_data::refresh_time・nmb_name::scope・nmb_data::source・name_record::subnet・tdb_unpack()・nmb_data::wins_flags・nmb_data::wins_ip・wins_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.c の 145 行で定義されています。
参照先 name_record::data・nmb_data::death_time・nmb_data::id・nmb_data::ip・len・nmb_data::nb_flags・nmb_data::num_ips・nmb_data::refresh_time・nmb_data::source・tdb_pack()・nmb_data::wins_flags・nmb_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 }
nmbd_winsserver.c の 190 行で定義されています。
参照先 nmb_name::name・nmb_name::name_type・pull_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.c の 211 行で定義されています。
参照先 name_record::data・nmb_data::ip・name_record::name・nmb_name::name・name_to_key()・subnet_record::namelist・name_record::next・nmb_namestr()・PERMANENT_NAME・SELF_NAME・nmb_data::source・tdb_fetch()・wins_record_to_name_record()・wins_server_subnet・wins_tdb.
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.c の 266 行で定義されています。
参照先 name_record::data・name_record::name・name_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.c の 292 行で定義されています。
参照先 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.c の 301 行で定義されています。
参照先 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.c の 311 行で定義されています。
参照先 name_record::name・name_to_key()・subnet_record::namelist・tdb_delete()・wins_server_subnet・wins_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.c の 334 行で定義されています。
参照先 name_record::data・TDB_DATA::dsize・dump_name_record()・fp・nmb_data::ip・wins_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.c の 355 行で定義されています。
参照先 fp・tdb_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] |
static void update_wins_flag | ( | struct name_record * | namerec, | |
int | flags | |||
) | [static] |
nmbd_winsserver.c の 373 行で定義されています。
参照先 name_record::data・nmb_data::death_time・name_record::name・nmb_name::name_type・nmb_data::nb_flags・nmb_data::num_ips・nmb_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.c の 416 行で定義されています。
参照元 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.c の 439 行で定義されています。
参照先 name_record::data・nmb_data::ip・nmb_name::name・name_record::name・nmb_name::name_type・nmb_namestr()・nmb_data::num_ips・smbrun()・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.c の 486 行で定義されています。
参照先 nmb_packet::header・nmb_packet::nm_flags・nmb_packet::opcode・packet・nmb_packet::question・nmb_packet::question_type・nmb_packet::response・wins_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.c の 547 行で定義されています。
参照先 nmb_packet::additional・res_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.c の 566 行で定義されています。
参照先 add_name_to_subnet()・add_samba_names_to_subnet()・errno・fgets_slash()・fp・interpret_addr2()・line・lock_path()・name・next_token()・REGISTER_NAME・strerror()・tdb_open_log()・tdb_store_int32()・type・wins_server_subnet・wins_tdb・x_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.c の 743 行で定義されています。
参照先 nmb_packet::header・nmb_packet::nm_flags・packet_struct::nmb・NMB_WAIT_ACK・nmb_packet::opcode・packet_struct::packet・reply_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.c の 783 行で定義されています。
参照先 nmb_packet::additional・packet_struct::nmb・packet_struct::packet・res_rec::rdata・reply_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.c の 803 行で定義されています。
参照先 nmb_packet::additional・dbgtext()・find_ip_in_name_record()・find_name_on_subnet()・get_global_id_and_update()・get_nb_flags()・get_ttl_from_packet()・nmb_packet::header・interpret_addr2()・nmb_name::name_type・nmb_packet::nm_flags・packet_struct::nmb・nmb_namestr()・packet_struct::packet・nmb_packet::question・nmb_packet::question_name・res_rec::rdata・remove_name_from_namelist()・send_wins_name_registration_response()・subnet_record::subnet_name・update_name_ttl()・update_wins_owner()・wins_hook()・wins_process_name_registration_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.c の 981 行で定義されています。
参照先 userdata_struct::data・free_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.c の 1010 行で定義されています。
参照先 name_record::data・userdata_struct::data・find_name_on_subnet()・free_packet()・nmb_data::ip・packet_struct::ip・nmb_namestr()・response_record::packet・REGISTER_NAME・remove_name_from_namelist()・nmb_data::source・response_record::userdata・wins_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.c の 1108 行で定義されています。
参照先 add_ip_to_name_record()・add_name_to_subnet()・nmb_packet::additional・userdata_struct::copy_fn・userdata_struct::data・name_record::data・DNS_NAME・DNSFAIL_NAME・find_ip_in_name_record()・find_name_on_subnet()・userdata_struct::free_fn・get_global_id_and_update()・get_nb_flags()・get_ttl_from_packet()・nmb_packet::header・nmb_data::id・interpret_addr2()・nmb_data::ip・packet_struct::ip・is_myname()・ismyip()・packet_struct::locked・nmb_name::name・name_record::name・name・nmb_name::name_type・nmb_packet::nm_flags・packet_struct::nmb・nmb_namestr()・nmb_data::num_ips・packet_struct::packet・pull_ascii_nstring()・query_name_from_wins_server()・nmb_packet::question・nmb_packet::question_name・res_rec::rdata・REGISTER_NAME・remove_name_from_namelist()・send_wins_name_registration_response()・send_wins_wack_response()・nmb_data::source・subnet_record::subnet_name・update_name_ttl()・update_wins_flag()・update_wins_owner()・userdata_struct::userdata_len・wins_hook()・nmb_data::wins_ip・wins_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.c の 1390 行で定義されています。
参照先 add_ip_to_name_record()・nmb_packet::additional・name_record::data・userdata_struct::data・find_ip_in_name_record()・find_name_on_subnet()・free_packet()・get_global_id_and_update()・get_ttl_from_packet()・nmb_data::id・interpret_addr2()・nmb_namestr()・res_rec::rdata・REGISTER_NAME・send_wins_name_registration_response()・nmb_data::source・update_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.c の 1455 行で定義されています。
参照先 userdata_struct::data・free_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.c の 1479 行で定義されています。
参照先 add_ip_to_name_record()・add_name_to_subnet()・nmb_packet::additional・userdata_struct::copy_fn・userdata_struct::data・name_record::data・DNS_NAME・DNSFAIL_NAME・find_ip_in_name_record()・find_name_on_subnet()・userdata_struct::free_fn・get_global_id_and_update()・get_nb_flags()・get_ttl_from_packet()・nmb_packet::header・nmb_data::id・interpret_addr2()・nmb_data::ip・packet_struct::ip・is_myname()・ismyip()・packet_struct::locked・nmb_name::name・name_record::name・nmb_name::name_type・nmb_packet::nm_flags・packet_struct::nmb・nmb_namestr()・packet_struct::packet・pull_ascii_nstring()・query_name_from_wins_server()・nmb_packet::question・nmb_packet::question_name・res_rec::rdata・REGISTER_NAME・remove_name_from_namelist()・send_wins_name_registration_response()・send_wins_wack_response()・nmb_data::source・subnet_record::subnet_name・update_name_ttl()・update_wins_flag()・update_wins_owner()・userdata_struct::userdata_len・wins_hook()・wins_multihomed_register_query_fail()・wins_multihomed_register_query_success().
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.c の 1722 行で定義されています。
参照先 TDB_DATA::dptr・TDB_DATA::dsize・subnet_record::namelist・wins_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.c の 1744 行で定義されています。
参照先 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.c の 1753 行で定義されています。
参照先 name_record::data・fetch_all_active_wins_1b_names()・nmb_data::ip・name_record::name・nmb_name::name_type・subnet_record::namelist・nmb_data::nb_flags・name_record::next・nmb_data::num_ips・reply_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.c の 1831 行で定義されています。
参照先 name_record::data・nmb_data::death_time・packet_struct::ip・nmb_data::ip・nmb_data::nb_flags・nmb_data::num_ips・reply_netbios_packet()・set_nb_flags()・sort_query_replies()・packet_struct::timestamp・WINS_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.c の 1883 行で定義されています。
参照先 name_record::data・nmb_data::death_time・DNSFAIL_NAME・find_name_on_subnet()・nmb_data::ip・packet_struct::ip・nmb_name::name・nmb_name::name_type・packet_struct::nmb・nmb_namestr()・packet_struct::packet・process_wins_dmb_query_request()・pull_ascii_nstring()・nmb_packet::question・nmb_packet::question_name・queue_dns_query()・send_wins_name_query_response()・nmb_data::source・strequal()・packet_struct::timestamp.
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.c の 1973 行で定義されています。
参照先 nmb_packet::additional・packet_struct::nmb・NMB_REL・packet_struct::packet・res_rec::rdata・reply_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.c の 1993 行で定義されています。
参照先 nmb_packet::additional・name_record::data・find_ip_in_name_record()・find_name_on_subnet()・get_nb_flags()・nmb_packet::header・packet_struct::ip・nmb_name::name_type・nmb_packet::nm_flags・packet_struct::nmb・nmb_namestr()・nmb_data::num_ips・packet_struct::packet・nmb_packet::question・nmb_packet::question_name・res_rec::rdata・REGISTER_NAME・remove_ip_from_name_record()・send_wins_name_release_response()・nmb_data::source・subnet_record::subnet_name・update_name_ttl()・nmb_data::wins_flags・wins_hook().
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.c の 2111 行で定義されています。
参照先 name_record::data・nmb_data::death_time・DNS_NAME・DNSFAIL_NAME・TDB_DATA::dsize・get_global_id_and_update()・nmb_data::id・interpret_addr2()・nmb_data::ip・name_record::name・nmb_namestr()・remove_name_from_wins_namelist()・SELF_NAME・nmb_data::source・subnet_record::subnet_name・t・nmb_data::wins_flags・nmb_data::wins_ip・wins_record_to_name_record()・wins_server_subnet・wins_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.c の 2207 行で定義されています。
参照先 tdb_traverse()・wins_delete_all_tmp_in_memory_records()・wins_processing_traverse_fn()・wins_tdb・wins_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.c の 2236 行で定義されています。
参照先 name_record::data・nmb_data::death_time・fp・nmb_data::ip・localtime()・nmb_name::name・name・name_record::name・nmb_name::name_type・nmb_data::nb_flags・nmb_namestr()・nmb_data::num_ips・pull_ascii_nstring()・REGISTER_NAME・nmb_data::source・x_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.c の 2284 行で定義されています。
参照先 name_record::data・TDB_DATA::dsize・fp・nmb_data::ip・wins_record_to_name_record()・wins_write_name_record().
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.c の 2306 行で定義されています。
参照先 all_string_sub()・CatchChild()・errno・fp・strerror()・sys_fork()・sys_getpid()・tdb_reopen()・tdb_traverse()・wins_tdb・wins_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.c の 2374 行で定義されています。
参照先 add_ip_to_name_record()・add_name_to_subnet()・name_record::data・find_ip_in_name_record()・find_name_on_subnet()・get_global_id_and_update()・nmb_data::id・_WINS_RECORD::id・interpret_addr2()・nmb_data::ip・_WINS_RECORD::ip・make_nmb_name()・_WINS_RECORD::name・subnet_record::namelist_changed・_WINS_RECORD::nb_flags・_WINS_RECORD::num_ips・REGISTER_NAME・_WINS_RECORD::type・update_wins_flag()・update_wins_owner()・nmb_data::wins_flags・_WINS_RECORD::wins_flags・nmb_data::wins_ip・_WINS_RECORD::wins_ip・wins_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 }