/* * Attempt to locate the index number for one of the known attribute names * that are stored in plists. If we can't match it, just return 0. */ int ACL_Attr2Index(const char *attrname) { int index = 0; if ( ACLAttr2IndexPList ) { PListFindValue(ACLAttr2IndexPList, attrname, (void **)&index, NULL); if (index < 0) index = 0; } return index; }
// // 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; }