| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503 | 
							- /** BEGIN COPYRIGHT BLOCK
 
-  * This Program is free software; you can redistribute it and/or modify it under
 
-  * the terms of the GNU General Public License as published by the Free Software
 
-  * Foundation; version 2 of the License.
 
-  * 
 
-  * This Program is distributed in the hope that it will be useful, but WITHOUT
 
-  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
-  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 
-  * 
 
-  * You should have received a copy of the GNU General Public License along with
 
-  * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
-  * Place, Suite 330, Boston, MA 02111-1307 USA.
 
-  * 
 
-  * In addition, as a special exception, Red Hat, Inc. gives You the additional
 
-  * right to link the code of this Program with code not covered under the GNU
 
-  * General Public License ("Non-GPL Code") and to distribute linked combinations
 
-  * including the two, subject to the limitations in this paragraph. Non-GPL Code
 
-  * permitted under this exception must only link to the code of this Program
 
-  * through those well defined interfaces identified in the file named EXCEPTION
 
-  * found in the source code files (the "Approved Interfaces"). The files of
 
-  * Non-GPL Code may instantiate templates or use macros or inline functions from
 
-  * the Approved Interfaces without causing the resulting work to be covered by
 
-  * the GNU General Public License. Only Red Hat, Inc. may make changes or
 
-  * additions to the list of Approved Interfaces. You must obey the GNU General
 
-  * Public License in all respects for all of the Program code and other code used
 
-  * in conjunction with the Program except the Non-GPL Code covered by this
 
-  * exception. If you modify this file, you may extend this exception to your
 
-  * version of the file, but you are not obligated to do so. If you do not wish to
 
-  * provide this exception without modification, you must delete this exception
 
-  * statement from your version and license this file solely under the GPL without
 
-  * exception. 
 
-  * 
 
-  * 
 
-  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
 
-  * Copyright (C) 2005 Red Hat, Inc.
 
-  * All rights reserved.
 
-  * END COPYRIGHT BLOCK **/
 
- #ifdef HAVE_CONFIG_H
 
- #  include <config.h>
 
- #endif
 
- #include <prlog.h>
 
- #include <base/crit.h>
 
- #include <base/ereport.h>
 
- #include <plhash.h>
 
- #include <libaccess/acl.h>
 
- #include "aclpriv.h"
 
- #include <libaccess/aclproto.h>
 
- #include <libaccess/aclglobal.h>
 
- #include <libaccess/usrcache.h>
 
- #include <libaccess/las.h>
 
- #include "aclutil.h"
 
- #define NO_ACL_HASH_FUNCS
 
- #include "permhash.h"
 
- #include "aclcache.h"
 
- static CRITICAL acl_hash_crit = NULL;	/* Controls Global Hash */
 
- enum {
 
-     ACL_URI_HASH,
 
-     ACL_URI_GET_HASH
 
- };
 
- /*	ACL_ListHashKeyHash
 
-  *	Given an ACL List address, computes a randomized hash value of the
 
-  *	ACL structure pointer addresses by simply adding them up.  Returns
 
-  *	the resultant hash value.
 
-  */
 
- static PLHashNumber
 
- ACL_ListHashKeyHash(const void *Iacllist)
 
- {
 
-     PLHashNumber hash=0;
 
-     ACLWrapper_t *wrap;
 
-     ACLListHandle_t *acllist=(ACLListHandle_t *)Iacllist;
 
-     for (wrap=acllist->acl_list_head; wrap; wrap=wrap->wrap_next) {
 
- 	hash += (PLHashNumber)(PRSize)wrap->acl;
 
-     }
 
-     return (hash);
 
- }
 
- /*	ACL_ListHashKeyCompare
 
-  *	Given two acl lists, compares the addresses of the acl pointers within
 
-  *	them to see if theyre identical.  Returns 1 if equal, 0 otherwise.
 
-  */
 
- static int
 
- ACL_ListHashKeyCompare(const void *Iacllist1, const void *Iacllist2)
 
