Esempio n. 1
0
/*=========================================================================*/
void KnownDABadDA(struct in_addr* daaddr)
/* Mark a KnownDA as a Bad DA.                                             */
/*                                                                         */
/* daaddr (IN) address of the bad DA                                       */
/*                                                                         */
/* Returns: none                                                           */
/*=========================================================================*/
{
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    
    dh = SLPDatabaseOpen(&G_KnownDACache);
    if(dh)
    {
        /*-----------------------------------*/
        /* Check to find the requested entry */
        /*-----------------------------------*/
        while(1)
        {
            entry = SLPDatabaseEnum(dh);
            if(entry == NULL) break;
            
            /* Assume DAs are identical if their in_addrs match */
            if(memcmp(daaddr,&(entry->msg->peer.sin_addr),sizeof(struct in_addr)) == 0)
            {
                SLPDatabaseRemove(dh,entry);
                break;            
            }
        }

        SLPDatabaseClose(dh);
    }
}
Esempio n. 2
0
/*=========================================================================*/
void KnownDAFreeAll()
/* Frees all (cached) resources associated with known DAs                  */
/*                                                                         */
/* returns: none                                                           */
/*=========================================================================*/
{
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    dh = SLPDatabaseOpen(&G_KnownDACache);
    if(dh)
    {
        while(1)
        {
            entry = SLPDatabaseEnum(dh);
            if(entry == NULL) break;
            
            SLPDatabaseRemove(dh,entry);
        }

        SLPDatabaseClose(dh);
    }
    G_KnownDAScopesLen = 0;
    
    if(G_KnownDAScopes) xfree(G_KnownDAScopes);
}
Esempio n. 3
0
/*-------------------------------------------------------------------------*/
int KnownDAAdd(SLPMessage msg, SLPBuffer buf)
/* Add an entry to the KnownDA cache                                       */
/*                                                                         */
/* Returns: zero on success, non-zero on error                             */
/*-------------------------------------------------------------------------*/
{
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    SLPDAAdvert*        entrydaadvert;
    SLPDAAdvert*        daadvert;
    int                 result;

    result = 0;

    dh = SLPDatabaseOpen(&G_KnownDACache);
    if(dh)
    {
        /* daadvert is the DAAdvert message being added */
        daadvert = &(msg->body.daadvert);
    
        /*-----------------------------------------------------*/
        /* Check to see if there is already an identical entry */
        /*-----------------------------------------------------*/
        while(1)
        {
            entry = SLPDatabaseEnum(dh);
            if(entry == NULL) break;
            
            /* entrydaadvert is the DAAdvert message from the database */
            entrydaadvert = &(entry->msg->body.daadvert);

            /* Assume DAs are identical if their URLs match */
            if(SLPCompareString(entrydaadvert->urllen,
                                entrydaadvert->url,
                                daadvert->urllen,
                                daadvert->url) == 0)
            {
                SLPDatabaseRemove(dh,entry);
                break;
            }
        }

        /* Create and link in a new entry */
        entry = SLPDatabaseEntryCreate(msg,buf);
        if(entry)
        {
            SLPDatabaseAdd(dh, entry);
        }
        else
        {
            result = SLP_MEMORY_ALLOC_FAILED;
        }
        
        SLPDatabaseClose(dh);
    }
        
    return result;
}
Esempio n. 4
0
/*=========================================================================*/
void SLPDDatabaseEnumEnd(void* eh)
/* End an enumeration started by SLPDDatabaseEnumStart()                   */
/*                                                                         */
/* Parameters:  eh (IN) The enumeration handle returned by                 */
/*              SLPDDatabaseEnumStart()                                    */
/*=========================================================================*/
{
    if ( eh )
    {
        SLPDatabaseClose((SLPDatabaseHandle)eh);
    }
}
Esempio n. 5
0
/*=========================================================================*/
int SLPDDatabaseReInit(const char* regfile)
/* Re-initialize the database with changed registrations from a regfile.   */
/*                                                                         */
/* regfile  (IN)    the regfile to register.                               */
/*                                                                         */
/* Returns  - zero on success or non-zero on error.                        */
/*=========================================================================*/
{
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    SLPMessage          msg;
    SLPBuffer           buf;
    FILE*               fd;

    /*------------------------------------------------------------------*/
    /* open the database handle and remove all the static registrations */
    /* (the registrations from the /etc/slp.reg) file.                  */
    /*------------------------------------------------------------------*/
    dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
    if ( dh )
    {
        while ( 1 )
        {
            entry = SLPDatabaseEnum(dh);
            if ( entry == NULL ) break;

            if ( entry->msg->body.srvreg.source == SLP_REG_SOURCE_STATIC )
            {
                SLPDatabaseRemove(dh,entry);
            }
        }
        SLPDatabaseClose(dh);
    }

    /*--------------------------------------*/
    /* Read static registration file if any */
    /*--------------------------------------*/
    if ( regfile )
    {
        fd = fopen(regfile,"rb");
        if ( fd )
        {
            while ( SLPDRegFileReadSrvReg(fd, &msg, &buf) == 0 )
            {
                SLPDDatabaseReg(msg, buf);
            }   

            fclose(fd);
        }
    }

    return 0;
}
Esempio n. 6
0
/*-------------------------------------------------------------------------*/
SLPBoolean KnownDAListFind(int scopelistlen,
                           const char* scopelist,
                           int spistrlen,
                           const char* spistr,
                           struct in_addr* daaddr)
