X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/2d21ac55c334faf3a56e5634905ed6987fc787d4..bb59bff194111743b33cc36712410b5656329d3c:/bsd/kern/kern_authorization.c diff --git a/bsd/kern/kern_authorization.c b/bsd/kern/kern_authorization.c index b65a828c2..91c2305c8 100644 --- a/bsd/kern/kern_authorization.c +++ b/bsd/kern/kern_authorization.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2007 Apple Inc. All rights reserved. + * Copyright (c) 2004-2011 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -43,7 +43,7 @@ #include #include -#include +#include #include #include @@ -117,7 +117,7 @@ struct kauth_scope { static TAILQ_HEAD(,kauth_scope) kauth_scopes; static int kauth_add_callback_to_scope(kauth_scope_t sp, kauth_listener_t klp); -static void kauth_scope_init(void) __attribute__((section("__TEXT, initcode"))); +static void kauth_scope_init(void); static kauth_scope_t kauth_alloc_scope(const char *identifier, kauth_scope_callback_t callback, void *idata); static kauth_listener_t kauth_alloc_listener(const char *identifier, kauth_scope_callback_t callback, void *idata); #if 0 @@ -154,11 +154,14 @@ kauth_init(void) /* bring up kauth subsystem components */ kauth_cred_init(); +#if CONFIG_EXT_RESOLVER kauth_identity_init(); kauth_groups_init(); +#endif kauth_scope_init(); +#if CONFIG_EXT_RESOLVER kauth_resolver_init(); - +#endif /* can't alloc locks after this */ lck_grp_free(kauth_lck_grp); kauth_lck_grp = NULL; @@ -185,10 +188,9 @@ kauth_alloc_scope(const char *identifier, kauth_scope_callback_t callback, void /* * Allocate and populate the scope structure. */ - MALLOC(sp, kauth_scope_t, sizeof(*sp), M_KAUTH, M_WAITOK); + MALLOC(sp, kauth_scope_t, sizeof(*sp), M_KAUTH, M_WAITOK | M_ZERO); if (sp == NULL) return(NULL); - bzero(&sp->ks_listeners, sizeof(sp->ks_listeners)); sp->ks_flags = 0; sp->ks_identifier = identifier; sp->ks_idata = idata; @@ -613,7 +615,7 @@ kauth_authorize_generic_callback(kauth_cred_t credential, __unused void *idata, int kauth_acl_evaluate(kauth_cred_t cred, kauth_acl_eval_t eval) { - int applies, error, i; + int applies, error, i, gotguid; kauth_ace_t ace; guid_t guid; uint32_t rights; @@ -632,9 +634,11 @@ kauth_acl_evaluate(kauth_cred_t cred, kauth_acl_eval_t eval) * Get our guid for comparison purposes. */ if ((error = kauth_cred_getguid(cred, &guid)) != 0) { - eval->ae_result = KAUTH_RESULT_DENY; - KAUTH_DEBUG(" ACL - can't get credential GUID (%d), ACL denied", error); - return(error); + KAUTH_DEBUG(" ACL - can't get credential GUID (%d)", error); + error = 0; + gotguid = 0; + } else { + gotguid = 1; } KAUTH_DEBUG(" ACL - %d entries, initial residual %x", eval->ae_count, eval->ae_residual); @@ -678,7 +682,7 @@ kauth_acl_evaluate(kauth_cred_t cred, kauth_acl_eval_t eval) /* we don't recognise this ACE, skip it */ continue; } - + /* * Verify whether this entry applies to the credential. */ @@ -688,7 +692,10 @@ kauth_acl_evaluate(kauth_cred_t cred, kauth_acl_eval_t eval) applies = eval->ae_options & KAUTH_AEVAL_IS_OWNER; break; case KAUTH_WKG_GROUP: - applies = eval->ae_options & KAUTH_AEVAL_IN_GROUP; + if (!gotguid || (eval->ae_options & KAUTH_AEVAL_IN_GROUP_UNKNOWN)) + applies = ((ace->ace_flags & KAUTH_ACE_KINDMASK) == KAUTH_ACE_DENY); + else + applies = eval->ae_options & KAUTH_AEVAL_IN_GROUP; break; /* we short-circuit these here rather than wasting time calling the group membership code */ case KAUTH_WKG_EVERYBODY: @@ -700,12 +707,12 @@ kauth_acl_evaluate(kauth_cred_t cred, kauth_acl_eval_t eval) default: /* check to see whether it's exactly us, or a group we are a member of */ - applies = kauth_guid_equal(&guid, &ace->ace_applicable); + applies = !gotguid ? 0 : kauth_guid_equal(&guid, &ace->ace_applicable); KAUTH_DEBUG(" ACL - ACE applicable " K_UUID_FMT " caller " K_UUID_FMT " %smatched", K_UUID_ARG(ace->ace_applicable), K_UUID_ARG(guid), applies ? "" : "not "); if (!applies) { - error = kauth_cred_ismember_guid(cred, &ace->ace_applicable, &applies); + error = !gotguid ? ENOENT : kauth_cred_ismember_guid(cred, &ace->ace_applicable, &applies); /* * If we can't resolve group membership, we have to limit misbehaviour. * If the ACE is an 'allow' ACE, assume the cred is not a member (avoid @@ -791,15 +798,37 @@ kauth_acl_inherit(vnode_t dvp, kauth_acl_t initial, kauth_acl_t *product, int is * XXX TODO: wants a "umask ACL" from the process. */ inherit = NULL; - if ((dvp != NULL) && !vfs_authopaque(vnode_mount(dvp))) { + /* + * If there is no initial ACL, or there is, and the initial ACLs + * flags do not request "no inheritance", then we inherit. This allows + * initial object creation via open_extended() and mkdir_extended() + * to reject inheritance for themselves and for inferior nodes by + * specifying a non-NULL inital ACL which has the KAUTH_ACL_NO_INHERIT + * flag set in the flags field. + */ + if ((initial == NULL || !(initial->acl_flags & KAUTH_ACL_NO_INHERIT)) && + (dvp != NULL) && !vfs_authopaque(vnode_mount(dvp))) { VATTR_INIT(&dva); VATTR_WANTED(&dva, va_acl); if ((error = vnode_getattr(dvp, &dva, ctx)) != 0) { KAUTH_DEBUG(" ERROR - could not get parent directory ACL for inheritance"); return(error); } - if (VATTR_IS_SUPPORTED(&dva, va_acl)) + if (VATTR_IS_SUPPORTED(&dva, va_acl)) { inherit = dva.va_acl; + /* + * If there is an ACL on the parent directory, then + * there are potentially inheritable ACE entries, but + * if the flags on the directory ACL say not to + * inherit, then we don't inherit. This allows for + * per directory rerooting of the inheritable ACL + * hierarchy. + */ + if (inherit != NULL && inherit->acl_flags & KAUTH_ACL_NO_INHERIT) { + kauth_acl_free(inherit); + inherit = NULL; + } + } } /* @@ -852,14 +881,17 @@ kauth_acl_inherit(vnode_t dvp, kauth_acl_t initial, kauth_acl_t *product, int is /* * Composition is simply: - * - initial - * - inherited + * - initial direct ACEs + * - inherited ACEs from new parent */ index = 0; if (initial != NULL) { - for (i = 0; i < initial->acl_entrycount; i++) - result->acl_ace[index++] = initial->acl_ace[i]; - KAUTH_DEBUG(" INHERIT - applied %d initial entries", index); + for (i = 0; i < initial->acl_entrycount; i++) { + if (!(initial->acl_ace[i].ace_flags & KAUTH_ACE_INHERITED)) { + result->acl_ace[index++] = initial->acl_ace[i]; + } + } + KAUTH_DEBUG(" INHERIT - applied %d of %d initial entries", index, initial->acl_entrycount); } if (inherit != NULL) { for (i = 0; i < inherit->acl_entrycount; i++) { @@ -873,6 +905,7 @@ kauth_acl_inherit(vnode_t dvp, kauth_acl_t initial, kauth_acl_t *product, int is if (inherit->acl_ace[i].ace_flags & (isdir ? KAUTH_ACE_DIRECTORY_INHERIT : KAUTH_ACE_FILE_INHERIT)) { result->acl_ace[index] = inherit->acl_ace[i]; result->acl_ace[index].ace_flags |= KAUTH_ACE_INHERITED; + result->acl_ace[index].ace_flags &= ~KAUTH_ACE_ONLY_INHERIT; /* * We do not re-inherit inheritance flags * if the ACE from the container has a @@ -947,7 +980,7 @@ kauth_copyinfilesec(user_addr_t xsecurity, kauth_filesec_t *xsecdestpp) * The upper bound must be less than KAUTH_ACL_MAX_ENTRIES. The * value here is fairly arbitrary. It's ok to have a zero count. */ - known_bound = xsecurity + sizeof(struct kauth_filesec); + known_bound = xsecurity + KAUTH_FILESEC_SIZE(0); uaddr = mach_vm_round_page(known_bound); count = (uaddr - known_bound) / sizeof(struct kauth_ace); if (count > 32) @@ -988,6 +1021,7 @@ out: kauth_filesec_free(fsec); } else { *xsecdestpp = fsec; + AUDIT_ARG(opaque, fsec, copysize); } return(error); }