- {
 
-     ACLWrapper_t *wrap1, *wrap2;
 
-     ACLListHandle_t *acllist1=(ACLListHandle_t *)Iacllist1;
 
-     ACLListHandle_t *acllist2=(ACLListHandle_t *)Iacllist2;
 
-     if (acllist1->acl_count != acllist2->acl_count) 
 
-         return 0;
 
-     wrap1 = acllist1->acl_list_head;
 
-     wrap2 = acllist2->acl_list_head;
 
-     while ((wrap1 != NULL) && (wrap2 != NULL)) {
 
- 	if (wrap1->acl != wrap2->acl) 
 
-             return 0;
 
- 	wrap1 = wrap1->wrap_next;
 
- 	wrap2 = wrap2->wrap_next;
 
-     }
 
-     if ((wrap1 != NULL) || (wrap2 != NULL)) 
 
-         return 0;
 
-     else 
 
-         return 1;
 
- }
 
- /*  ACL_ListHashValueCompare
 
-  *  Returns 1 if equal, 0 otherwise
 
-  */
 
- static int
 
- ACL_ListHashValueCompare(const void *acllist1, const void *acllist2)
 
- {
 
-     return (acllist1 == acllist2);
 
- }
 
- void 
 
- ACL_ListHashInit()
 
- {
 
-     ACLListHash = PR_NewHashTable(200, 
 
- 				  ACL_ListHashKeyHash,
 
- 				  ACL_ListHashKeyCompare,
 
- 				  ACL_ListHashValueCompare,
 
- 				  &ACLPermAllocOps, 
 
- 				  NULL);
 
-     if (ACLListHash == NULL) {
 
- 	ereport(LOG_SECURITY, "Unable to allocate ACL List Hash\n");
 
- 	return;
 
-     }
 
-     return;
 
- }
 
- static void 
 
- ACL_ListHashDestroy()
 
- {
 
-     if (ACLListHash) {
 
-         PR_HashTableDestroy(ACLListHash);
 
-         ACLListHash = NULL;
 
-     }
 
-     return;
 
- }
 
- /*  ACL_ListHashUpdate
 
-  *  Typically called with the &rq->acllist.  Checks if the newly generated
 
-  *  acllist matches one that's already been created.  If so, toss the new
 
-  *  list and set the pointer to the old list in its place.
 
-  */
 
- void 
 
- ACL_ListHashUpdate(ACLListHandle_t **acllistp)
 
- {
 
-     NSErr_t *errp = 0;
 
-     ACLListHandle_t *tmp_acllist;
 
-     PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
-     tmp_acllist = (ACLListHandle_t *)PR_HashTableLookup(ACLListHash, *acllistp);
 
-     if (tmp_acllist  &&  tmp_acllist != *acllistp) {
 
- 	PR_ASSERT(*acllistp  &&  *acllistp != ACL_LIST_NO_ACLS);
 
- 	ACL_ListDestroy(errp, *acllistp);
 
- 	*acllistp = tmp_acllist;
 
- 	PR_ASSERT(ACL_CritHeld());
 
-         tmp_acllist->ref_count++;	/* we're gonna use it */
 
-     } else { 			/* Wasn't in the list */
 
- 	PR_HashTableAdd(ACLListHash, *acllistp, *acllistp);
 
-     }
 
-     PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
-     return;
 
- }
 
- /*  ACL_ListCacheEnter
 
-  *  In some cases, the URI cache is useless.  E.g. when virtual servers are used.
 
-  *  When that happens, the List Cache is still useful, because the cached ACL
 
-  *  List has the Eval cache in it, plus any LAS caches.
 
-  */
 
- NSAPI_PUBLIC void
 
- ACL_ListHashEnter(ACLListHandle_t **acllistp)
 
- {
 
-     ACL_CritEnter();
 
-     /*  Look for a matching ACL List and use it if we find one.  */
 
-     if (*acllistp)  {
 
- 	PR_ASSERT(*acllistp != ACL_LIST_NO_ACLS);
 
-         PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
- 	ACL_ListHashUpdate(acllistp);
 
-     } else {
 
- 	*acllistp = ACL_LIST_NO_ACLS;
 
-     }
 
-     ACL_CritExit();
 
-     PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
-     return;
 
- }
 