/* Returns: non-zero on success, zero if DA can not be found               */
/*-------------------------------------------------------------------------*/
{
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    int result = SLP_FALSE;
   
    dh = SLPDatabaseOpen(&G_KnownDACache);
    if(dh)
    {
        /*----------------------------------------*/
        /* Check to see if there a matching entry */
        /*----------------------------------------*/
        while(1)
        {
            entry = SLPDatabaseEnum(dh);
            if(entry == NULL) break;
            
            /* Check scopes */
            if(SLPSubsetStringList(entry->msg->body.daadvert.scopelistlen,
                                   entry->msg->body.daadvert.scopelist,
                                   scopelistlen,
                                   scopelist))
            {
#ifdef ENABLE_SLPv2_SECURITY
                if(SLPCompareString(entry->msg->body.daadvert.spilistlen,
                                    entry->msg->body.daadvert.spilist,
                                    spistrlen,
                                    spistr) == 0)
#endif
                {
                    
                    memcpy(daaddr, 
                           &(entry->msg->peer.sin_addr),
                           sizeof(struct in_addr));
    
                    result = SLP_TRUE;
                }
            }
        }
        SLPDatabaseClose(dh);
    }

    return result;
}
Esempio n. 7
0
/*=========================================================================*/
int SLPDDatabaseIsEmpty()
/* Returns an boolean value indicating whether the database is empty       */
/*=========================================================================*/
{
    int result = 1;

    SLPDatabaseHandle dh;
    dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
    {
        result = SLPDatabaseCount(dh) == 0;
        SLPDatabaseClose(dh);
    }
    return result;
}
Esempio n. 8
0
/*=========================================================================*/
void SLPDDatabaseSrvTypeRqstEnd(SLPDDatabaseSrvTypeRqstResult* result)
/* Release resources used to find service types in the database            */
/*                                                                         */
/* result   (IN) pointer result structure previously passed to             */
/*               SLPDDatabaseSrvTypeRqstStart                              */
/*                                                                         */
/* Returns  - None                                                         */
/*=========================================================================*/
{
    if ( result )
    {
        SLPDatabaseClose((SLPDatabaseHandle)result->reserved);
        xfree(result);
    }
}
Esempio n. 9
0
/*=========================================================================*/
int KnownDAGetScopes(int* scopelistlen,
                     char** scopelist)
