+ 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, if available.
+ */
+/* ARGSUSED */
+getlogin(p, uap, retval)
+ struct proc *p;
+ struct args {
+ char *namebuf;
+ u_int namelen;
+ } *uap;
+ int *retval;
+{
+
+ if (uap->namelen > sizeof (p->p_logname))
+ uap->namelen = sizeof (p->p_logname);
+ return (copyout((caddr_t)p->p_logname, (caddr_t)uap->namebuf,
+ uap->namelen));
+}
+
+/*
+ * Set login name.
+ */
+/* ARGSUSED */
+setlogin(p, uap, retval)
+ struct proc *p;
+ struct args {
+ char *namebuf;
+ } *uap;
+ int *retval;
+{
+ int error;
+
+ if (error = suser(u.u_cred, &u.u_acflag))
+ return (error);
+ error = copyinstr((caddr_t)uap->namebuf, (caddr_t)p->p_logname,
+ sizeof (p->p_logname) - 1, (int *) 0);
+ if (error == ENOENT) /* name too long */
+ error = EINVAL;
+ return (error);