- /*  ACL_ListHashCheck
 
-  *  When Virtual Servers are active, and the ACL URI cache is inactive, someone
 
-  *  with an old ACL List pointer can check to see if it's still valid.  This will
 
-  *  also increment the reference count on it.
 
-  */
 
- NSAPI_PUBLIC int
 
- ACL_ListHashCheck(ACLListHandle_t **acllistp)
 
- {
 
-     ACLListHandle_t *tmp_acllist;
 
-     if (*acllistp == ACL_LIST_NO_ACLS) return 1;
 
-     ACL_CritEnter();
 
-     tmp_acllist = (ACLListHandle_t *)PR_HashTableLookup(ACLListHash, *acllistp);
 
-     if (tmp_acllist) {
 
- 	PR_ASSERT(*acllistp  &&  *acllistp != ACL_LIST_NO_ACLS);
 
- 	*acllistp = tmp_acllist;
 
- 	PR_ASSERT(ACL_CritHeld());
 
-         tmp_acllist->ref_count++;	/* we're gonna use it */
 
-         ACL_CritExit();
 
- 	PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
-         return 1;		/* Normal path */
 
-     } else { 			/* Wasn't in the list */
 
-         ACL_CritExit();
 
-         return 0;
 
-     }
 
- }
 
-    
 
- void
 
- ACL_UriHashDestroy(void)
 
- {
 
-     if (acl_uri_hash) {
 
- 	PR_HashTableDestroy(acl_uri_hash);
 
-         acl_uri_hash = NULL;
 
-     }
 
-     if (acl_uri_get_hash) {
 
- 	PR_HashTableDestroy(acl_uri_get_hash);
 
-         acl_uri_get_hash = NULL;
 
-     }
 
-     pool_destroy((void **)acl_uri_hash_pool);
 
-     acl_uri_hash_pool = NULL;
 
- }
 
- void
 
- ACL_Destroy(void)
 
- {
 
-     ACL_ListHashDestroy();
 
-     ACL_UriHashDestroy();
 
-     ACL_LasHashDestroy();
 
- }
 
- /* 	Only used in ASSERT statements to verify that we have the lock 	 */
 
- int
 
- ACL_CritHeld(void)
 
- {
 
-     return (crit_owner_is_me(acl_hash_crit));
 
- }
 
- NSAPI_PUBLIC void
 
- ACL_CritEnter(void)
 
- {
 
-     crit_enter(acl_hash_crit);
 
- }
 
- NSAPI_PUBLIC void 
 
- ACL_CritExit(void)
 
- {
 
-     crit_exit(acl_hash_crit);
 
- }
 
- void
 
- ACL_CritInit(void)
 
- {
 
-     acl_hash_crit = crit_init();
 
- }
 
- void
 
- ACL_UriHashInit(void)
 
- {
 
-     acl_uri_hash = PR_NewHashTable(200,
 
-                                      PR_HashString,
 
-                                      PR_CompareStrings,
 
-                                      PR_CompareValues,
 
-                                      &ACLPermAllocOps,
 
-                                      NULL);
 
-     acl_uri_get_hash = PR_NewHashTable(200,
 
-                                      PR_HashString,
 
-                                      PR_CompareStrings,
 
-                                      PR_CompareValues,
 
-                                      &ACLPermAllocOps,
 
-                                      NULL);
 
-     acl_uri_hash_pool = pool_create();
 
- }
 
- /*  ACL_CacheCheck
 
-  *  INPUT
 
-  *	uri	A URI string pointer
 
-  *	acllistp A pointer to an acllist placeholder.  E.g. &rq->acllist
 
-  *  OUTPUT
 
-  *	return	1 if cached. 0 if not.   The reference count on the ACL List
 
-  *	is INCREMENTED, and will be decremented when ACL_EvalDestroy or 
 
-  *	ACL_ListDecrement is
 
-  *	called. 
 
-  */
 
