- /* get current credential and take a reference while we muck with it */
- for (;;) {
- my_cred = kauth_cred_proc_ref(p);
+ if ((uthread->uu_flag & UT_SETUID) != 0) {
+ /*
+ * If this thread is under an assumed identity, set the
+ * supplementary grouplist on the thread credential instead
+ * of the process one. If we were the only reference holder,
+ * the credential is updated in place, otherwise, our reference
+ * is dropped and we get back a different cred with a reference
+ * already held on it. Because this is per-thread, we don't
+ * need the referencing/locking/retry required for per-process.
+ *
+ * Hack: this opts into memberd to avoid needing to use a per
+ * thread credential initgroups() instead of setgroups() in
+ * AFP server to address <rdar://4561060>
+ */
+ my_cred = uthread->uu_ucred;
+ uthread->uu_ucred = kauth_cred_setgroups(my_cred, &newgroups[0], ngrp, my_cred->cr_gmuid);
+ } else {