/* Gets a list of scopes from the known DA list                            */
/*                                                                         */
/* scopelistlen (OUT) stringlen of the scopelist                           */
/*                                                                         */
/* scopelist (OUT) NULL terminated list of scopes                          */
/*                                                                         */
/* returns: zero on success, non-zero on failure                           */
/*=========================================================================*/
{
    int                 newlen;
    time_t              curtime;
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    
    /* Refresh the cache if necessary */
    curtime = time(&curtime);
    if(G_KnownDALastCacheRefresh == 0 ||
       curtime - G_KnownDALastCacheRefresh > MINIMUM_DISCOVERY_INTERVAL)
    {
        G_KnownDALastCacheRefresh = curtime;

        /* discover DAs */
        if(KnownDADiscoverFromIPC() == 0)
        {
            KnownDADiscoverFromDHCP();
            KnownDADiscoverFromProperties();
            KnownDADiscoverFromMulticast(0,"");
        }
    }

    /* enumerate through all the knownda entries and generate a */
    /* scopelist                                                */
    dh = SLPDatabaseOpen(&G_KnownDACache);
    if(dh)
    {
        /*-----------------------------------*/
        /* Check to find the requested entry */
        /*-----------------------------------*/
        while(1)
        {
            entry = SLPDatabaseEnum(dh);
            if(entry == NULL) break;
            newlen = G_KnownDAScopesLen;
            while(SLPUnionStringList(G_KnownDAScopesLen,
                                     G_KnownDAScopes,
                                     entry->msg->body.daadvert.scopelistlen,
                                     entry->msg->body.daadvert.scopelist,
                                     &newlen,
                                     G_KnownDAScopes) < 0)
            {
                G_KnownDAScopes = xrealloc(G_KnownDAScopes,newlen);
                if(G_KnownDAScopes == 0)
                {
                    G_KnownDAScopesLen = 0;
                    break;
                }
            }
            G_KnownDAScopesLen = newlen;

        }

        SLPDatabaseClose(dh);
    }

    /* Explicitly add in the useScopes property */
    newlen = G_KnownDAScopesLen;
    while(SLPUnionStringList(G_KnownDAScopesLen,
                             G_KnownDAScopes,
                             strlen(SLPPropertyGet("net.slp.useScopes")),
                             SLPPropertyGet("net.slp.useScopes"),
                             &newlen,
                             G_KnownDAScopes) < 0)
    {
        G_KnownDAScopes = xrealloc(G_KnownDAScopes,newlen);
        if(G_KnownDAScopes == 0)
        {
            G_KnownDAScopesLen = 0;
            break;
        }
    }
    G_KnownDAScopesLen = newlen;


    if(G_KnownDAScopesLen)
    {
        *scopelist = xmalloc(G_KnownDAScopesLen + 1);
        if(*scopelist == 0)
        {
            return -1;
        }
        memcpy(*scopelist,G_KnownDAScopes, G_KnownDAScopesLen);
        (*scopelist)[G_KnownDAScopesLen] = 0; 
        *scopelistlen = G_KnownDAScopesLen;
    }
    else
    {
        *scopelist = xstrdup("");
        if(*scopelist == 0)
        {
            return -1;
        }
        *scopelistlen = 0; 
    }

    return 0;
}
Esempio n. 10
0
/*=========================================================================*/
void SLPDDatabaseAge(int seconds, int ageall)
/* Ages the database entries and clears new and deleted entry lists        */
/*                                                                         */
/* seconds  (IN) the number of seconds to age each entry by                */
/*																		   */
/* ageall   (IN) age even entries with SLP_LIFETIME_MAXIMUM                */
/*                                                                         */
/* Returns  - None                                                         */
/*=========================================================================*/
{
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    SLPSrvReg*          srvreg;

    dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
    if ( dh )
    {
        while ( 1 )
        {
            entry = SLPDatabaseEnum(dh);
            if ( entry == NULL ) break;

            /* srvreg is the SrvReg message from the database */
            srvreg = &(entry->msg->body.srvreg);

            if ( srvreg->urlentry.lifetime == SLP_LIFETIME_MAXIMUM )
            {
                if ( srvreg->source == SLP_REG_SOURCE_LOCAL )
                {
                    /* entries that were made from local registrations    */
                    /* that have a lifetime of SLP_LIFETIME_MAXIMUM must  */
                    /* NEVER be aged                                      */
                    continue;
                }

                if ( ageall == 0 )
                {
                    /* Don't age any services that have a lifetime of     */
                    /* SLP_LIFETIME_MAXIMUM unless explicitly told to     */
                    continue;
                }
            }

            /* Age entries by seconds */
            srvreg->urlentry.lifetime -= seconds;

            /* Age local entries to death when registering pid disappears */
            if(srvreg->source == SLP_REG_SOURCE_LOCAL && srvreg->pid)
            {
                /* Send benign signal to process (don't worry, chances are 
                 * that we'll get an EPERM since we've droped root 
                 * permissions)
                 */
                if(SLPPidExists(srvreg->pid))
                {
                    srvreg->urlentry.lifetime = 0;
                    SLPDKnownDADeRegisterWithAllDas(entry->msg,entry->buf);
                }
            }

            /* Remove entries that have timed out */
            if ( srvreg->urlentry.lifetime <= 0 )
            {
                SLPDatabaseRemove(dh,entry);
                SLPDLogRegistration("Timeout",entry);
            }
        }

        SLPDatabaseClose(dh);
    }
}
Esempio n. 11
0
/*=========================================================================*/
int SLPDDatabaseSrvTypeRqstStart(SLPMessage msg,
                                 SLPDDatabaseSrvTypeRqstResult** result)
