//
// ACL_ListIncrement - increment the ACLList's refcount safely
//
NSAPI_PUBLIC void
ACL_ListIncrement(NSErr_t *errp, ACLListHandle_t *acllist)
{
    if (!acllist  ||  acllist == ACL_LIST_NO_ACLS)
	return;

    NS_ASSERT(ACL_AssertAcllist(acllist));

    ACL_CritEnter();
    NS_ASSERT(ACL_CritHeld());
    acllist->ref_count++;
    ACL_CritExit();
    return;
}
//
// ACL_ListDecrement - decrement the ACLList's refcount safely
//
NSAPI_PUBLIC int
ACL_ListDecrement(NSErr_t *errp, ACLListHandle_t *acllist)
{
    if (!acllist  ||  acllist == ACL_LIST_NO_ACLS)
	return 0;

    NS_ASSERT(ACL_AssertAcllist(acllist));

    ACL_CritEnter();
    NS_ASSERT(ACL_CritHeld());
    if (--acllist->ref_count == 0)
        ACL_ListDestroy(errp, acllist);
    ACL_CritExit();

    return 0;
}
/*  The hash table is keyed by attribute name, and contains pointers to the
 *  PRCList headers.  These in turn, circularly link a set of AttrGetter_s
 *  structures.
 */
NSAPI_PUBLIC int
ACL_AttrGetterRegister(NSErr_t *errp, const char *attr, ACLAttrGetterFn_t fn,
                       ACLMethod_t m, ACLDbType_t d, int position, void *arg)
{
    ACLAttrGetter_t	*getter;
    PRHashEntry         **hep;

    if (position != ACL_AT_FRONT  &&  position != ACL_AT_END) {
	return -1;
    }

    ACL_CritEnter();
    
    hep = PR_HashTableRawLookup(ACLAttrGetterHash, ACLPR_HashCaseString(attr), attr);

    /*  Now, allocate the current entry  */
    getter = (ACLAttrGetter_t *)CALLOC(sizeof(ACLAttrGetter_t));
    if (getter == NULL) {
        ACL_CritExit();
        return -1;
    }
    getter->method	= m;
    getter->dbtype	= d;
    getter->fn	= fn;
    getter->arg = arg;

    if (*hep == 0) {	/* New entry */

	PR_INIT_CLIST(&getter->list);
        PR_HashTableAdd(ACLAttrGetterHash, attr, (void *)getter);
    }
    else {

        ACLAttrGetter_t *head = (ACLAttrGetter_t *)((*hep)->value);

        PR_INSERT_BEFORE(&getter->list, &head->list);

        if (position == ACL_AT_FRONT) {

            /* Set new head of list */
            (*hep)->value = (void *)getter;
        }
    }

    ACL_CritExit();
    return 0;
}
/*
 *    LASIpEval
 *    INPUT
 *    attr_name      The string "ip" - in lower case.
 *    comparator     CMP_OP_EQ or CMP_OP_NE only
 *    attr_pattern   A comma-separated list of IP addresses and netmasks
 *                   in dotted-decimal form.  Netmasks are optionally
 *                   prepended to the IP address using a plus sign.  E.g.
 *                   255.255.255.0+123.45.67.89.  Any byte in the IP address
 *                   (but not the netmask) can be wildcarded using "*"
 *    *cachable      Always set to ACL_INDEF_CACHABLE
 *    subject        Subject property list
 *    resource       Resource property list
 *    auth_info      The authentication info if any
 *    RETURNS
 *    ret code       The usual LAS return codes.
 */
int LASIpEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
          char *attr_pattern, ACLCachable_t *cachable, void **LAS_cookie,
          PList_t subject, PList_t resource, PList_t auth_info,
          PList_t global_auth)
{
    void               *pip;
    int                retcode;
    LASIpContext_t     *context;
    int		       rv;

#ifndef UTEST
    *cachable = ACL_INDEF_CACHABLE;
#endif

    if (strcmp(attr_name, "ip") != 0) {
	nserrGenerate(errp, ACLERRINVAL, ACLERR5200, ACL_Program, 2, XP_GetAdminStr(DBT_lasIpBuildReceivedRequestForAttr_), attr_name);
        return LAS_EVAL_INVALID;
    }

    if ((comparator != CMP_OP_EQ) && (comparator != CMP_OP_NE)) {
	nserrGenerate(errp, ACLERRINVAL, ACLERR5210, ACL_Program, 2, XP_GetAdminStr(DBT_lasipevalIllegalComparatorDN_), comparator_string(comparator));
        return LAS_EVAL_INVALID;
    }

    /* GET THE IP ADDR FROM THE SESSION CONTEXT AND STORE IT IN THE
     * VARIABLE ip.
     */
#ifndef    UTEST
    rv = ACL_GetAttribute(errp, ACL_ATTR_IP, &pip,
			  subject, resource, auth_info, global_auth);

    PRNetAddr *ip_addr = (PRNetAddr *)pip;
    if (rv != LAS_EVAL_TRUE) {
        if (subject || resource) {
            /* Don't ereport if called from ACL_CachableAclList */
	    char rv_str[16];
	    sprintf(rv_str, "%d", rv);
	    nserrGenerate(errp, ACLERRINVAL, ACLERR5220, ACL_Program, 2, XP_GetAdminStr(DBT_lasipevalUnableToGetSessionAddre_), rv_str);
        }
        ereport(LOG_VERBOSE,
                "ERROR Attribute Getter for ACL_ATTR_IP returned error %d.",
                rv);
	return LAS_EVAL_FAIL;
    }

#else
     PRNetAddr *ip_addr = LASIpGetIpv6();
    if (ip_addr == NULL) {
        ereport(LOG_VERBOSE,
                "ERROR IP Address returned from LASIpGetIpv6() is NULL.");
        return LAS_EVAL_FAIL;
    }
#endif
    int ipVersion = PR_AF_INET;
    if (ip_addr->ipv6.family == PR_AF_INET6) {
         ipVersion = PR_AF_INET6;
    } else if (ip_addr->inet.family != PR_AF_INET) {
         PR_ASSERT(0);
    }

    /* If this is the first time through, build the pattern tree first.
     */
    if (*LAS_cookie == NULL) {
        if (strcspn(attr_pattern, "0123456789.*ABCDEF:abcdef,+ \t")) {
            nserrGenerate(errp,ACLERRINVAL,ACLERR5120,ACL_Program,2,
                 XP_GetAdminStr(DBT_lasIpIncorrentIPPattern),attr_pattern);
            return LAS_EVAL_INVALID;
        }
        ACL_CritEnter();
        context = (LASIpContext *) *LAS_cookie;
        if (*LAS_cookie == NULL) {    /* must check again */
            *LAS_cookie = context = (LASIpContext_t *)PERM_MALLOC(sizeof(LASIpContext_t));
            if (context == NULL) {
		nserrGenerate(errp, ACLERRNOMEM, ACLERR5230, ACL_Program, 1, XP_GetAdminStr(DBT_lasipevalUnableToAllocateContext_));
                ACL_CritExit();
                return LAS_EVAL_FAIL;
            }
            context->treetop = NULL;
            retcode = LASIpBuild(errp, attr_pattern, &context->treetop, ipVersion);
            if ((retcode == PR_AF_INET6) ||
                (retcode == PR_AF_INET) ||
                (retcode == (PR_AF_INET6+PR_AF_INET)))
                 context->ipVersion = retcode;
            else {
                ACL_CritExit();
                return (retcode);
	    }
        }
	ACL_CritExit();
    } else
        context = (LASIpContext *) *LAS_cookie;

    return traverseTreeAndCompareIPs(errp, ip_addr, context, attr_pattern, 
                                     ipVersion, (comparator == CMP_OP_EQ)?1:0);
}
示例#5
0
文件: lasdns.cpp 项目: Firstyear/ds
/*
 *	LASDnsEval
 *	INPUT
 *	attr_name	The string "dns" - in lower case.
 *	comparator	CMP_OP_EQ or CMP_OP_NE only
 *	attr_pattern	A comma-separated list of DNS names
 *			Any segment(s) in a DNS name can be wildcarded using
 *			"*".  Note that this is not a true Regular Expression
 *			form.
 *	*cachable	Always set to ACL_INDEF_CACHE
 *      subject		Subject property list
 *      resource 	Resource property list
 *      auth_info	Authentication info, if any
 *	RETURNS
 *	ret code	The usual LAS return codes.
 */
int LASDnsEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
               char *attr_pattern, ACLCachable_t *cachable, void **LAS_cookie,
               PList_t subject, PList_t resource,
               PList_t auth_info, PList_t global_auth)
{
    int			result;
    int			aliasflg;
    char		*my_dns;
    LASDnsContext_t 	*context = NULL;
    int			rv;

    *cachable = ACL_INDEF_CACHABLE;

    if (strcmp(attr_name, "dns") == 0) {
        /* Enable aliasflg for "dns", which allows "dns" hostname to look up
         * DSN hash table using the primary hostname. */
        aliasflg = 1;
    } else if (strcmp(attr_name, "dnsalias") == 0) {
        aliasflg = 1;
    } else {
        nserrGenerate(errp, ACLERRINVAL, ACLERR4800, ACL_Program, 2, XP_GetAdminStr(DBT_lasDnsBuildReceivedRequestForAtt_), attr_name);
        return LAS_EVAL_INVALID;
    }

    if ((comparator != CMP_OP_EQ) && (comparator != CMP_OP_NE)) {
        nserrGenerate(errp, ACLERRINVAL, ACLERR4810, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsevalIllegalComparatorDN_), comparator_string(comparator));
        return LAS_EVAL_INVALID;
    }

    /* If this is the first time through, build the pattern tree first.  */
    if (*LAS_cookie == NULL) {
        ACL_CritEnter();
        if (*LAS_cookie == NULL) {	/* Must check again */
            *LAS_cookie = context =
                              (LASDnsContext_t *)PERM_MALLOC(sizeof(LASDnsContext_t));
            if (context == NULL) {
                nserrGenerate(errp, ACLERRNOMEM, ACLERR4820, ACL_Program, 1, XP_GetAdminStr(DBT_lasdnsevalUnableToAllocateContex_));
                ACL_CritExit();
                return LAS_EVAL_FAIL;
            }
            context->Table = NULL;
            if (LASDnsBuild(errp, attr_pattern, context, aliasflg) ==
                    LAS_EVAL_INVALID) {
                /* Error is already printed in LASDnsBuild */
                ACL_CritExit();
                return LAS_EVAL_FAIL;
            }
            /* After this line, it is assured context->Table is not NULL. */
        } else {
            context = (LASDnsContext *) *LAS_cookie;
        }
        ACL_CritExit();
    } else {
        ACL_CritEnter();
        context = (LASDnsContext *) *LAS_cookie;
        ACL_CritExit();
    }

    /* Call the DNS attribute getter */
#ifdef  UTEST
    LASDnsGetDns(&my_dns);      /* gets stuffed on return       */
#else
    rv = ACL_GetAttribute(errp, ACL_ATTR_DNS, (void **)&my_dns,
                          subject, resource, auth_info, global_auth);

    if (rv != LAS_EVAL_TRUE) {
        if (subject || resource) {
            char rv_str[16];
            /* Don't ereport if called from ACL_CachableAclList */
            sprintf(rv_str, "%d", rv);
            nserrGenerate(errp, ACLERRINVAL, ACLERR4830, ACL_Program, 2, XP_GetAdminStr(DBT_lasdnsevalUnableToGetDnsErrorDN_), rv_str);
        }
        return LAS_EVAL_FAIL;
    }
#endif

    result = LASDnsMatch(my_dns, context);

    if (comparator == CMP_OP_NE) {
        if (result == LAS_EVAL_FALSE)
            return LAS_EVAL_TRUE;
        else if (result == LAS_EVAL_TRUE)
            return LAS_EVAL_FALSE;
    }
    return (result);
}