#endif /* CONFIG_EXT_RESOLVER */
-static const int kauth_cred_primes[KAUTH_CRED_PRIMES_COUNT] = KAUTH_CRED_PRIMES;
-static int kauth_cred_primes_index = 0;
-static int kauth_cred_table_size = 0;
+#define KAUTH_CRED_TABLE_SIZE 97
TAILQ_HEAD(kauth_cred_entry_head, ucred);
static struct kauth_cred_entry_head * kauth_cred_table_anchor = NULL;
if ((kip->ki_valid & KI_VALID_UID) && (kip->ki_uid == elp->el_uid)) {
if (elp->el_flags & KAUTH_EXTLOOKUP_VALID_SUPGRPS) {
assert(elp->el_sup_grp_cnt <= NGROUPS);
+ if (elp->el_sup_grp_cnt > NGROUPS) {
+ KAUTH_DEBUG("CACHE - invalid sup_grp_cnt provided (%d), truncating to %d",
+ elp->el_sup_grp_cnt, NGROUPS);
+ elp->el_sup_grp_cnt = NGROUPS;
+ }
kip->ki_supgrpcnt = elp->el_sup_grp_cnt;
memcpy(kip->ki_supgrps, elp->el_sup_groups, sizeof(elp->el_sup_groups[0]) * kip->ki_supgrpcnt);
kip->ki_valid |= KI_VALID_GROUPS;
#if CONFIG_EXT_RESOLVER == 0
/*
- * If there's no resolver, short-circuit the kauth_cred_x2y() lookups.
+ * If there's no resolver, only support a subset of the kauth_cred_x2y() lookups.
*/
static __inline int
-kauth_cred_cache_lookup(__unused int from, __unused int to,
- __unused void *src, __unused void *dst)
+kauth_cred_cache_lookup(int from, int to, void *src, void *dst)
{
- return (EWOULDBLOCK);
-
+ /* NB: These must match the definitions used by Libinfo's mbr_identifier_translate(). */
+ static const uuid_t _user_compat_prefix = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd, 0xcc, 0xcc, 0xbb, 0xbb, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00};
+ static const uuid_t _group_compat_prefix = {0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x00};
+#define COMPAT_PREFIX_LEN (sizeof(uuid_t) - sizeof(id_t))
+
+ assert(from != to);
+
+ switch (from) {
+ case KI_VALID_UID: {
+ id_t uid = htonl(*(id_t *)src);
+
+ if (to == KI_VALID_GUID) {
+ uint8_t *uu = dst;
+ memcpy(uu, _user_compat_prefix, sizeof(_user_compat_prefix));
+ memcpy(&uu[COMPAT_PREFIX_LEN], &uid, sizeof(uid));
+ return (0);
+ }
+ break;
+ }
+ case KI_VALID_GID: {
+ id_t gid = htonl(*(id_t *)src);
+
+ if (to == KI_VALID_GUID) {
+ uint8_t *uu = dst;
+ memcpy(uu, _group_compat_prefix, sizeof(_group_compat_prefix));
+ memcpy(&uu[COMPAT_PREFIX_LEN], &gid, sizeof(gid));
+ return (0);
+ }
+ break;
+ }
+ case KI_VALID_GUID: {
+ const uint8_t *uu = src;
+
+ if (to == KI_VALID_UID) {
+ if (memcmp(uu, _user_compat_prefix, COMPAT_PREFIX_LEN) == 0) {
+ id_t uid;
+ memcpy(&uid, &uu[COMPAT_PREFIX_LEN], sizeof(uid));
+ *(id_t *)dst = ntohl(uid);
+ return (0);
+ }
+ } else if (to == KI_VALID_GID) {
+ if (memcmp(uu, _group_compat_prefix, COMPAT_PREFIX_LEN) == 0) {
+ id_t gid;
+ memcpy(&gid, &uu[COMPAT_PREFIX_LEN], sizeof(gid));
+ *(id_t *)dst = ntohl(gid);
+ return (0);
+ }
+ }
+ break;
+ }
+ default:
+ /* NOT IMPLEMENTED */
+ break;
+ }
+ return (ENOENT);
}
#endif
return(kauth_cred_cache_lookup(KI_VALID_GUID, KI_VALID_GID, guidp, gidp));
}
+/*
+ * kauth_cred_nfs4domain2dsnode
+ *
+ * Description: Fetch dsnode from nfs4domain
+ *
+ * Parameters: nfs4domain Pointer to a string nfs4 domain
+ * dsnode Pointer to buffer for dsnode
+ *
+ * Returns: 0 Success
+ * ENOENT For now just a stub that always fails
+ *
+ * Implicit returns:
+ * *dsnode Modified, if successuful
+ */
+int
+kauth_cred_nfs4domain2dsnode(__unused char *nfs4domain, __unused char *dsnode)
+{
+ return(ENOENT);
+}
+
+/*
+ * kauth_cred_dsnode2nfs4domain
+ *
+ * Description: Fetch nfs4domain from dsnode
+ *
+ * Parameters: nfs4domain Pointer to string dsnode
+ * dsnode Pointer to buffer for nfs4domain
+ *
+ * Returns: 0 Success
+ * ENOENT For now just a stub that always fails
+ *
+ * Implicit returns:
+ * *nfs4domain Modified, if successuful
+ */
+int
+kauth_cred_dsnode2nfs4domain(__unused char *dsnode, __unused char *nfs4domain)
+{
+ return(ENOENT);
+}
/*
* kauth_cred_ntsid2uid
* changing access to server file system objects on each
* expiration.
*/
+ if (ki.ki_supgrpcnt > NGROUPS) {
+ panic("kauth data structure corrupted. kauth identity 0x%p with %d groups, greater than max of %d",
+ &ki, ki.ki_supgrpcnt, NGROUPS);
+ }
+
el.el_sup_grp_cnt = ki.ki_supgrpcnt;
memcpy(el.el_sup_groups, ki.ki_supgrps, sizeof (el.el_sup_groups[0]) * ki.ki_supgrpcnt);
*resultp = 1;
break;
default:
-#if CONFIG_EXT_RESOLVER
{
- struct kauth_identity ki;
gid_t gid;
-#if 6603280
+#if CONFIG_EXT_RESOLVER
+ struct kauth_identity ki;
+
/*
* Grovel the identity cache looking for this GUID.
* If we find it, and it is for a user record, return
return (0);
}
}
-#endif /* 6603280 */
+#endif /* CONFIG_EXT_RESOLVER */
/*
* Attempt to translate the GUID to a GID. Even if
* this fails, we will have primed the cache if it is
error = 0;
}
} else {
+#if CONFIG_EXT_RESOLVER
do_check:
+#endif /* CONFIG_EXT_RESOLVER */
error = kauth_cred_ismember_gid(cred, gid, resultp);
}
}
-#else /* CONFIG_EXT_RESOLVER */
- error = ENOENT;
-#endif /* CONFIG_EXT_RESOLVER */
break;
}
return(error);
int i;
kauth_cred_hash_mtx = lck_mtx_alloc_init(kauth_lck_grp, 0/*LCK_ATTR_NULL*/);
- kauth_cred_table_size = kauth_cred_primes[kauth_cred_primes_index];
/*allocate credential hash table */
MALLOC(kauth_cred_table_anchor, struct kauth_cred_entry_head *,
- (sizeof(struct kauth_cred_entry_head) * kauth_cred_table_size),
+ (sizeof(struct kauth_cred_entry_head) * KAUTH_CRED_TABLE_SIZE),
M_KAUTH, M_WAITOK | M_ZERO);
if (kauth_cred_table_anchor == NULL)
panic("startup: kauth_cred_init");
- for (i = 0; i < kauth_cred_table_size; i++) {
+ for (i = 0; i < KAUTH_CRED_TABLE_SIZE; i++) {
TAILQ_INIT(&kauth_cred_table_anchor[i]);
}
}
* Returns: (kauth_cred_t) Pointer to the process's
* newly referenced credential
*
- * Locks: PROC_LOCK is held before taking the reference and released
+ * Locks: PROC_UCRED_LOCK is held before taking the reference and released
* after the refeence is taken to protect the p_ucred field of
* the process referred to by procp.
*
{
kauth_cred_t cred;
- proc_lock(procp);
+ proc_ucred_lock(procp);
cred = proc_ucred(procp);
kauth_cred_ref(cred);
- proc_unlock(procp);
+ proc_ucred_unlock(procp);
return(cred);
}
DEBUG_CRED_CHANGE("kauth_proc_setlabel_unlocked CH(%d): %p/0x%08x -> %p/0x%08x\n", p->p_pid, my_cred, my_cred->cr_flags, my_new_cred, my_new_cred->cr_flags);
- proc_lock(p);
+ proc_ucred_lock(p);
/*
* We need to protect for a race where another thread
* also changed the credential after we took our
* restart this again with the new cred.
*/
if (p->p_ucred != my_cred) {
- proc_unlock(p);
+ proc_ucred_unlock(p);
kauth_cred_unref(&my_new_cred);
my_cred = kauth_cred_proc_ref(p);
/* try again */
PROC_UPDATE_CREDS_ONPROC(p);
mac_proc_set_enforce(p, MAC_ALL_ENFORCE);
- proc_unlock(p);
+ proc_ucred_unlock(p);
}
break;
}
DEBUG_CRED_CHANGE("kauth_proc_label_update_execve_unlocked CH(%d): %p/0x%08x -> %p/0x%08x\n", p->p_pid, my_cred, my_cred->cr_flags, my_new_cred, my_new_cred->cr_flags);
- proc_lock(p);
+ proc_ucred_lock(p);
/*
* We need to protect for a race where another thread
* also changed the credential after we took our
* restart this again with the new cred.
*/
if (p->p_ucred != my_cred) {
- proc_unlock(p);
+ proc_ucred_unlock(p);
kauth_cred_unref(&my_new_cred);
my_cred = kauth_cred_proc_ref(p);
/* try again */
/* update cred on proc */
PROC_UPDATE_CREDS_ONPROC(p);
mac_proc_set_enforce(p, MAC_ALL_ENFORCE);
- proc_unlock(p);
+ proc_ucred_unlock(p);
}
break;
}
KAUTH_CRED_HASH_LOCK_ASSERT();
hash_key = kauth_cred_get_hashkey(new_cred);
- hash_key %= kauth_cred_table_size;
+ hash_key %= KAUTH_CRED_TABLE_SIZE;
/* race fix - there is a window where another matching credential
* could have been inserted between the time this one was created and we
kauth_cred_t found_cred;
hash_key = kauth_cred_get_hashkey(cred);
- hash_key %= kauth_cred_table_size;
+ hash_key %= KAUTH_CRED_TABLE_SIZE;
/* Avoid race */
if (cred->cr_ref < 1)
#endif
hash_key = kauth_cred_get_hashkey(cred);
- hash_key %= kauth_cred_table_size;
+ hash_key %= KAUTH_CRED_TABLE_SIZE;
/* Find cred in the credential hash table */
TAILQ_FOREACH(found_cred, &kauth_cred_table_anchor[hash_key], cr_link) {
printf("\n\t kauth credential hash table statistics - current cred count %d \n", kauth_cred_count);
/* count slot hits, misses, collisions, and max depth */
- for (i = 0; i < kauth_cred_table_size; i++) {
+ for (i = 0; i < KAUTH_CRED_TABLE_SIZE; i++) {
printf("[%02d] ", i);
j = 0;
TAILQ_FOREACH(found_cred, &kauth_cred_table_anchor[i], cr_link) {
return (EPERM);
/* calculate space needed */
- for (i = 0; i < kauth_cred_table_size; i++) {
+ for (i = 0; i < KAUTH_CRED_TABLE_SIZE; i++) {
TAILQ_FOREACH(found_cred, &kauth_cred_table_anchor[i], cr_link) {
counter++;
}
/* fill in creds to send back */
nextp = cred_listp;
space = 0;
- for (i = 0; i < kauth_cred_table_size; i++) {
+ for (i = 0; i < KAUTH_CRED_TABLE_SIZE; i++) {
TAILQ_FOREACH(found_cred, &kauth_cred_table_anchor[i], cr_link) {
nextp->credp = found_cred;
nextp->cr_ref = found_cred->cr_ref;