+ MALLOC(cr, struct ucred *, sizeof(*cr), M_CRED, M_WAITOK);
+ bzero((caddr_t)cr, sizeof(*cr));
+ cr->cr_ref = 1;
+ return(cr);
+}
+
+/*
+ * Free a cred structure.
+ * Throws away space when ref count gets to 0.
+ */
+crfree(cr)
+ struct ucred *cr;
+{
+ int s = splimp();
+
+ if (--cr->cr_ref != 0) {
+ (void) splx(s);
+ return;
+ }
+ FREE((caddr_t)cr, M_CRED);
+ (void) splx(s);
+}
+
+/*
+ * Copy cred structure to a new one and free the old one.
+ */
+struct ucred *
+crcopy(cr)
+ struct ucred *cr;
+{
+ struct ucred *newcr;
+
+ newcr = crget();
+ *newcr = *cr;
+ crfree(cr);
+ newcr->cr_ref = 1;
+ return(newcr);
+}
+
+/*
+ * Dup cred struct to a new held one.
+ */
+struct ucred *
+crdup(cr)
+ struct ucred *cr;
+{
+ struct ucred *newcr;
+
+ newcr = crget();
+ *newcr = *cr;
+ newcr->cr_ref = 1;
+ return(newcr);
+}
+
+/*
+ * Get login name of process owner, if available
+ */
+
+getlogname()
+{
+ struct a {
+ char *namebuf;
+ u_int namelen;
+ } *uap = (struct a *)u.u_ap;
+
+ if (uap->namelen > sizeof (u.u_logname))
+ uap->namelen = sizeof (u.u_logname);
+ u.u_error = copyout((caddr_t)u.u_logname, (caddr_t)uap->namebuf,
+ uap->namelen);
+}
+
+/*
+ * Set login name of process owner
+ */
+
+setlogname()
+{
+ struct a {
+ char *namebuf;
+ u_int namelen;
+ } *uap = (struct a *)u.u_ap;
+
+ if (u.u_error = suser(u.u_cred, &u.u_acflag))
+ return;
+ if (uap->namelen > sizeof (u.u_logname) - 1)
+ u.u_error = EINVAL;
+ else
+ u.u_error = copyin((caddr_t)uap->namebuf,
+ (caddr_t)u.u_logname, uap->namelen);