- int
 
- ACL_INTCacheCheck(int which, char *uri, ACLListHandle_t **acllistp)
 
- {
 
-     PLHashTable *hash;
 
-     PR_ASSERT(uri && acl_uri_hash && acl_uri_get_hash);
 
-     /*  ACL cache:  If the ACL List is already in the cache, there's no need
 
-      *  to go through the pathcheck directives.
 
-      *  NULL	means that the URI hasn't been accessed before.
 
-      *  ACL_LIST_NO_ACLS	
 
-      *		means that the URI has no ACLs.
 
-      *  Anything else is a pointer to the acllist.
 
-      */
 
-     ACL_CritEnter();
 
-     /* Get the pointer to the hash table after acquiring the lock */
 
-     if (which == ACL_URI_HASH)
 
- 	hash = acl_uri_hash;
 
-     else
 
- 	hash = acl_uri_get_hash;
 
-     *acllistp = (ACLListHandle_t *)PR_HashTableLookup(hash, uri);
 
-     if (*acllistp != NULL) {
 
- 	if (*acllistp != ACL_LIST_NO_ACLS) {
 
-             PR_ASSERT((*acllistp)->ref_count >= 0);
 
- 	    PR_ASSERT(ACL_CritHeld());
 
- 	    (*acllistp)->ref_count++;
 
- 	}
 
-         ACL_CritExit();
 
- 	PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
-         return 1;		/* Normal path */
 
-     }
 
-     ACL_CritExit();
 
-     return 0;
 
- }
 
- int
 
- ACL_CacheCheckGet(char *uri, ACLListHandle_t **acllistp)
 
- {
 
-     return (ACL_INTCacheCheck(ACL_URI_GET_HASH, uri, acllistp));
 
- }
 
- int
 
- ACL_CacheCheck(char *uri, ACLListHandle_t **acllistp)
 
- {
 
-     return (ACL_INTCacheCheck(ACL_URI_HASH, uri, acllistp));
 
- }
 
-  
 
- /*  ACL_CacheEnter
 
-  *  INPUT
 
-  *	acllist or 0 if there were no ACLs that applied.
 
-  *  OUTPUT
 
-  *      The acllist address may be changed if it matches an existing one.
 
-  */
 
- static void
 
- ACL_INTCacheEnter(int which, char *uri, ACLListHandle_t **acllistp)
 
- {
 
-     ACLListHandle_t *tmpacllist;
 
-     NSErr_t *errp = 0;
 
-     PLHashTable *hash;
 
-     PR_ASSERT(uri);
 
-     ACL_CritEnter();
 
-     /* Get the pointer to the hash table after acquiring the lock */
 
-     if (which == ACL_URI_HASH)
 
- 	hash = acl_uri_hash;
 
-     else
 
- 	hash = acl_uri_get_hash;
 
-     /*  Check again (now that we're in the critical section) to see if
 
-      *  someone else created an ACL List for this URI.  If so, discard the
 
-      *  list that we made and replace it with the one just found.
 
-      */
 
-     tmpacllist = (ACLListHandle_t *)PR_HashTableLookup(hash, uri);
 
-     if (tmpacllist != NULL) {
 
-         if (tmpacllist != ACL_LIST_NO_ACLS) {
 
- 	    PR_ASSERT(ACL_CritHeld());
 
-             tmpacllist->ref_count++;	/* we're going to use it */
 
-         }
 
- 	ACL_CritExit();
 
- 	if (*acllistp  &&  *acllistp != ACL_LIST_NO_ACLS) {
 
- 	    ACL_ListDestroy(errp, *acllistp);
 
- 	}
 
- 	*acllistp = tmpacllist;
 
- 	PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
- 	return;
 
-     }
 
-     /*  Didn't find another list, so put ours in.  */
 
-     /*  Look for a matching ACL List and use it if we find one.  */
 
-     if (*acllistp)  {
 
- 	PR_ASSERT(*acllistp != ACL_LIST_NO_ACLS);
 
-         PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
- 	ACL_ListHashUpdate(acllistp);
 
-     } else {
 
- 	*acllistp = ACL_LIST_NO_ACLS;
 
-     }
 
-     PR_HashTableAdd(hash, pool_strdup((void **)acl_uri_hash_pool, uri), (void *)*acllistp);
 
-     ACL_CritExit();
 
-     PR_ASSERT(ACL_AssertAcllist(*acllistp));
 
-     return;
 
- }
 
