if ((ngrp = uap->gidsetsize) == 0) {
                *retval = cred->cr_ngroups;
-               kauth_cred_rele(cred);
+               kauth_cred_unref(&cred);
                return (0);
        }
        if (ngrp < cred->cr_ngroups) {
-               kauth_cred_rele(cred);
+               kauth_cred_unref(&cred);
                return (EINVAL);
        }
        ngrp = cred->cr_ngroups;
        if ((error = copyout((caddr_t)cred->cr_groups,
                                        uap->gidset, 
                                        ngrp * sizeof(gid_t)))) {
-               kauth_cred_rele(cred);
+               kauth_cred_unref(&cred);
                return (error);
        }
-       kauth_cred_rele(cred);
+       kauth_cred_unref(&cred);
        *retval = ngrp;
        return (0);
 }
                my_cred = kauth_cred_proc_ref(p);
                
                /* 
-                * set the credential with new info.  If there is no change we get back 
-                * the same credential we passed in.
+                * Set the credential with new info.  If there is no change,
+                * we get back the same credential we passed in; if there is
+                * a change, we drop the reference on the credential we
+                * passed in.  The subsequent compare is safe, because it is
+                * a pointer compare rather than a contents compare.
                 */
                my_new_cred = kauth_cred_setuid(my_cred, uid);
                if (my_cred != my_new_cred) {
                         */
                        if (p->p_ucred != my_cred) {
                                proc_unlock(p);
-                               kauth_cred_rele(my_cred);
-                               kauth_cred_rele(my_new_cred);
+                               kauth_cred_unref(&my_new_cred);
                                /* try again */
                                continue;
                        }
                        p->p_flag |= P_SUGID;
                        proc_unlock(p);
                }
-               /* drop our extra reference */
-               kauth_cred_rele(my_cred);
+               /* drop old proc reference or our extra reference */
+               kauth_cred_unref(&my_cred);
                break;
        }
        
                my_cred = kauth_cred_proc_ref(p);
        
                /* 
-                * set the credential with new info.  If there is no change we get back 
-                * the same credential we passed in.
+                * Set the credential with new info.  If there is no change,
+                * we get back the same credential we passed in; if there is
+                * a change, we drop the reference on the credential we
+                * passed in.  The subsequent compare is safe, because it is
+                * a pointer compare rather than a contents compare.
                 */
-               my_new_cred = kauth_cred_seteuid(p->p_ucred, euid);
+               my_new_cred = kauth_cred_seteuid(my_cred, euid);
        
                if (my_cred != my_new_cred) {
                        proc_lock(p);
-                       /* need to protect for a race where another thread also changed
-                        * the credential after we took our reference.  If p_ucred has 
-                        * changed then we should restart this again with the new cred.
+                       /*
+                        * We need to protect for a race where another thread
+                        * also changed the credential after we took our
+                        * reference.  If p_ucred has changed then we should
+                        * restart this again with the new cred.
                         */
                        if (p->p_ucred != my_cred) {
                                proc_unlock(p);
-                               kauth_cred_rele(my_cred);
-                               kauth_cred_rele(my_new_cred);
+                               kauth_cred_unref(&my_new_cred);
                                /* try again */
                                continue;
                        }
                        p->p_flag |= P_SUGID;
                        proc_unlock(p);
                }
-               /* drop our extra reference */
-               kauth_cred_rele(my_cred);
+               /* drop old proc reference or our extra reference */
+               kauth_cred_unref(&my_cred);
                break;
        }
 
                my_cred = kauth_cred_proc_ref(p);
                
                /* 
-                * set the credential with new info.  If there is no change we get back 
-                * the same credential we passed in.
+                * Set the credential with new info.  If there is no change,
+                * we get back the same credential we passed in; if there is
+                * a change, we drop the reference on the credential we
+                * passed in.  The subsequent compare is safe, because it is
+                * a pointer compare rather than a contents compare.
                 */
-               my_new_cred = kauth_cred_setgid(p->p_ucred, gid);
+               my_new_cred = kauth_cred_setgid(my_cred, gid);
                if (my_cred != my_new_cred) {
                        proc_lock(p);
-                       /* need to protect for a race where another thread also changed
-                        * the credential after we took our reference.  If p_ucred has 
-                        * changed then we should restart this again with the new cred.
+                       /*
+                        * We need to protect for a race where another thread
+                        * also changed the credential after we took our
+                        * reference.  If p_ucred has changed then we should
+                        * restart this again with the new cred.
                         */
                        if (p->p_ucred != my_cred) {
                                proc_unlock(p);
-                               kauth_cred_rele(my_cred);
-                               kauth_cred_rele(my_new_cred);
+                               kauth_cred_unref(&my_new_cred);
                                /* try again */
                                continue;
                        }
                        p->p_flag |= P_SUGID;
                        proc_unlock(p);
                }
