int
LASIpGetter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t
           auth_info, PList_t global_auth, void *arg)
{
    Session *sn=NULL;
    int rv;
    IPAddr_t ip;
    int retcode, tmpip, netmask;
    char * tmp;

    rv = PListGetValue(subject, ACL_ATTR_SESSION_INDEX, (void **)&sn, NULL);
    if (rv < 0) {
        ereport(LOG_SECURITY, XP_GetAdminStr(DBT_aclFrameLASIpGetter1), rv);
        return LAS_EVAL_FAIL;
    }

    tmp = inet_ntoa(sn->iaddr);
    retcode =dotdecimal(tmp, "255.255.255.255", &tmpip, &netmask);
    if (retcode)
        return (retcode);
    ip = tmpip;

    rv = PListInitProp(subject, ACL_ATTR_IP_INDEX, ACL_ATTR_IP, (void *)ip, NULL);
    if (rv < 0) {
        ereport(LOG_SECURITY, XP_GetAdminStr(DBT_aclFrameLASIpGetter2), rv);
        return LAS_EVAL_FAIL;
    }

    return LAS_EVAL_TRUE;
}
NSAPI_PUBLIC int
ACL_ListPostParseForAuth(NSErr_t *errp, ACLListHandle_t *acl_list ) 
{
    ACLHandle_t *acl;
    ACLWrapper_t *wrap;
    ACLExprHandle_t *expr;
    char *method;
    char *database;
    int rv;
    ACLDbType_t *dbtype;
    ACLMethod_t *methodtype;

    if ( acl_list == NULL )
        return(0);

    // for all ACLs
    for ( wrap = acl_list->acl_list_head; wrap; wrap = wrap->wrap_next ) {

        acl = wrap->acl;
        if ( acl == NULL )
            continue;

        // for all expressions with the ACL
        for ( expr = acl->expr_list_head; expr; expr = expr->expr_next ) {

            if ( expr->expr_type != ACL_EXPR_TYPE_AUTH || expr->expr_auth == NULL) 
                continue;

            // get method attribute - this is a name now
            rv = PListGetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX, (void **) &method, NULL);
            if ( rv >= 0 ) {
		methodtype = (ACLMethod_t *)PERM_MALLOC(sizeof(ACLMethod_t));
		rv = ACL_MethodFind(errp, method, methodtype);
		if (rv < 0) {
		    nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
				  3, acl->tag, "method", method);
		    PERM_FREE(methodtype);
		    return(ACLERRUNDEF);
		}

                // replace it with a method type
	        rv = PListSetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX, methodtype, NULL);
		if ( rv < 0 ) {
		    nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program, 0);
		    return(ACLERRNOMEM);
		}
		PERM_FREE(method);
	    }
        }
    }
    return(0);
}
Exemple #3
0
/* acl_get_req_time --
 * If the REQ_TIME is available on the 'resource' plist, return it.
 * Otherwise, make a system call to get the time and insert the time on the
 * 'resource' PList.  Allocate the time_t structure using the 'resource'
 * PList's pool.
 */
time_t *acl_get_req_time (PList_t resource)
{
    time_t *req_time = 0;
    int rv = PListGetValue(resource, ACL_ATTR_TIME_INDEX, (void **)&req_time,
                           NULL);

    if (rv < 0) {
        req_time = (time_t *)pool_malloc(PListGetPool(resource), sizeof(time_t));
        if (NULL == req_time) {
            return NULL;
        }
        time(req_time);
        PListInitProp(resource, ACL_ATTR_TIME_INDEX, ACL_ATTR_TIME,
                      (void *)req_time, NULL);
    }

    return req_time;
}
/* 
 * LASIpv6Getter
 * This is the Attribute Getter function for  IPv6 Addresses.
 * LAS_EVAL_FAIL on failure of LAS_EVAL_TRUE on success.
 */