- void
 
- ACL_CacheEnter(char *uri, ACLListHandle_t **acllistp)
 
- {
 
-     ACL_INTCacheEnter(ACL_URI_HASH, uri, acllistp);
 
-     return;
 
- }
 
- void
 
- ACL_CacheEnterGet(char *uri, ACLListHandle_t **acllistp)
 
- {
 
-     ACL_INTCacheEnter(ACL_URI_GET_HASH, uri, acllistp);
 
-     return;
 
- }
 
- static int get_is_owner_default (NSErr_t *errp, PList_t subject,
 
- 				 PList_t resource, PList_t auth_info,
 
- 				 PList_t global_auth, void *unused)
 
- {
 
-     /* Make sure we don't generate error "all getters declined" message from
 
-      * ACL_GetAttribute.
 
-      */
 
- 	PListInitProp(subject, ACL_ATTR_IS_OWNER_INDEX, ACL_ATTR_IS_OWNER,
 
- 		"true", 0);
 
-     return LAS_EVAL_TRUE;
 
- }
 
- NSAPI_PUBLIC int
 
- ACL_Init(void)
 
- {
 
-     ACL_InitAttr2Index();
 
-     ACLGlobal = (ACLGlobal_p)PERM_CALLOC(sizeof(ACLGlobal_s));
 
-     oldACLGlobal = (ACLGlobal_p)PERM_CALLOC(sizeof(ACLGlobal_s));
 
-     PR_ASSERT(ACLGlobal && oldACLGlobal);
 
-     ACL_DATABASE_POOL = pool_create();
 
-     ACL_METHOD_POOL = pool_create();
 
-     ACL_CritInit();
 
-     ACL_UriHashInit();
 
-     ACL_ListHashInit();
 
-     ACL_LasHashInit();
 
-     ACL_Init2();
 
-     return 0;
 
- }
 
- /* This one gets called at startup AND at cache flush time. */
 
- void
 
- ACL_Init2(void)
 
- {
 
-     /* Register the ACL functions */
 
-     ACL_LasRegister(NULL, "timeofday", LASTimeOfDayEval, LASTimeOfDayFlush);
 
-     ACL_LasRegister(NULL, "dayofweek", LASDayOfWeekEval, LASDayOfWeekFlush);
 
-     ACL_LasRegister(NULL, "ip", LASIpEval, LASIpFlush);
 
-     ACL_LasRegister(NULL, "dns", LASDnsEval, LASDnsFlush);
 
-     ACL_LasRegister(NULL, "dnsalias", LASDnsEval, LASDnsFlush);
 
-     ACL_LasRegister(NULL, "group", LASGroupEval, (LASFlushFunc_t)NULL);
 
-     ACL_LasRegister(NULL, "user", LASUserEval, (LASFlushFunc_t)NULL);
 
- #ifdef MCC_ADMSERV
 
-     ACL_LasRegister(NULL, "program", LASProgramEval, (LASFlushFunc_t)NULL);
 
- #endif
 
-     return;
 
- }
 
- NSAPI_PUBLIC int
 
- ACL_InitPostMagnus(void)
 
- {
 
-     int rv;
 
-     rv = ACL_AttrGetterRegister(NULL, ACL_ATTR_IS_OWNER,
 
- 				get_is_owner_default,
 
- 				ACL_METHOD_ANY, ACL_DBTYPE_ANY,
 
- 				ACL_AT_END, NULL);
 
-     return rv;
 
- }
 
- NSAPI_PUBLIC int
 
- ACL_LateInitPostMagnus(void)
 
- {
 
-     return acl_usr_cache_init();
 
- }
 
 
  |