Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source3/nmbd/nmbd_winsserver.c

    r454 r745  
    2222
    2323#include "includes.h"
     24#include "system/filesys.h"
     25#include "nmbd/nmbd.h"
     26#include "util_tdb.h"
    2427
    2528#define WINS_LIST "wins.dat"
     
    4952                SAFE_FREE(nr->data.ip);
    5053                SAFE_FREE(nr);
     54        }
     55}
     56
     57/****************************************************************************
     58 Delete all the temporary 1b name records on the in-memory linked list.
     59*****************************************************************************/
     60
     61static void wins_delete_all_1b_in_memory_records(void)
     62{
     63        struct name_record *nr = NULL;
     64        struct name_record *nrnext = NULL;
     65
     66        /* Delete all temporary 1b name records on the wins subnet linked list. */
     67        for( nr = wins_server_subnet->namelist; nr; nr = nrnext) {
     68                nrnext = nr->next;
     69                if (nr->name.name_type == 0x1b) {
     70                        DLIST_REMOVE(wins_server_subnet->namelist, nr);
     71                        SAFE_FREE(nr->data.ip);
     72                        SAFE_FREE(nr);
     73                }
    5174        }
    5275}
     
    405428        namerec->data.wins_flags|=flags;
    406429
    407         DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: 0x%d, flags: 0x%x, winsflags: 0x%x\n",
     430        DEBUG(8,("update_wins_flag: nbflags: 0x%x, ttl: %d, flags: 0x%x, winsflags: 0x%x\n",
    408431                 namerec->data.nb_flags, (int)namerec->data.death_time, flags, namerec->data.wins_flags));
    409432}
     
    584607
    585608        /* Open the wins.tdb. */
    586         wins_tdb = tdb_open_log(state_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_CREAT|O_RDWR, 0600);
     609        wins_tdb = tdb_open_log(state_path("wins.tdb"), 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
     610                        O_CREAT|O_RDWR, 0600);
    587611        if (!wins_tdb) {
    588612                DEBUG(0,("initialise_wins: failed to open wins.tdb. Error was %s\n",
     
    12511275
    12521276                        if(!find_ip_in_name_record(namerec, from_ip)) {
     1277                                /*
     1278                                 * Need to emulate the behaviour of Windows, as
     1279                                 * described in:
     1280                                 * http://lists.samba.org/archive/samba-technical/2001-October/016236.html
     1281                                 * (is there an MS reference for this
     1282                                 * somewhere?) because if the 1c list gets over
     1283                                 * 86 entries, the reply packet is too big
     1284                                 * (rdata>576 bytes) so no reply is sent.
     1285                                 *
     1286                                 * Keep only the "latest" 25 records, while
     1287                                 * ensuring that the PDC (0x1b) is never removed
     1288                                 * We do this by removing the first entry that
     1289                                 * isn't the 1b entry for the same name,
     1290                                 * on the grounds that insertion is at the end
     1291                                 * of the list, so the oldest entries are at
     1292                                 * the start.
     1293                                 *
     1294                                 */
     1295                                while(namerec->data.num_ips>=25) {
     1296                                        struct name_record *name1brec = NULL;
     1297
     1298                                        /* We only do this for 1c types. */
     1299                                        if (namerec->name.name_type != 0x1c) {
     1300                                                break;
     1301                                        }
     1302                                        DEBUG(3,("wins_process_name_registration_request: "
     1303                                                "More than 25 IPs already in "
     1304                                                "the list. Looking for a 1b "
     1305                                                "record\n"));
     1306
     1307                                        /* Ensure we have all the active 1b
     1308                                         * names on the list. */
     1309                                        wins_delete_all_1b_in_memory_records();
     1310                                        fetch_all_active_wins_1b_names();
     1311
     1312                                        /* Per the above, find the 1b record,
     1313                                           and then remove the first IP that isn't the same */
     1314                                        for(name1brec = subrec->namelist;
     1315                                                        name1brec;
     1316                                                        name1brec = name1brec->next ) {
     1317                                                if( WINS_STATE_ACTIVE(name1brec) &&
     1318                                                                name1brec->name.name_type == 0x1b) {
     1319                                                        DEBUG(3,("wins_process_name_registration_request: "
     1320                                                                "Found the #1b record "
     1321                                                                "with ip %s\n",
     1322                                                                inet_ntoa(name1brec->data.ip[0])));
     1323                                                        break;
     1324                                                }
     1325                                        }
     1326                                        if(!name1brec) {
     1327                                                DEBUG(3,("wins_process_name_registration_request: "
     1328                                                        "Didn't find a #1b name record. "
     1329                                                        "Removing the first available "
     1330                                                        "entry %s\n",
     1331                                                        inet_ntoa(namerec->data.ip[0])));
     1332                                                remove_ip_from_name_record(namerec, namerec->data.ip[0]);
     1333                                                wins_hook("delete", namerec, 0);
     1334                                        } else {
     1335                                                int i;
     1336                                                for(i=0; i<namerec->data.num_ips; i++) {
     1337                                                        /* The name1brec should only have
     1338                                                         * the single IP address in it,
     1339                                                         * so we only check against the first one*/
     1340                                                        if(!ip_equal_v4( namerec->data.ip[i], name1brec->data.ip[0])) {
     1341                                                                /* The i'th entry isn't the 1b address; delete it  */
     1342                                                                DEBUG(3,("wins_process_name_registration_request: "
     1343                                                                        "Entry at %d is not the #1b address. "
     1344                                                                        "About to remove it\n",
     1345                                                                        i));
     1346                                                                remove_ip_from_name_record(namerec, namerec->data.ip[i]);
     1347                                                                wins_hook("delete", namerec, 0);
     1348                                                                break;
     1349                                                        }
     1350                                                }
     1351                                        }
     1352                                }
     1353                                /* The list is guaranteed to be < 25 entries now
     1354                                 * - safe to add a new one  */
    12531355                                add_ip_to_name_record(namerec, from_ip);
    12541356                                /* we need to update the record for replication */
     
    18671969
    18681970        if(rcode == 0) {
     1971
     1972                int ip_count;
     1973
    18691974                ttl = (namerec->data.death_time != PERMANENT_TTL) ?  namerec->data.death_time - p->timestamp : lp_max_wins_ttl();
     1975
     1976                /* The netbios reply packet data section is limited to 576 bytes.  In theory
     1977                 * this should give us space for 96 addresses, but in practice, 86 appears
     1978                 * to be the max (don't know why).  If we send any more than that,
     1979                 * reply_netbios_packet will fail to send a reply to avoid a memcpy buffer
     1980                 * overflow.  Keep the count to 85 and it will be ok */
     1981                ip_count=namerec->data.num_ips;
     1982                if(ip_count>85) {
     1983                        ip_count=85;   
     1984                }
    18701985
    18711986                /* Copy all known ip addresses into the return data. */
    18721987                /* Optimise for the common case of one IP address so we don't need a malloc. */
    18731988
    1874                 if( namerec->data.num_ips == 1 ) {
     1989                if( ip_count == 1 ) {
    18751990                        prdata = rdata;
    18761991                } else {
    1877                         if((prdata = (char *)SMB_MALLOC( namerec->data.num_ips * 6 )) == NULL) {
     1992                        if((prdata = (char *)SMB_MALLOC( ip_count * 6 )) == NULL) {
    18781993                                DEBUG(0,("send_wins_name_query_response: malloc fail !\n"));
    18791994                                return;
     
    18811996                }
    18821997
    1883                 for(i = 0; i < namerec->data.num_ips; i++) {
     1998                for(i = 0; i < ip_count; i++) {
    18841999                        set_nb_flags(&prdata[i*6],namerec->data.nb_flags);
    18852000                        putip((char *)&prdata[2+(i*6)], &namerec->data.ip[i]);
     
    18872002
    18882003                sort_query_replies(prdata, i, p->ip);
    1889                 reply_data_len = namerec->data.num_ips * 6;
     2004                reply_data_len = ip_count * 6;
    18902005        }
    18912006
     
    20262141        struct name_record *namerec = NULL;
    20272142        struct in_addr from_ip;
    2028         bool releasing_group_name = (nb_flags & NB_GROUP) ? True : False;;
     2143        bool releasing_group_name = (nb_flags & NB_GROUP) ? True : False;
    20292144
    20302145        putip((char *)&from_ip,&nmb->additional->rdata[2]);
Note: See TracChangeset for help on using the changeset viewer.