-               /* drop our extra reference */
-               kauth_cred_rele(my_cred);
+               /* drop old proc reference or our extra reference */
+               kauth_cred_unref(&my_cred);
                break;
        }
        
                my_cred = kauth_cred_proc_ref(p);
                
                /* 
-                * set the credential with new info.  If there is no change we get back 
-                * the same credential we passed in.
+                * Set the credential with new info.  If there is no change,
+                * we get back the same credential we passed in; if there is
+                * a change, we drop the reference on the credential we
+                * passed in.  The subsequent compare is safe, because it is
+                * a pointer compare rather than a contents compare.
                 */
-               my_new_cred = kauth_cred_setegid(p->p_ucred, egid);
+               my_new_cred = kauth_cred_setegid(my_cred, egid);
                if (my_cred != my_new_cred) {
                        proc_lock(p);
                        /* need to protect for a race where another thread also changed
                         */
                        if (p->p_ucred != my_cred) {
                                proc_unlock(p);
-                               kauth_cred_rele(my_cred);
-                               kauth_cred_rele(my_new_cred);
+                               kauth_cred_unref(&my_new_cred);
                                /* try again */
                                continue;
                        }
                        p->p_flag |= P_SUGID;
                        proc_unlock(p);
                }
-               /* drop our extra reference */
-               kauth_cred_rele(my_cred);
+               /* drop old proc reference or our extra reference */
+               kauth_cred_unref(&my_cred);
                break;
        }
 
 
                /* revert to delayed binding of process credential */
                uc = kauth_cred_proc_ref(p);
-               kauth_cred_rele(uthread->uu_ucred);
+               kauth_cred_unref(&uthread->uu_ucred);
                uthread->uu_ucred = uc;
                uthread->uu_flag &= ~UT_SETUID;
        } else {
                uthread->uu_flag |= UT_SETUID;
 
                /* drop our extra reference */
-               kauth_cred_rele(my_cred);
+               kauth_cred_unref(&my_cred);
        }
        /*
         * XXX should potentially set per thread security token (there is
                uthread->uu_flag |= UT_SETUID;
                
                /* drop our extra references */
-               kauth_cred_rele(my_cred);
-               kauth_cred_rele(my_target_cred);
+               kauth_cred_unref(&my_cred);
+               kauth_cred_unref(&my_target_cred);
 
                return (0);
        }
 
        /* revert to delayed binding of process credential */
        my_new_cred = kauth_cred_proc_ref(p);
-       kauth_cred_rele(uthread->uu_ucred);
+       kauth_cred_unref(&uthread->uu_ucred);
        uthread->uu_ucred = my_new_cred;
        uthread->uu_flag &= ~UT_SETUID;
        
                        my_cred = kauth_cred_proc_ref(p);
 
                        /* 
-                        * set the credential with new info.  If there is no
-                        * change we get back the same credential we passed in.
+                        * Set the credential with new info.  If there is no
+                        * change, we get back the same credential we passed
+                        * in; if there is a change, we drop the reference on
+                        * the credential we passed in.  The subsequent
+                        * compare is safe, because it is a pointer compare
+                        * rather than a contents compare.
                         */
                        my_new_cred = kauth_cred_setgroups(my_cred, &newgroups[0], ngrp, gmuid);
                        if (my_cred != my_new_cred) {
                                 */
                                if (p->p_ucred != my_cred) {
                                        proc_unlock(p);
-                                       kauth_cred_rele(my_cred);
-                                       kauth_cred_rele(my_new_cred);
+                                       kauth_cred_unref(&my_new_cred);
                                        /* try again */
                                        continue;
                                }
                                p->p_flag |= P_SUGID;
                                proc_unlock(p);
                        }
-                       /* drop our extra reference */
-                       kauth_cred_rele(my_cred);
+                       /* drop old proc reference or our extra reference */
+                       kauth_cred_unref(&my_cred);
                        break;
                }
 
 suser(kauth_cred_t cred, u_short *acflag)
 {
 #if DIAGNOSTIC
-       if (cred == NOCRED || cred == FSCRED)
+       if (!IS_VALID_CRED(cred))
                panic("suser");
 #endif
        if (kauth_cred_getuid(cred) == 0) {
        }
                
        /* XXX mach_init doesn't have a p_ucred when it calls this function */
-       if (p->p_ucred != NOCRED && p->p_ucred != FSCRED) {
+       if (IS_VALID_CRED(p->p_ucred)) {
                sec_token.val[0] = kauth_cred_getuid(p->p_ucred);
                sec_token.val[1] = p->p_ucred->cr_gid;
        } else {