int
LASIpv6Getter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t
              auth_info, PList_t global_auth, void *arg)
{
    Request *rq = 0;
    int rv = PListGetValue(resource, ACL_ATTR_REQUEST_INDEX,
                           (void **)&rq, NULL);
    if (rv < 0) {
        ereport(LOG_VERBOSE, "Unable to get request object", rv);
        return LAS_EVAL_FAIL;
    }
    HttpRequest *hrq =  GetHrq(rq);
    DaemonSession &dsn = hrq->GetDaemonSession();
    PRNetAddr *ip = dsn.GetRemoteAddress();
    
    rv = PListInitProp(subject, ACL_ATTR_IP_INDEX, ACL_ATTR_IP,
                       (void *)ip, NULL);
    if (rv < 0) {
        ereport(LOG_SECURITY, XP_GetAdminStr(DBT_aclFrameLASIpGetter2), rv);
        return LAS_EVAL_FAIL;
    }

    return LAS_EVAL_TRUE;
}
Exemple #5
0
NSAPI_PUBLIC int
ACL_ListPostParseForAuth(NSErr_t *errp, ACLListHandle_t *acl_list ) 
{
    ACLHandle_t *acl;
    ACLWrapper_t *wrap;
    ACLExprHandle_t *expr;
    char *method;
    char *database;
    int rv;
    ACLDbType_t *dbtype;
    ACLMethod_t *methodtype;

    if ( acl_list == NULL )
        return(0);

    for ( wrap = acl_list->acl_list_head; wrap; wrap = wrap->wrap_next ) {

        acl = wrap->acl;
        if ( acl == NULL )
            continue;

        for ( expr = acl->expr_list_head; expr; expr = expr->expr_next ) {

            if ( expr->expr_type != ACL_EXPR_TYPE_AUTH || 
                 expr->expr_auth == NULL) 
                continue;

            rv = PListGetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX, 
                                (void **) &method, NULL);
            if ( rv >= 0 ) {
		methodtype = (ACLMethod_t *)PERM_MALLOC(sizeof(ACLMethod_t));
		rv = ACL_MethodFind(errp, method, methodtype);
		if (rv) {
		    nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
				  3, acl->tag, "method", method);
		    PERM_FREE(methodtype);
		    return(ACLERRUNDEF);
		}

	        rv = PListSetValue(expr->expr_auth, ACL_ATTR_METHOD_INDEX, 
				      methodtype, NULL);
		if ( rv < 0 ) {
		    nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program,
				  0);
		    return(ACLERRNOMEM);
		}
		PERM_FREE(method);
	    }
    
            rv = PListGetValue(expr->expr_auth, ACL_ATTR_DATABASE_INDEX, 
				(void **) &database, NULL);

	    if (rv < 0) continue;

	    /* The following function lets user use databases which are
	     * not registered by their administrators.  This also fixes
	     * the backward compatibility.
	     */
	    dbtype = (ACLDbType_t *)PERM_MALLOC(sizeof(ACLDbType_t));
	    rv = ACL_RegisterDbFromACL(errp, (const char *) database,
				       dbtype);

	    if (rv < 0) {
		    nserrGenerate(errp, ACLERRUNDEF, ACLERR3800, ACL_Program,
				  3, acl->tag, "database", database);
		PERM_FREE(dbtype);
		return(ACLERRUNDEF);
	    }
    
	    rv = PListInitProp(expr->expr_auth, ACL_ATTR_DBTYPE_INDEX, ACL_ATTR_DBTYPE, 
			       dbtype, NULL);
	    if ( rv < 0 ) {
		nserrGenerate(errp, ACLERRNOMEM, ACLERR3810, ACL_Program,
			      0);
		return(ACLERRNOMEM);
	    }

        }

    }

    return(0);

}
/*	SSL LAS driver
 *	Note that everything is case-insensitive.
 *	INPUT
 *	attr		must be the string "ssl".
 *	comparator	can only be "=" or "!=".
 *	pattern		"on", "off", "yes", "no", "true", "false", "1", "0"
 *	OUTPUT
 *	cachable	Will be set to ACL_NOT_CACHABLE.
 *	return code	set to LAS_EVAL_*
 */