/* Find service types in the database                                      */
/*                                                                         */
/* msg      (IN) the SrvTypRqst to find.                                   */
/*                                                                         */
/* result   (OUT) pointer result structure                                 */
/*                                                                         */
/* Returns  - Zero on success. Non-zero on failure                         */
/*                                                                         */
/* Note:    Caller must pass *result to SLPDDatabaseSrvtypeRqstEnd() to    */
/*          free                                                           */
/*=========================================================================*/
{
    SLPDatabaseHandle           dh;
    SLPDatabaseEntry*           entry;
    SLPSrvReg*                  entryreg;
    SLPSrvTypeRqst*             srvtyperqst;

    dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
    if ( dh )
    {
        /* srvtyperqst is the SrvTypeRqst being made */
        srvtyperqst = &(msg->body.srvtyperqst);

        while ( 1 )
        {
            /*-----------------------------------------------------------------*/
            /* Allocate result with generous srvtypelist of url entry pointers */
            /*-----------------------------------------------------------------*/
            *result = (SLPDDatabaseSrvTypeRqstResult*) xrealloc(*result, sizeof(SLPDDatabaseSrvTypeRqstResult) + G_SlpdDatabase.srvtypelistlen);
            if ( *result == NULL )
            {
                /* out of memory */
                SLPDatabaseClose(dh);
                return SLP_ERROR_INTERNAL_ERROR;
            }
            (*result)->srvtypelist = (char*)((*result) + 1);
            (*result)->srvtypelistlen = 0;
            (*result)->reserved = dh;

            /*-------------------------------------------------*/
            /* Rewind enumeration in case we had to reallocate */
            /*-------------------------------------------------*/
            SLPDatabaseRewind(dh);

            while ( 1 )
            {
                entry = SLPDatabaseEnum(dh);
                if ( entry == NULL )
                {
                    /* This is the only successful way out */
                    return 0;
                }

                /* entry reg is the SrvReg message from the database */
                entryreg = &(entry->msg->body.srvreg);

                if ( SLPCompareNamingAuth(entryreg->srvtypelen,
                                          entryreg->srvtype,
                                          srvtyperqst->namingauthlen,
                                          srvtyperqst->namingauth) == 0 && 
                     SLPIntersectStringList(srvtyperqst->scopelistlen,
                                            srvtyperqst->scopelist,
                                            entryreg->scopelistlen,
                                            entryreg->scopelist) &&
                     SLPContainsStringList((*result)->srvtypelistlen, 
                                           (*result)->srvtypelist,
                                           entryreg->srvtypelen,
                                           entryreg->srvtype) == 0 )
                {
                    /* Check to see if we allocated a big enough srvtypelist */
                    if ( (*result)->srvtypelistlen + entryreg->srvtypelen > G_SlpdDatabase.srvtypelistlen )
                    {
                        /* Oops we did not allocate a big enough result */
                        G_SlpdDatabase.srvtypelistlen *= 2;
                        break;
                    }

                    /* Append a comma if needed */
                    if ( (*result)->srvtypelistlen )
                    {
                        (*result)->srvtypelist[(*result)->srvtypelistlen] = ',';
                        (*result)->srvtypelistlen += 1;
                    }
                    /* Append the service type */
                    memcpy(((*result)->srvtypelist) + (*result)->srvtypelistlen,
                           entryreg->srvtype,
                           entryreg->srvtypelen);
                    (*result)->srvtypelistlen += entryreg->srvtypelen;
                }
            }
        }

        SLPDatabaseClose(dh);
    }

    return 0;
}
Esempio n. 12
0
/*=========================================================================*/
int SLPDDatabaseSrvRqstStart(SLPMessage msg,
                             SLPDDatabaseSrvRqstResult** result)
