Last sec draft std adjustment
[shibboleth/sp.git] / shib / shib.h
1 /*
2  * The Shibboleth License, Version 1.
3  * Copyright (c) 2002
4  * University Corporation for Advanced Internet Development, Inc.
5  * All rights reserved
6  *
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright notice, this
12  * list of conditions and the following disclaimer.
13  *
14  * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution, if any, must include
17  * the following acknowledgment: "This product includes software developed by
18  * the University Corporation for Advanced Internet Development
19  * <http://www.ucaid.edu>Internet2 Project. Alternately, this acknowledegement
20  * may appear in the software itself, if and wherever such third-party
21  * acknowledgments normally appear.
22  *
23  * Neither the name of Shibboleth nor the names of its contributors, nor
24  * Internet2, nor the University Corporation for Advanced Internet Development,
25  * Inc., nor UCAID may be used to endorse or promote products derived from this
26  * software without specific prior written permission. For written permission,
27  * please contact shibboleth@shibboleth.org
28  *
29  * Products derived from this software may not be called Shibboleth, Internet2,
30  * UCAID, or the University Corporation for Advanced Internet Development, nor
31  * may Shibboleth appear in their name, without prior written permission of the
32  * University Corporation for Advanced Internet Development.
33  *
34  *
35  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
36  * AND WITH ALL FAULTS. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
38  * PARTICULAR PURPOSE, AND NON-INFRINGEMENT ARE DISCLAIMED AND THE ENTIRE RISK
39  * OF SATISFACTORY QUALITY, PERFORMANCE, ACCURACY, AND EFFORT IS WITH LICENSEE.
40  * IN NO EVENT SHALL THE COPYRIGHT OWNER, CONTRIBUTORS OR THE UNIVERSITY
41  * CORPORATION FOR ADVANCED INTERNET DEVELOPMENT, INC. BE LIABLE FOR ANY DIRECT,
42  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
43  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
47  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  */
49
50
51 /* shib.h - Shibboleth header file
52
53    Scott Cantor
54    6/4/02
55
56    $History:$
57 */
58
59 #ifndef __shib_h__
60 #define __shib_h__
61
62 #include <saml/saml.h>
63 #include <shib/shib-threads.h>
64
65 #ifdef WIN32
66 # ifndef SHIB_EXPORTS
67 #  define SHIB_EXPORTS __declspec(dllimport)
68 # endif
69 #else
70 # define SHIB_EXPORTS
71 #endif
72
73 namespace shibboleth
74 {
75     #define DECLARE_SHIB_EXCEPTION(name,base) \
76         class SHIB_EXPORTS name : public saml::base \
77         { \
78         public: \
79             name(const char* msg) : saml::base(msg) {RTTI(name);} \
80             name(const std::string& msg) : saml::base(msg) {RTTI(name);} \
81             name(const saml::Iterator<saml::QName>& codes, const char* msg) : saml::base(codes,msg) {RTTI(name);} \
82             name(const saml::Iterator<saml::QName>& codes, const std::string& msg) : saml::base(codes, msg) {RTTI(name);} \
83             name(const saml::QName& code, const char* msg) : saml::base(code,msg) {RTTI(name);} \
84             name(const saml::QName& code, const std::string& msg) : saml::base(code, msg) {RTTI(name);} \
85             name(DOMElement* e) : saml::base(e) {RTTI(name);} \
86             name(std::istream& in) : saml::base(in) {RTTI(name);} \
87             virtual ~name() throw () {} \
88         }
89
90     DECLARE_SHIB_EXCEPTION(MetadataException,SAMLException);
91     DECLARE_SHIB_EXCEPTION(CredentialException,SAMLException);
92     DECLARE_SHIB_EXCEPTION(InvalidHandleException,RetryableProfileException);
93
94     // Manages pluggable implementations of interfaces
95     // Would prefer this to be a template, but the Windows STL isn't DLL-safe.
96
97     struct SHIB_EXPORTS IPlugIn
98     {
99         virtual ~IPlugIn() {}
100     };
101
102     class SHIB_EXPORTS PlugManager
103     {
104     public:
105         PlugManager() {}
106         ~PlugManager() {}
107
108         typedef IPlugIn* Factory(const DOMElement* source);
109         void regFactory(const char* type, Factory* factory);
110         void unregFactory(const char* type);
111         IPlugIn* newPlugin(const char* type, const DOMElement* source);
112
113     private:
114         typedef std::map<std::string, Factory*> FactoryMap;
115         FactoryMap m_map;
116     };
117
118     // Metadata abstract interfaces, inching toward SAML 2.0...
119     
120     struct SHIB_EXPORTS ILockable
121     {
122         virtual void lock()=0;
123         virtual void unlock()=0;
124         virtual ~ILockable() {}
125     };
126     
127     struct SHIB_EXPORTS IContactPerson
128     {
129         enum ContactType { technical, support, administrative, billing, other };
130         virtual ContactType getType() const=0;
131         virtual const char* getCompany() const=0;
132         virtual const char* getName() const=0;
133         virtual saml::Iterator<std::string> getEmails() const=0;
134         virtual saml::Iterator<std::string> getTelephones() const=0;
135         virtual const DOMElement* getElement() const=0;
136         virtual ~IContactPerson() {}
137     };
138
139     struct SHIB_EXPORTS IOrganization
140     {
141         virtual const char* getName(const char* lang) const=0;
142         virtual const char* getDisplayName(const char* lang) const=0;
143         virtual const char* getURL(const char* lang) const=0;
144         virtual const DOMElement* getElement() const=0;
145         virtual ~IOrganization() {}
146     };
147     
148     struct SHIB_EXPORTS IKeyDescriptor
149     {
150         enum KeyUse { encryption, signing };
151         virtual KeyUse getUse() const=0;
152         virtual const XMLCh* getEncryptionMethod() const=0;
153         virtual int getKeySize() const=0;
154         virtual DSIGKeyInfoList* getKeyInfo() const=0;
155         virtual const DOMElement* getElement() const=0;
156         virtual ~IKeyDescriptor() {}
157     };
158
159     struct SHIB_EXPORTS IEndpoint
160     {
161         virtual const XMLCh* getBinding() const=0;
162         virtual const XMLCh* getVersion() const=0;
163         virtual const XMLCh* getLocation() const=0;
164         virtual const XMLCh* getResponseLocation() const=0;
165         virtual const DOMElement* getElement() const=0;
166         virtual ~IEndpoint() {}
167     };
168
169     struct SHIB_EXPORTS IProvider;
170     struct SHIB_EXPORTS IProviderRole
171     {
172         virtual const IProvider* getProvider() const=0;
173         virtual saml::Iterator<const XMLCh*> getProtocolSupportEnumeration() const=0;
174         virtual bool hasSupport(const XMLCh* version) const=0;
175         virtual saml::Iterator<const IKeyDescriptor*> getKeyDescriptors() const=0;
176         virtual const IOrganization* getOrganization() const=0;
177         virtual saml::Iterator<const IContactPerson*> getContacts() const=0;
178         virtual const char* getErrorURL() const=0;
179         virtual const DOMElement* getElement() const=0;
180         virtual ~IProviderRole() {}
181     };
182        
183     struct SHIB_EXPORTS ISSOProviderRole : public virtual IProviderRole
184     {
185         virtual saml::Iterator<const IEndpoint*> getSingleLogoutServices() const=0;
186         virtual saml::Iterator<const IEndpoint*> getManageNameIdentifierServices() const=0;
187         virtual ~ISSOProviderRole() {}
188     };
189     
190     struct SHIB_EXPORTS IIDPProviderRole : public virtual ISSOProviderRole
191     {
192         virtual saml::Iterator<const IEndpoint*> getSingleSignOnServices() const=0;
193         virtual saml::Iterator<const IEndpoint*> getNameIdentifierMappingServices() const=0;
194         virtual ~IIDPProviderRole() {}
195     };
196     
197     struct SHIB_EXPORTS ISPProviderRole : public virtual ISSOProviderRole
198     {
199         virtual bool getAuthnRequestsSigned() const=0;
200         virtual const IEndpoint* getDefaultAssertionConsumerService() const=0;
201         virtual const IEndpoint* getAssertionConsumerServices(const XMLCh* id) const=0;
202         virtual ~ISPProviderRole() {}
203     };
204
205     struct SHIB_EXPORTS IPDPProviderRole : public virtual IProviderRole
206     {
207         virtual saml::Iterator<const IEndpoint*> getAuthorizationServices() const=0;
208         virtual ~IPDPProviderRole() {}
209     };
210
211     struct SHIB_EXPORTS IAttributeAuthorityRole : public virtual IProviderRole
212     {
213         virtual saml::Iterator<const IEndpoint*> getAttributeServices() const=0;
214         virtual saml::Iterator<const saml::SAMLAttributeDesignator*> getAttributeDesignators() const=0;
215         virtual ~IAttributeAuthorityRole() {}
216     };
217
218     struct SHIB_EXPORTS IAttributeRequestingService
219     {
220         virtual const XMLCh* getName(const XMLCh* lang) const=0;
221         virtual const XMLCh* getDescription(const XMLCh* lang) const=0;
222         virtual saml::Iterator<std::pair<const saml::SAMLAttribute*,bool> > getRequestedAttributes() const=0;
223         virtual const DOMElement* getElement() const=0;
224         virtual ~IAttributeRequestingService() {}
225     };
226
227     struct SHIB_EXPORTS IAttributeRequesterRole : public virtual IProviderRole
228     {
229         virtual const IAttributeRequestingService* getDefaultAttributeRequestingService() const=0;
230         virtual const IAttributeRequestingService* getAttributeRequestingService(const XMLCh* id) const=0;
231         virtual saml::Iterator<const IAttributeRequestingService*> getAttributeRequestingServices() const=0;
232         virtual ~IAttributeRequesterRole() {}
233     };
234
235     struct SHIB_EXPORTS IProvider
236     {
237         virtual const XMLCh* getId() const=0;
238         virtual saml::Iterator<const XMLCh*> getGroups() const=0;
239         virtual const IOrganization* getOrganization() const=0;
240         virtual saml::Iterator<const IContactPerson*> getContacts() const=0;
241         virtual saml::Iterator<const IProviderRole*> getRoles() const=0;
242         virtual const DOMElement* getElement() const=0;
243         virtual saml::Iterator<std::pair<const XMLCh*,bool> > getSecurityDomains() const=0;
244         virtual ~IProvider() {}
245     };
246     
247     struct SHIB_EXPORTS IMetadata : public virtual ILockable, public virtual IPlugIn
248     {
249         virtual const IProvider* lookup(const XMLCh* providerId) const=0;
250         virtual ~IMetadata() {}
251     };
252
253     struct SHIB_EXPORTS IRevocation : public virtual ILockable, public virtual IPlugIn
254     {
255         virtual saml::Iterator<void*> getRevocationLists(const IProvider* provider, const IProviderRole* role=NULL) const=0;
256         virtual ~IRevocation() {}
257     };
258
259     // Trust interface hides *all* details of signature and SSL validation.
260     // Pluggable providers can fully override the Shibboleth trust model here.
261     
262     struct SHIB_EXPORTS ITrust : public virtual IPlugIn
263     {
264         virtual bool validate(
265             const saml::Iterator<IRevocation*>& revocations,
266             const IProviderRole* role, const saml::SAMLSignedObject& token,
267             const saml::Iterator<IMetadata*>& metadatas=EMPTY(IMetadata*)
268             )=0;
269         virtual bool attach(const saml::Iterator<IRevocation*>& revocations, const IProviderRole* role, void* ctx)=0;
270         virtual ~ITrust() {}
271     };
272     
273     struct SHIB_EXPORTS ICredResolver : public virtual IPlugIn
274     {
275         virtual void attach(void* ctx) const=0;
276         virtual XSECCryptoKey* getKey() const=0;
277         virtual saml::Iterator<XSECCryptoX509*> getCertificates() const=0;
278         virtual void dump(FILE* f) const=0;
279         virtual void dump() const { dump(stdout); }
280         virtual ~ICredResolver() {}
281     };
282
283     struct SHIB_EXPORTS ICredentials : public virtual ILockable, public virtual IPlugIn
284     {
285         virtual const ICredResolver* lookup(const char* id) const=0;
286         virtual ~ICredentials() {}
287     };
288     
289     struct SHIB_EXPORTS IAttributeRule
290     {
291         virtual const XMLCh* getName() const=0;
292         virtual const XMLCh* getNamespace() const=0;
293         virtual const char* getFactory() const=0;
294         virtual const char* getAlias() const=0;
295         virtual const char* getHeader() const=0;
296         virtual void apply(const IProvider* originSite, saml::SAMLAttribute& attribute) const=0;
297         virtual ~IAttributeRule() {}
298     };
299     
300     struct SHIB_EXPORTS IAAP : public virtual ILockable, public virtual IPlugIn
301     {
302         virtual bool anyAttribute() const=0;
303         virtual const IAttributeRule* lookup(const XMLCh* attrName, const XMLCh* attrNamespace=NULL) const=0;
304         virtual const IAttributeRule* lookup(const char* alias) const=0;
305         virtual saml::Iterator<const IAttributeRule*> getAttributeRules() const=0;
306         virtual ~IAAP() {}
307     };
308
309 #ifdef SHIB_INSTANTIATE
310     template class SHIB_EXPORTS saml::Iterator<const IContactPerson*>;
311     template class SHIB_EXPORTS saml::Iterator<const IProviderRole*>;
312     template class SHIB_EXPORTS saml::Iterator<const IKeyDescriptor*>;
313     template class SHIB_EXPORTS saml::Iterator<const IEndpoint*>;
314     template class SHIB_EXPORTS saml::Iterator<const IAttributeRule*>;
315     template class SHIB_EXPORTS saml::Iterator<IMetadata*>;
316     template class SHIB_EXPORTS saml::ArrayIterator<IMetadata*>;
317     template class SHIB_EXPORTS saml::Iterator<ITrust*>;
318     template class SHIB_EXPORTS saml::ArrayIterator<ITrust*>;
319     template class SHIB_EXPORTS saml::Iterator<IRevocation*>;
320     template class SHIB_EXPORTS saml::ArrayIterator<IRevocation*>;
321     template class SHIB_EXPORTS saml::Iterator<ICredentials*>;
322     template class SHIB_EXPORTS saml::ArrayIterator<ICredentials*>;
323     template class SHIB_EXPORTS saml::Iterator<IAAP*>;
324     template class SHIB_EXPORTS saml::ArrayIterator<IAAP*>;
325 #endif
326
327     struct SHIB_EXPORTS Constants
328     {
329         static const XMLCh SHIB_ATTRIBUTE_NAMESPACE_URI[];
330         static const XMLCh SHIB_NAMEID_FORMAT_URI[];
331         static const XMLCh SHIB_NS[];
332         static const XMLCh InvalidHandle[];
333     };
334
335     // Glue classes between abstract metadata and concrete providers
336     
337     class SHIB_EXPORTS Locker
338     {
339     public:
340         Locker(ILockable* lockee) : m_lockee(lockee) {m_lockee->lock();}
341         ~Locker() {if (m_lockee) m_lockee->unlock();}
342         
343     private:
344         Locker(const Locker&);
345         void operator=(const Locker&);
346         ILockable* m_lockee;
347     };
348     
349     class SHIB_EXPORTS Metadata
350     {
351     public:
352         Metadata(const saml::Iterator<IMetadata*>& metadatas) : m_metadatas(metadatas), m_mapper(NULL) {}
353         ~Metadata();
354
355         const IProvider* lookup(const XMLCh* providerId);
356
357     private:
358         Metadata(const Metadata&);
359         void operator=(const Metadata&);
360         IMetadata* m_mapper;
361         const saml::Iterator<IMetadata*>& m_metadatas;
362     };
363
364     class SHIB_EXPORTS Revocation
365     {
366     public:
367         Revocation(const saml::Iterator<IRevocation*>& revocations) : m_revocations(revocations), m_mapper(NULL) {}
368         ~Revocation();
369
370         saml::Iterator<void*> getRevocationLists(const IProvider* provider, const IProviderRole* role=NULL);
371
372     private:
373         Revocation(const Revocation&);
374         void operator=(const Revocation&);
375         IRevocation* m_mapper;
376         const saml::Iterator<IRevocation*>& m_revocations;
377     };
378
379     class SHIB_EXPORTS Trust
380     {
381     public:
382         Trust(const saml::Iterator<ITrust*>& trusts) : m_trusts(trusts) {}
383         ~Trust() {}
384
385         bool validate(
386             const saml::Iterator<IRevocation*>& revocations,
387             const IProviderRole* role, const saml::SAMLSignedObject& token,
388             const saml::Iterator<IMetadata*>& metadatas=EMPTY(IMetadata*)
389             ) const;
390         bool attach(const saml::Iterator<IRevocation*>& revocations, const IProviderRole* role, void* ctx) const;
391         
392     private:
393         Trust(const Trust&);
394         void operator=(const Trust&);
395         const saml::Iterator<ITrust*>& m_trusts;
396     };
397     
398     class SHIB_EXPORTS Credentials
399     {
400     public:
401         Credentials(const saml::Iterator<ICredentials*>& creds) : m_creds(creds), m_mapper(NULL) {}
402         ~Credentials();
403
404         const ICredResolver* lookup(const char* id);
405
406     private:
407         Credentials(const Credentials&);
408         void operator=(const Credentials&);
409         ICredentials* m_mapper;
410         const saml::Iterator<ICredentials*>& m_creds;
411     };
412
413     class SHIB_EXPORTS AAP
414     {
415     public:
416         AAP(const saml::Iterator<IAAP*>& aaps, const XMLCh* attrName, const XMLCh* attrNamespace=NULL);
417         AAP(const saml::Iterator<IAAP*>& aaps, const char* alias);
418         ~AAP();
419         bool fail() const {return m_mapper==NULL;}
420         const IAttributeRule* operator->() const {return m_rule;}
421         operator const IAttributeRule*() const {return m_rule;}
422         
423         static void apply(const saml::Iterator<IAAP*>& aaps, const IProvider* originSite, saml::SAMLAssertion& assertion);
424         
425     private:
426         AAP(const AAP&);
427         void operator=(const AAP&);
428         IAAP* m_mapper;
429         const IAttributeRule* m_rule;
430     };
431
432     // Wrapper classes around the POST profile and SAML binding
433
434     class SHIB_EXPORTS ShibPOSTProfile
435     {
436     public:
437         ShibPOSTProfile(
438             const saml::Iterator<IMetadata*>& metadatas=EMPTY(IMetadata*),
439             const saml::Iterator<IRevocation*>& revocations=EMPTY(IRevocation*),
440             const saml::Iterator<ITrust*>& trusts=EMPTY(ITrust*),
441             const saml::Iterator<ICredentials*>& creds=EMPTY(ICredentials*)
442             );
443         virtual ~ShibPOSTProfile() {}
444
445         virtual const saml::SAMLAssertion* getSSOAssertion(
446             const saml::SAMLResponse& r, const saml::Iterator<const XMLCh*>& audiences=EMPTY(const XMLCh*)
447             );
448         virtual const saml::SAMLAuthenticationStatement* getSSOStatement(const saml::SAMLAssertion& a);
449         virtual saml::SAMLResponse* accept(
450             const XMLByte* buf,
451             const XMLCh* recipient,
452             int ttlSeconds,
453             const saml::Iterator<const XMLCh*>& audiences=EMPTY(const XMLCh*),
454             XMLCh** pproviderId=NULL
455             );
456         virtual saml::SAMLResponse* prepare(
457             const IIDPProviderRole* role,
458             const char* credResolverId,
459             const XMLCh* recipient,
460             const XMLCh* authMethod,
461             time_t authInstant,
462             const XMLCh* name,
463             const XMLCh* format=Constants::SHIB_NAMEID_FORMAT_URI,
464             const XMLCh* nameQualifier=NULL,
465             const XMLCh* subjectIP=NULL,
466             const saml::Iterator<const XMLCh*>& audiences=EMPTY(const XMLCh*),
467             const saml::Iterator<saml::SAMLAuthorityBinding*>& bindings=EMPTY(saml::SAMLAuthorityBinding*)
468             );
469         virtual bool checkReplayCache(const saml::SAMLAssertion& a);
470         virtual const XMLCh* getProviderId(const saml::SAMLResponse& r);
471
472     protected:
473         const saml::Iterator<IMetadata*>& m_metadatas;
474         const saml::Iterator<IRevocation*>& m_revocations;
475         const saml::Iterator<ITrust*>& m_trusts;
476         const saml::Iterator<ICredentials*>& m_creds;
477     };
478
479     class SHIB_EXPORTS ShibBinding
480     {
481     public:
482         ShibBinding(
483             const saml::Iterator<IRevocation*>& revocations,
484             const saml::Iterator<ITrust*>& trusts,
485             const saml::Iterator<ICredentials*>& creds
486             ) : m_revocations(revocations), m_trusts(trusts), m_creds(creds),
487                 m_credResolverId(NULL), m_AA(NULL), m_binding(NULL) {}
488         virtual ~ShibBinding() {delete m_binding;}
489
490         saml::SAMLResponse* send(
491             saml::SAMLRequest& req,
492             const IAttributeAuthorityRole* AA,
493             const char* credResolverId=NULL,
494             const saml::Iterator<const XMLCh*>& audiences=EMPTY(const XMLCh*),
495             const saml::Iterator<saml::SAMLAuthorityBinding*>& bindings=EMPTY(saml::SAMLAuthorityBinding*),
496             saml::SAMLConfig::SAMLBindingConfig& conf=saml::SAMLConfig::getConfig().binding_defaults
497             );
498
499     private:
500         friend bool ssl_ctx_callback(void* ssl_ctx, void* userptr);
501         const saml::Iterator<IRevocation*>& m_revocations;
502         const saml::Iterator<ITrust*>& m_trusts;
503         const saml::Iterator<ICredentials*>& m_creds;
504         const char* m_credResolverId;
505         const IAttributeAuthorityRole* m_AA;
506         saml::SAMLBinding* m_binding;
507     };
508
509     class SHIB_EXPORTS ShibConfig
510     {
511     public:
512         ShibConfig() {}
513         virtual ~ShibConfig() {}
514
515         // global per-process setup and shutdown of Shibboleth runtime
516         virtual bool init();
517         virtual void term();
518
519         // enables runtime and clients to access configuration
520         static ShibConfig& getConfig();
521
522         // allows pluggable implementations of metadata and configuration data
523         PlugManager m_plugMgr;
524     };
525
526     /* Helper classes for implementing reloadable XML-based config files
527        The ILockable interface will usually be inherited twice, once as
528        part of the external interface to clients and once as an implementation
529        detail of the reloading class below.
530      */
531     
532     class SHIB_EXPORTS ReloadableXMLFileImpl
533     {
534     public:
535         ReloadableXMLFileImpl(const char* pathname);
536         ReloadableXMLFileImpl(const DOMElement* pathname);
537         virtual ~ReloadableXMLFileImpl();
538         
539     protected:
540         DOMDocument* m_doc;
541         const DOMElement* m_root;
542     };
543
544     class SHIB_EXPORTS ReloadableXMLFile : protected virtual ILockable
545     {
546     public:
547         ReloadableXMLFile(const DOMElement* e);
548         ~ReloadableXMLFile() { delete m_lock; delete m_impl; }
549
550         virtual void lock();
551         virtual void unlock() { if (m_lock) m_lock->unlock(); }
552
553         ReloadableXMLFileImpl* getImplementation() const;
554
555     protected:
556         virtual ReloadableXMLFileImpl* newImplementation(const char* pathname, bool first=true) const=0;
557         virtual ReloadableXMLFileImpl* newImplementation(const DOMElement* e, bool first=true) const=0;
558         mutable ReloadableXMLFileImpl* m_impl;
559         
560     private:
561         const DOMElement* m_root;
562         std::string m_source;
563         time_t m_filestamp;
564         RWLock* m_lock;
565     };
566 }
567
568 #endif