int
LASSSLEval(NSErr_t *errp, char *attr, CmpOp_t comparator, char *pattern, 
		 ACLCachable_t *cachable, void **las_cookie, PList_t subject, 
		 PList_t resource, PList_t auth_info, PList_t global_auth)
{
    Session *sn = NULL;
    PRBool sslrequired, sslstate;
    int rv;
    
    /*	Sanity checking				*/
    if (strcmp(attr, "ssl") != 0) {
        nserrGenerate(errp, ACLERRINVAL, ACLERR6300, ACL_Program, 2, XP_GetAdminStr(DBT_sslLasUnexpectedAttribute), attr);
        return LAS_EVAL_INVALID;
    }
    if ((comparator != CMP_OP_EQ) && (comparator != CMP_OP_NE)) {
        nserrGenerate(errp, ACLERRINVAL, ACLERR6310, ACL_Program, 2, XP_GetAdminStr(DBT_sslLasIllegalComparator), comparator_string(comparator));
        return LAS_EVAL_INVALID;
    }
    *cachable = ACL_NOT_CACHABLE;       // ????

    if (PL_strcasecmp(pattern, "on") == 0 ||
        PL_strcasecmp(pattern, "true") == 0 ||
        PL_strcasecmp(pattern, "yes") == 0 ||
        PL_strcasecmp(pattern, "1") == 0)
    {
        sslrequired = PR_TRUE;
    }
    else
    if (PL_strcasecmp(pattern, "off") == 0 ||
        PL_strcasecmp(pattern, "false") == 0 ||
        PL_strcasecmp(pattern, "no") == 0 ||
        PL_strcasecmp(pattern, "0") == 0)
    {
        sslrequired = PR_FALSE;
    }
    else {
        nserrGenerate(errp, ACLERRINVAL, ACLERR6320, ACL_Program, 2, XP_GetAdminStr(DBT_sslLasIllegalValue), pattern);
        return LAS_EVAL_INVALID;
    }

    // Now look whether our session is over SSL
    if (PListGetValue(subject, ACL_ATTR_SESSION_INDEX, (void **)&sn, NULL) < 0) {
        nserrGenerate(errp, ACLERRINVAL, ACLERR6330, ACL_Program, 2, XP_GetAdminStr(DBT_sslLasUnableToGetSessionAddr));
        return LAS_EVAL_FAIL;
    }

    sslstate = GetSecurity(sn);

    if ((sslstate == sslrequired) && (comparator == CMP_OP_EQ)) {
        rv = LAS_EVAL_TRUE;
    }
    else if ((sslstate != sslrequired) && (comparator == CMP_OP_NE)) {
        rv = LAS_EVAL_TRUE;
    } else {
        rv = LAS_EVAL_FALSE;
    }

    ereport(LOG_VERBOSE, "acl ssl: %s on ssl %s (%s)",
            (rv == LAS_EVAL_FALSE) ? "no match" : "match",
            (comparator == CMP_OP_EQ) ? "=" : "!=",
            pattern);

    return rv;
}
//
// ACL_GetAttribute - find and call one or more matching attribute getter functions
//
NSAPI_PUBLIC int
ACL_GetAttribute(NSErr_t *errp, const char *attr, void **val,
		     		  PList_t subject, PList_t resource, 
				  PList_t auth_info, PList_t global_auth) 
{ 
    int rv; 
    void *attrval;
    ACLAttrGetterFn_t func;
    ACLAttrGetterList_t getters;
    ACLAttrGetter_t *getter;
    ACLMethod_t method;
    char *dbname;
    ACLDbType_t dbtype;

    /* If subject PList is NULL, we will fail anyway */
    if (!subject)
        return LAS_EVAL_FAIL;

    /* Is the attribute already present in the subject property list? */
    rv = PListFindValue(subject, attr, &attrval, NULL);
    if (rv >= 0) {
        /* Yes, take it from there */
	*val = attrval;
	return LAS_EVAL_TRUE;
    }

    /* Get the authentication method and database type */
    // XXX umm... for ACLs that do not depend on user databases and authentication
    // methods (like cipher, dns, ip, tod!), we do not need method and database type.
    // so there's no reason to fail if we don't find anything here.
    // I think setting method to ACL_METHOD_ANY and dbtype to ACL_DBTYPE_ANY would
    // do the job in attr_getter_is_matching - this way, we would find only attr
    // getters that do not care about method and dbtype.

    if (ACL_AuthInfoGetMethod(errp, auth_info, &method) < 0) {
	nserrGenerate(errp, ACLERRFAIL, ACLERR4300, ACL_Program, 2,
            XP_GetAdminStr(DBT_GetAttributeCouldntDetermineMethod), attr);
        return LAS_EVAL_FAIL;
    }

    // dbtype is cached by our friendly ACLEvalAce caller (it's constant for the ACE)
    // XXX what if we don't get called by ACLEvalAce?
    if (PListGetValue(resource, ACL_ATTR_DBTYPE_INDEX, &dbtype, NULL) < 0) {
        dbtype = ACL_DBTYPE_INVALID;
    }

    /* Get the list of attribute getters */
    if ((ACL_AttrGetterFind(errp, attr, &getters) < 0) || (getters == 0)) {
	nserrGenerate(errp, ACLERRFAIL, ACLERR4310, ACL_Program, 2,
                      XP_GetAdminStr(DBT_GetAttributeCouldntLocateGetter), attr);
        return LAS_EVAL_DECLINE;
    }

    // Iterate over each getter and see if it should be called
    // Call each matching getter until a getter which doesn't decline is
    // found.
    char * method_name = NULL;
    char * dbtype_name = NULL;

    for (getter = ACL_AttrGetterFirst(&getters); getter != 0; getter = ACL_AttrGetterNext(&getters, getter)) {

        /* Require matching method and database type */

        if (!attr_getter_is_matching(errp, getter, method, dbtype))
            continue;

        if (ereport_can_log(LOG_VERBOSE)) {
            method_name = acl_get_name(ACLMethodHash, method);
            dbtype_name = acl_get_name(ACLDbTypeHash, dbtype);
            ereport(LOG_VERBOSE, "acl: calling getter for (attr=%s; "
                    "method=%s, dbtype=%s)", attr, method_name, dbtype_name);
        }

        /* Call the getter function */
        func = getter->fn;
        rv = (*func)(errp, subject, resource, auth_info, global_auth, getter->arg);

        if (method_name) {
            ereport(LOG_VERBOSE, "acl: getter for (attr=%s; "
                    "method=%s, dbtype=%s) returns %d", 
                    attr, method_name, dbtype_name, rv);
            FREE(method_name);
            FREE(dbtype_name);
        }

        // if the getter declined, let's try to find another one
        if (rv == LAS_EVAL_DECLINE)
            continue;

        /* Did the getter succeed? */
        if (rv == LAS_EVAL_TRUE) {
            /*
             * Yes, it should leave the attribute on the subject
             * property list.
             */
            if (PListFindValue(subject, attr, (void **)&attrval, NULL) < 0) {
                nserrGenerate(errp, ACLERRFAIL, ACLERR4320, ACL_Program, 2,
                              XP_GetAdminStr(DBT_GetAttributeDidntSetAttr), attr);
                return LAS_EVAL_FAIL;
            }

            /* Got it */
            *val = attrval;
            return LAS_EVAL_TRUE;
        } else {
            /* No, did it fail to get the attribute */
            if (rv == LAS_EVAL_FAIL || rv == LAS_EVAL_INVALID) {
                nserrGenerate(errp, ACLERRFAIL, ACLERR4330, ACL_Program, 2,
                              XP_GetAdminStr(DBT_GetAttributeDidntGetAttr), attr);
            }
            return rv;
        }
    }

    // If we fall out of the loop, all the getters declined

    if (ereport_can_log(LOG_VERBOSE)) {
        method_name = acl_get_name(ACLMethodHash, method);
        dbtype_name = acl_get_name(ACLDbTypeHash, dbtype);
        ereport(LOG_VERBOSE, "acl: unable to obtain an attribute getter for "
                "[%s] with method [%s] (%d), dbtype [%s] (%d)", 
                attr, method_name, method, dbtype_name, dbtype);
        FREE(method_name);
        FREE(dbtype_name);
    }

    nserrGenerate(errp, ACLERRFAIL, ACLERR4340, ACL_Program, 2,
		  XP_GetAdminStr(DBT_GetAttributeAllGettersDeclined), attr);
    return LAS_EVAL_DECLINE;
}