/* Find services in the database                                           */
/*                                                                         */
/* msg      (IN) the SrvRqst to find.                                      */
/*                                                                         */
/* result   (OUT) pointer result structure                                 */
/*                                                                         */
/* Returns  - Zero on success. Non-zero on failure                         */
/*                                                                         */
/* Note:    Caller must pass *result to SLPDDatabaseSrvRqstEnd() to free   */
/*=========================================================================*/
{
    SLPDatabaseHandle           dh;
    SLPDatabaseEntry*           entry;
    SLPSrvReg*                  entryreg;
    SLPSrvRqst*                 srvrqst;
#ifdef ENABLE_SLPv2_SECURITY
    int                         i;
#endif


    /* start with the result set to NULL just to be safe */
    *result = NULL;

    dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
    if ( dh )
    {
        /* srvrqst is the SrvRqst being made */
        srvrqst = &(msg->body.srvrqst);

        while ( 1 )
        {
            /*-----------------------------------------------------------*/
            /* Allocate result with generous array of url entry pointers */
            /*-----------------------------------------------------------*/
            *result = (SLPDDatabaseSrvRqstResult*) xrealloc(*result, sizeof(SLPDDatabaseSrvRqstResult) + (sizeof(SLPUrlEntry*) * G_SlpdDatabase.urlcount));
            if ( *result == NULL )
            {
                /* out of memory */
                SLPDatabaseClose(dh);
                return SLP_ERROR_INTERNAL_ERROR;
            }
            (*result)->urlarray = (SLPUrlEntry**)((*result) + 1);
            (*result)->urlcount = 0;
            (*result)->reserved = dh;

            /*-------------------------------------------------*/
            /* Rewind enumeration in case we had to reallocate */
            /*-------------------------------------------------*/
            SLPDatabaseRewind(dh);

            /*-----------------------------------------*/
            /* Check to see if there is matching entry */
            /*-----------------------------------------*/
            while ( 1 )
            {
                entry = SLPDatabaseEnum(dh);
                if ( entry == NULL )
                {
                    /* This is the only successful way out */
                    return 0;
                }

                /* entry reg is the SrvReg message from the database */
                entryreg = &(entry->msg->body.srvreg);

                /* check the service type */
                if ( SLPCompareSrvType(srvrqst->srvtypelen,
                                       srvrqst->srvtype,
                                       entryreg->srvtypelen,
                                       entryreg->srvtype) == 0 &&
                     SLPIntersectStringList(entryreg->scopelistlen,
                                            entryreg->scopelist,
                                            srvrqst->scopelistlen,
                                            srvrqst->scopelist) > 0 )
                {
#ifdef ENABLE_PREDICATES
                    if ( SLPDPredicateTest(msg->header.version,
                                           entryreg->attrlistlen,
                                           entryreg->attrlist,
                                           srvrqst->predicatelen,
                                           srvrqst->predicate) )
#endif
                    {

#ifdef ENABLE_SLPv2_SECURITY
                        if ( srvrqst->spistrlen )
                        {
                            for ( i=0; i< entryreg->urlentry.authcount;i++ )
                            {
                                if ( SLPCompareString(srvrqst->spistrlen,
                                                      srvrqst->spistr,
                                                      entryreg->urlentry.autharray[i].spistrlen,
                                                      entryreg->urlentry.autharray[i].spistr) == 0 )
                                {
                                    break;
                                }
                            }
                            if ( i == entryreg->urlentry.authcount )
                            {
                                continue;
                            }
                        }
#endif
                        if ( (*result)->urlcount + 1 > G_SlpdDatabase.urlcount )
                        {
                            /* Oops we did not allocate a big enough result */
                            G_SlpdDatabase.urlcount *= 2;
                            break;
                        }

                        (*result)->urlarray[(*result)->urlcount] = &(entryreg->urlentry);
                        (*result)->urlcount ++;
                    }
                }
            }
        }
    }

    return 0;
}
Esempio n. 13
0
/*=========================================================================*/
int SLPDDatabaseDeReg(SLPMessage msg)
/* Remove a service registration from the database                         */
/*                                                                         */
/* msg  - (IN) message interpreting an SrvDereg message                    */
/*                                                                         */
/* Returns  -   Zero on success.  Non-zero on failure                      */
/*=========================================================================*/
{
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    SLPSrvReg*          entryreg;
    SLPSrvDeReg*        dereg;

    dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
    if ( dh )
    {
        /* dereg is the SrvDereg being deregistered */
        dereg = &(msg->body.srvdereg);

        /*---------------------------------------------*/
        /* Check to see if there is an identical entry */
        /*---------------------------------------------*/
        while ( 1 )
        {
            entry = SLPDatabaseEnum(dh);
            if ( entry == NULL ) break;

            /* entry reg is the SrvReg message from the database */
            entryreg = &(entry->msg->body.srvreg);

            if ( SLPCompareString(entryreg->urlentry.urllen,
                                  entryreg->urlentry.url,
                                  dereg->urlentry.urllen,
                                  dereg->urlentry.url) == 0 )
            {
                if ( SLPIntersectStringList(entryreg->scopelistlen,
                                            entryreg->scopelist,
                                            dereg->scopelistlen,
                                            dereg->scopelist) > 0 )
                {

                    /* Check to ensure the source addr is the same as */
                    /* the original */
                    if ( G_SlpdProperty.checkSourceAddr &&
                         memcmp(&(entry->msg->peer.sin_addr),
                                &(msg->peer.sin_addr),
                                sizeof(struct in_addr)) )
                    {
                        SLPDatabaseClose(dh);
                        return SLP_ERROR_AUTHENTICATION_FAILED;
                    }

#ifdef ENABLE_SLPv2_SECURITY
                    if ( entryreg->urlentry.authcount &&
                         entryreg->urlentry.authcount != dereg->urlentry.authcount )
                    {
                        SLPDatabaseClose(dh);
                        return SLP_ERROR_AUTHENTICATION_FAILED;
                    }
#endif                    
                    /* remove the registration from the database */
                    SLPDatabaseRemove(dh,entry);                   
                    SLPDLogRegistration("Deregistration",entry);
                    break;
                }
            }
        }

        SLPDatabaseClose(dh);

        if ( entry==NULL )
        {
            return SLP_ERROR_INVALID_REGISTRATION;
        }
    }

    return 0;
}
Esempio n. 14
0
/*=========================================================================*/
int SLPDDatabaseReg(SLPMessage msg, SLPBuffer buf)
/* Add a service registration to the database                              */
/*                                                                         */
/* msg          (IN) SLPMessage of a SrvReg message as returned by         */
/*                   SLPMessageParse()                                     */
/*                                                                         */
/* buf          (IN) Otherwise unreferenced buffer interpreted by the msg  */
/*                   structure                                             */
/*                                                                         */
/* Returns  -   Zero on success.  Nonzero on error                         */
/*                                                                         */
/* NOTE:        All registrations are treated as fresh                     */
/*=========================================================================*/
{
    SLPDatabaseHandle   dh;
    SLPDatabaseEntry*   entry;
    SLPSrvReg*          entryreg;
    SLPSrvReg*          reg;
    int                 result;

    /* reg is the SrvReg message being registered */
    reg = &(msg->body.srvreg);

    /* check service-url syntax */
    if ( SLPCheckServiceUrlSyntax(reg->urlentry.url, reg->urlentry.urllen) )
    {
        return SLP_ERROR_INVALID_REGISTRATION;
    }

    /* check attr-list syntax */
    if ( reg->attrlistlen &&
         SLPCheckAttributeListSyntax(reg->attrlist,reg->attrlistlen) )
    {
        return SLP_ERROR_INVALID_REGISTRATION;
    }

    dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
    if ( dh )
    {
        /*-----------------------------------------------------*/
        /* Check to see if there is already an identical entry */
        /*-----------------------------------------------------*/
        while ( 1 )
        {
            entry = SLPDatabaseEnum(dh);
            if ( entry == NULL ) break;

            /* entry reg is the SrvReg message from the database */
            entryreg = &(entry->msg->body.srvreg);

            if ( SLPCompareString(entryreg->urlentry.urllen,
                                  entryreg->urlentry.url,
                                  reg->urlentry.urllen,
                                  reg->urlentry.url) == 0 )
            {
                if ( SLPIntersectStringList(entryreg->scopelistlen,
                                            entryreg->scopelist,
                                            reg->scopelistlen,
                                            reg->scopelist) > 0 )
                {

                    /* Check to ensure the source addr is the same */
                    /* as the original */
                    if ( G_SlpdProperty.checkSourceAddr &&
                         memcmp(&(entry->msg->peer.sin_addr),
                                &(msg->peer.sin_addr),
                                sizeof(struct in_addr)) )
                    {
                        SLPDatabaseClose(dh);
                        return SLP_ERROR_AUTHENTICATION_FAILED;
                    }

#ifdef ENABLE_SLPv2_SECURITY
                    if ( entryreg->urlentry.authcount &&
                         entryreg->urlentry.authcount != reg->urlentry.authcount )
                    {
                        SLPDatabaseClose(dh);
                        return SLP_ERROR_AUTHENTICATION_FAILED;
                    }
#endif  
                    /* Remove the identical entry */
                    SLPDatabaseRemove(dh,entry);
                    break;
                }
            }
        }

        /*------------------------------------*/
        /* Add the new srvreg to the database */
        /*------------------------------------*/
        entry = SLPDatabaseEntryCreate(msg,buf);
        if ( entry )
        {
            /* set the source (allows for quicker aging ) */
            if ( msg->body.srvreg.source == SLP_REG_SOURCE_UNKNOWN )
            {
                if ( ISLOCAL(msg->peer.sin_addr) )
                {
                    msg->body.srvreg.source = SLP_REG_SOURCE_LOCAL; 
                }
                else
                {
                    msg->body.srvreg.source = SLP_REG_SOURCE_REMOTE;     
                }
            }

            /* add to database */
            SLPDatabaseAdd(dh, entry);
            SLPDLogRegistration("Registration",entry);

            /* SUCCESS! */
            result = 0;
        }
        else
        {
            result = SLP_ERROR_INTERNAL_ERROR;
        }

        SLPDatabaseClose(dh);
    }
    else
    {
        result = SLP_ERROR_INTERNAL_ERROR;
    }

    return result;
}