You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
937 lines
38 KiB
937 lines
38 KiB
/***************************************************************************/
|
|
/* */
|
|
/* Project: OpenSLP - OpenSource implementation of Service Location */
|
|
/* Protocol Version 2 */
|
|
/* */
|
|
/* File: slpd_database.c */
|
|
/* */
|
|
/* Abstract: Implements database abstraction. Currently a simple */
|
|
/* double linked list (common/slp_database.c) is used for the */
|
|
/* underlying storage. */
|
|
/* */
|
|
/*-------------------------------------------------------------------------*/
|
|
/* */
|
|
/* Please submit patches to http://www.openslp.org */
|
|
/* */
|
|
/*-------------------------------------------------------------------------*/
|
|
/* */
|
|
/* Copyright (C) 2000 Caldera Systems, Inc */
|
|
/* All rights reserved. */
|
|
/* */
|
|
/* Redistribution and use in source and binary forms, with or without */
|
|
/* modification, are permitted provided that the following conditions are */
|
|
/* met: */
|
|
/* */
|
|
/* Redistributions of source code must retain the above copyright */
|
|
/* notice, this list of conditions and the following disclaimer. */
|
|
/* */
|
|
/* Redistributions in binary form must reproduce the above copyright */
|
|
/* notice, this list of conditions and the following disclaimer in */
|
|
/* the documentation and/or other materials provided with the */
|
|
/* distribution. */
|
|
/* */
|
|
/* Neither the name of Caldera Systems nor the names of its */
|
|
/* contributors may be used to endorse or promote products derived */
|
|
/* from this software without specific prior written permission. */
|
|
/* */
|
|
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
|
|
/* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
|
|
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
|
|
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA */
|
|
/* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
|
|
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
|
|
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */
|
|
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
|
|
/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
|
|
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */
|
|
/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
|
/* */
|
|
/***************************************************************************/
|
|
|
|
|
|
/*=========================================================================*/
|
|
/* slpd includes */
|
|
/*=========================================================================*/
|
|
#include "slpd_database.h"
|
|
#include "slpd_regfile.h"
|
|
#include "slpd_property.h"
|
|
#include "slpd_log.h"
|
|
#include "slpd_knownda.h"
|
|
#ifdef ENABLE_PREDICATES
|
|
#include "slpd_predicate.h"
|
|
#endif
|
|
|
|
|
|
/*=========================================================================*/
|
|
/* common code includes */
|
|
/*=========================================================================*/
|
|
#include "slp_compare.h"
|
|
#include "slp_xmalloc.h"
|
|
#include "slp_pid.h"
|
|
|
|
|
|
/*=========================================================================*/
|
|
SLPDDatabase G_SlpdDatabase;
|
|
/* slpd database global */
|
|
/*=========================================================================*/
|
|
|
|
|
|
/*=========================================================================*/
|
|
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 ||
|
|
srvreg->source == SLP_REG_SOURCE_STATIC )
|
|
{
|
|
/* entries that were made from local registrations */
|
|
/* and entries made from static registration file */
|
|
/* 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 entry */
|
|
srvreg->urlentry.lifetime -= seconds;
|
|
|
|
/* Remove entries that have timed out */
|
|
if ( srvreg->urlentry.lifetime <= 0 )
|
|
{
|
|
SLPDLogRegistration("Timeout",entry);
|
|
SLPDatabaseRemove(dh,entry);
|
|
}
|
|
}
|
|
|
|
SLPDatabaseClose(dh);
|
|
}
|
|
}
|
|
|
|
/*=========================================================================*/
|
|
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;
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
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 */
|
|
SLPDLogRegistration("Deregistration",entry);
|
|
SLPDatabaseRemove(dh,entry);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SLPDatabaseClose(dh);
|
|
|
|
if ( entry==NULL )
|
|
{
|
|
return SLP_ERROR_INVALID_REGISTRATION;
|
|
}
|
|
}
|
|
|
|
return 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;
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
void SLPDDatabaseSrvRqstEnd(SLPDDatabaseSrvRqstResult* result)
|
|
/* Find services in the database */
|
|
/* */
|
|
/* result (IN) pointer result structure previously passed to */
|
|
/* SLPDDatabaseSrvRqstStart */
|
|
/* */
|
|
/* Returns - None */
|
|
/*=========================================================================*/
|
|
{
|
|
if ( result )
|
|
{
|
|
SLPDatabaseClose((SLPDatabaseHandle)result->reserved);
|
|
xfree(result);
|
|
}
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
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;
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
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);
|
|
}
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
int SLPDDatabaseAttrRqstStart(SLPMessage msg,
|
|
SLPDDatabaseAttrRqstResult** result)
|
|
/* Find attributes in the database */
|
|
/* */
|
|
/* msg (IN) the AttrRqst to find. */
|
|
/* */
|
|
/* result (OUT) pointer result structure */
|
|
/* */
|
|
/* Returns - Zero on success. Non-zero on failure */
|
|
/* */
|
|
/* Note: Caller must pass *result to SLPDDatabaseAttrRqstEnd() to */
|
|
/* free */
|
|
/*=========================================================================*/
|
|
{
|
|
SLPDatabaseHandle dh;
|
|
SLPDatabaseEntry* entry;
|
|
SLPSrvReg* entryreg;
|
|
SLPAttrRqst* attrrqst;
|
|
#ifdef ENABLE_SLPv2_SECURITY
|
|
int i;
|
|
#endif
|
|
|
|
*result = xmalloc(sizeof(SLPDDatabaseAttrRqstResult));
|
|
if ( *result == NULL )
|
|
{
|
|
return SLP_ERROR_INTERNAL_ERROR;
|
|
}
|
|
memset(*result,0,sizeof(SLPDDatabaseAttrRqstResult));
|
|
|
|
dh = SLPDatabaseOpen(&G_SlpdDatabase.database);
|
|
if ( dh )
|
|
{
|
|
(*result)->reserved = dh;
|
|
|
|
/* attrrqst is the AttrRqst being made */
|
|
attrrqst = &(msg->body.attrrqst);
|
|
|
|
while ( 1 )
|
|
{
|
|
entry = SLPDatabaseEnum(dh);
|
|
if ( entry == NULL )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* entry reg is the SrvReg message from the database */
|
|
entryreg = &(entry->msg->body.srvreg);
|
|
|
|
|
|
if ( SLPCompareString(attrrqst->urllen,
|
|
attrrqst->url,
|
|
entryreg->urlentry.urllen,
|
|
entryreg->urlentry.url) == 0 ||
|
|
SLPCompareSrvType(attrrqst->urllen,
|
|
attrrqst->url,
|
|
entryreg->srvtypelen,
|
|
entryreg->srvtype) == 0 )
|
|
{
|
|
if ( SLPIntersectStringList(attrrqst->scopelistlen,
|
|
attrrqst->scopelist,
|
|
entryreg->scopelistlen,
|
|
entryreg->scopelist) )
|
|
{
|
|
if ( attrrqst->taglistlen == 0 )
|
|
{
|
|
#ifdef ENABLE_SLPv2_SECURITY
|
|
if ( attrrqst->spistrlen )
|
|
{
|
|
for ( i=0; i< entryreg->authcount;i++ )
|
|
{
|
|
if ( SLPCompareString(attrrqst->spistrlen,
|
|
attrrqst->spistr,
|
|
entryreg->autharray[i].spistrlen,
|
|
entryreg->autharray[i].spistr) == 0 )
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if ( i == entryreg->authcount )
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
#endif
|
|
/* Send back what was registered */
|
|
(*result)->attrlistlen = entryreg->attrlistlen;
|
|
(*result)->attrlist = (char*)entryreg->attrlist;
|
|
(*result)->authcount = entryreg->authcount;
|
|
(*result)->autharray = entryreg->autharray;
|
|
}
|
|
#ifdef ENABLE_PREDICATES
|
|
else
|
|
{
|
|
/* Send back a partial list as specified by taglist */
|
|
if ( SLPDFilterAttributes(entryreg->attrlistlen,
|
|
entryreg->attrlist,
|
|
attrrqst->taglistlen,
|
|
attrrqst->taglist,
|
|
&(*result)->attrlistlen,
|
|
&(*result)->attrlist) == 0 )
|
|
{
|
|
(*result)->ispartial = 1;
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
void SLPDDatabaseAttrRqstEnd(SLPDDatabaseAttrRqstResult* result)
|
|
/* Release resources used to find attributes in the database */
|
|
/* */
|
|
/* result (IN) pointer result structure previously passed to */
|
|
/* SLPDDatabaseSrvTypeRqstStart */
|
|
/* */
|
|
/* Returns - None */
|
|
/*=========================================================================*/
|
|
{
|
|
if ( result )
|
|
{
|
|
SLPDatabaseClose((SLPDatabaseHandle)result->reserved);
|
|
if ( result->ispartial && result->attrlist ) free(result->attrlist);
|
|
xfree(result);
|
|
}
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
void* SLPDDatabaseEnumStart()
|
|
/* Start an enumeration of the entire database */
|
|
/* */
|
|
/* Returns: An enumeration handle that is passed to subsequent calls to */
|
|
/* SLPDDatabaseEnum(). Returns NULL on failure. Returned */
|
|
/* enumeration handle (if not NULL) must be passed to */
|
|
/* SLPDDatabaseEnumEnd() when you are done with it. */
|
|
/*=========================================================================*/
|
|
{
|
|
return SLPDatabaseOpen(&G_SlpdDatabase.database);
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
SLPMessage SLPDDatabaseEnum(void* eh, SLPMessage* msg, SLPBuffer* buf)
|
|
/* Enumerate through all entries of the database */
|
|
/* */
|
|
/* eh (IN) pointer to opaque data that is used to maintain */
|
|
/* enumerate entries. Pass in a pointer to NULL to start */
|
|
/* enumeration. */
|
|
/* */
|
|
/* msg (OUT) pointer to the SrvReg message that discribes buf */
|
|
/* */
|
|
/* buf (OUT) pointer to the SrvReg message buffer */
|
|
/* */
|
|
/* returns: Pointer to enumerated entry or NULL if end of enumeration */
|
|
/*=========================================================================*/
|
|
{
|
|
SLPDatabaseEntry* entry;
|
|
entry = SLPDatabaseEnum((SLPDatabaseHandle) eh);
|
|
if ( entry )
|
|
{
|
|
*msg = entry->msg;
|
|
*buf = entry->buf;
|
|
}
|
|
else
|
|
{
|
|
*msg = 0;
|
|
*buf = 0;
|
|
}
|
|
|
|
return *msg;
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
void SLPDDatabaseEnumEnd(void* eh)
|
|
/* End an enumeration started by SLPDDatabaseEnumStart() */
|
|
/* */
|
|
/* Parameters: eh (IN) The enumeration handle returned by */
|
|
/* SLPDDatabaseEnumStart() */
|
|
/*=========================================================================*/
|
|
{
|
|
if ( eh )
|
|
{
|
|
SLPDatabaseClose((SLPDatabaseHandle)eh);
|
|
}
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
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;
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
int SLPDDatabaseInit(const char* regfile)
|
|
/* Initialize the database with registrations from a regfile. */
|
|
/* */
|
|
/* regfile (IN) the regfile to register. Pass in NULL for no regfile */
|
|
/* */
|
|
/* Returns - zero on success or non-zero on error. */
|
|
/*=========================================================================*/
|
|
{
|
|
|
|
/* Set initial values */
|
|
memset(&G_SlpdDatabase,0,sizeof(G_SlpdDatabase));
|
|
G_SlpdDatabase.urlcount = SLPDDATABASE_INITIAL_URLCOUNT;
|
|
G_SlpdDatabase.srvtypelistlen = SLPDDATABASE_INITIAL_SRVTYPELISTLEN;
|
|
SLPDatabaseInit(&G_SlpdDatabase.database);
|
|
|
|
/* Call the reinit function */
|
|
return SLPDDatabaseReInit(regfile);
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
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;
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
/*=========================================================================*/
|
|
void SLPDDatabaseDeinit(void)
|
|
/* Cleans up all resources used by the database */
|
|
/*=========================================================================*/
|
|
{
|
|
SLPDatabaseDeinit(&G_SlpdDatabase.database);
|
|
}
|
|
|
|
|
|
/*=========================================================================*/
|
|
void SLPDDatabaseDump(void)
|
|
/* Dumps currently valid service registrations present with slpd */
|
|
/*=========================================================================*/
|
|
{
|
|
SLPMessage msg;
|
|
SLPBuffer buf;
|
|
void* eh;
|
|
|
|
eh = SLPDDatabaseEnumStart();
|
|
if ( eh )
|
|
{
|
|
SLPDLog("\n========================================================================\n");
|
|
SLPDLog("Dumping Registrations\n");
|
|
SLPDLog("========================================================================\n");
|
|
while ( SLPDDatabaseEnum(eh, &msg, &buf) )
|
|
{
|
|
SLPDLogMessageInternals(msg);
|
|
SLPDLog("\n");
|
|
}
|
|
|
|
SLPDDatabaseEnumEnd(eh);
|
|
}
|
|
}
|
|
#endif
|