fs discon support alternate uid
[openafs.git] / src / afs / afs_pioctl.c
index 5b140ef..931abf1 100644 (file)
 #ifdef AFS_OBSD_ENV
 #include "h/syscallargs.h"
 #endif
-#ifdef AFS_FBSD50_ENV
+#ifdef AFS_FBSD_ENV
 #include "h/sysproto.h"
 #endif
+#ifdef AFS_NBSD40_ENV
+#include <sys/ioctl.h>
+#include <sys/ioccom.h>
+#endif
 #include "afsincludes.h"       /* Afs-based standard headers */
 #include "afs/afs_stats.h"     /* afs statistics */
 #include "afs/vice.h"
@@ -29,14 +33,12 @@ afs_int32 afs_waitForever = 0;
 short afs_waitForeverCount = 0;
 afs_int32 afs_showflags = GAGUSER | GAGCONSOLE;        /* show all messages */
 
-#ifdef AFS_DISCON_ENV
 afs_int32 afs_is_disconnected;
 afs_int32 afs_is_discon_rw;
 /* On reconnection, turn this knob on until it finishes,
  * then turn it off.
  */
 afs_int32 afs_in_sync = 0;
-#endif
 
 struct afs_pdata {
     char *ptr;
@@ -49,7 +51,8 @@ struct afs_pdata {
  */
 
 static_inline int
-afs_pd_alloc(struct afs_pdata *apd, size_t size) {
+afs_pd_alloc(struct afs_pdata *apd, size_t size)
+{
 
     if (size > AFS_LRALLOCSIZ)
        apd->ptr = osi_Alloc(size + 1);
@@ -65,7 +68,8 @@ afs_pd_alloc(struct afs_pdata *apd, size_t size) {
 }
 
 static_inline void
-afs_pd_free(struct afs_pdata *apd) {
+afs_pd_free(struct afs_pdata *apd)
+{
     if (apd->ptr == NULL)
        return;
 
@@ -79,17 +83,20 @@ afs_pd_free(struct afs_pdata *apd) {
 }
 
 static_inline char *
-afs_pd_where(struct afs_pdata *apd) {
+afs_pd_where(struct afs_pdata *apd)
+{
     return apd ? apd->ptr : NULL;
 }
 
 static_inline size_t
-afs_pd_remaining(struct afs_pdata *apd) {
+afs_pd_remaining(struct afs_pdata *apd)
+{
     return apd ? apd->remaining : 0;
 }
 
 static_inline int
-afs_pd_skip(struct afs_pdata *apd, size_t skip) {
+afs_pd_skip(struct afs_pdata *apd, size_t skip)
+{
     if (apd == NULL || apd->remaining < skip)
        return EINVAL;
     apd->remaining -= skip;
@@ -99,7 +106,8 @@ afs_pd_skip(struct afs_pdata *apd, size_t skip) {
 }
 
 static_inline int
-afs_pd_getInt(struct afs_pdata *apd, afs_int32 *val) {
+afs_pd_getInt(struct afs_pdata *apd, afs_int32 *val)
+{
     if (apd == NULL || apd->remaining < sizeof(afs_int32))
        return EINVAL;
     apd->remaining -= sizeof(afs_int32);
@@ -109,12 +117,14 @@ afs_pd_getInt(struct afs_pdata *apd, afs_int32 *val) {
 }
 
 static_inline int
-afs_pd_getUint(struct afs_pdata *apd, afs_uint32 *val) {
+afs_pd_getUint(struct afs_pdata *apd, afs_uint32 *val)
+{
     return afs_pd_getInt(apd, (afs_int32 *)val);
 }
 
 static_inline int
-afs_pd_getBytes(struct afs_pdata *apd, void *dest, size_t bytes) {
+afs_pd_getBytes(struct afs_pdata *apd, void *dest, size_t bytes)
+{
     if (apd == NULL || apd->remaining < bytes)
        return EINVAL;
     apd->remaining -= bytes;
@@ -124,7 +134,8 @@ afs_pd_getBytes(struct afs_pdata *apd, void *dest, size_t bytes) {
 }
 
 static_inline void *
-afs_pd_inline(struct afs_pdata *apd, size_t bytes) {
+afs_pd_inline(struct afs_pdata *apd, size_t bytes)
+{
     void *ret;
 
     if (apd == NULL || apd->remaining < bytes)
@@ -139,7 +150,8 @@ afs_pd_inline(struct afs_pdata *apd, size_t bytes) {
 }
 
 static_inline int
-afs_pd_getString(struct afs_pdata *apd, char *str, size_t maxLen) {
+afs_pd_getString(struct afs_pdata *apd, char *str, size_t maxLen)
+{
     size_t len;
 
     if (apd == NULL || apd->remaining <= 0)
@@ -154,7 +166,8 @@ afs_pd_getString(struct afs_pdata *apd, char *str, size_t maxLen) {
 }
 
 static_inline int
-afs_pd_getStringPtr(struct afs_pdata *apd, char **str) {
+afs_pd_getStringPtr(struct afs_pdata *apd, char **str)
+{
     size_t len;
 
     if (apd == NULL || apd->remaining <= 0)
@@ -167,7 +180,8 @@ afs_pd_getStringPtr(struct afs_pdata *apd, char **str) {
 }
 
 static_inline int
-afs_pd_putInt(struct afs_pdata *apd, afs_int32 val) {
+afs_pd_putInt(struct afs_pdata *apd, afs_int32 val)
+{
     if (apd == NULL || apd->remaining < sizeof(afs_int32))
        return E2BIG;
     *(afs_int32 *)apd->ptr = val;
@@ -178,7 +192,8 @@ afs_pd_putInt(struct afs_pdata *apd, afs_int32 val) {
 }
 
 static_inline int
-afs_pd_putBytes(struct afs_pdata *apd, const void *bytes, size_t len) {
+afs_pd_putBytes(struct afs_pdata *apd, const void *bytes, size_t len)
+{
     if (apd == NULL || apd->remaining < len)
        return E2BIG;
     memcpy(apd->ptr, bytes, len);
@@ -280,7 +295,6 @@ DECL_PIOCTL(PPrecache);
 DECL_PIOCTL(PGetPAG);
 #if defined(AFS_CACHE_BYPASS)
 DECL_PIOCTL(PSetCachingThreshold);
-DECL_PIOCTL(PSetCachingBlkSize);
 #endif
 
 /*
@@ -781,7 +795,7 @@ afs_xioctl(afs_proc_t *p, register struct ioctl_args *uap, register_t *retval)
     return (code);
 }
 #elif defined(AFS_XBSD_ENV)
-# if !defined(AFS_FBSD50_ENV)
+# if defined(AFS_FBSD_ENV)
 #  define arg data
 int
 afs_xioctl(struct thread *td, register struct ioctl_args *uap,
@@ -802,9 +816,14 @@ afs_xioctl(afs_proc_t *p, register struct ioctl_args *uap, register_t *retval)
     register struct filedesc *fdp;
     register struct vcache *tvc;
     register int ioctlDone = 0, code = 0;
+    struct file *fd;
 
     AFS_STATCNT(afs_xioctl);
+#   if defined(AFS_NBSD40_ENV)
+     fdp = p->l_proc->p_fd;
+#   else
     fdp = p->p_fd;
+#endif
     if ((u_int) uap->fd >= fdp->fd_nfiles
        || (fd = fdp->fd_ofiles[uap->fd]) == NULL)
        return EBADF;
@@ -841,12 +860,13 @@ afs_xioctl(afs_proc_t *p, register struct ioctl_args *uap, register_t *retval)
     }
 
     if (!ioctlDone) {
-# if defined(AFS_FBSD50_ENV)
+# if defined(AFS_FBSD_ENV)
        return ioctl(td, uap);
-# elif defined(AFS_FBSD_ENV)
-       return ioctl(p, uap);
 # elif defined(AFS_OBSD_ENV)
        code = sys_ioctl(p, uap, retval);
+# elif defined(AFS_NBSD_ENV)
+           struct lwp *l = osi_curproc();
+           code = sys_ioctl(l, uap, retval);
 # endif
     }
 
@@ -928,7 +948,7 @@ afs_pioctl(struct pioctlargs *uap, rval_t * rvp)
 # endif
 }
 
-#elif defined(AFS_FBSD50_ENV)
+#elif defined(AFS_FBSD_ENV)
 int
 afs_pioctl(struct thread *td, void *args, int *retval)
 {
@@ -956,14 +976,18 @@ afs_pioctl(afs_proc_t *p, void *args, int *retval)
     } *uap = (struct a *)args;
 
     AFS_STATCNT(afs_pioctl);
-# ifdef AFS_DARWIN80_ENV
+# if defined(AFS_DARWIN80_ENV) || defined(AFS_NBSD40_ENV)
     return (afs_syscall_pioctl
            (uap->path, uap->cmd, uap->cmarg, uap->follow,
             kauth_cred_get()));
 # else
     return (afs_syscall_pioctl
            (uap->path, uap->cmd, uap->cmarg, uap->follow,
+#  if defined(AFS_FBSD_ENV)
+            td->td_ucred));
+#  else
             p->p_cred->pc_ucred));
+#  endif
 # endif
 }
 
@@ -1100,7 +1124,8 @@ afs_syscall_pioctl(char *path, unsigned int com, caddr_t cmarg, int follow)
 #else
        code = gop_lookupname_user(path, AFS_UIOUSER, follow, &vp);
 #if defined(AFS_FBSD80_ENV) /* XXX check on 7x */
-       VN_HOLD(vp);
+       if (vp != NULL)
+               VN_HOLD(vp);
 #endif /* AFS_FBSD80_ENV */
 #endif /* AFS_LINUX22_ENV */
 #endif /* AFS_AIX41_ENV */
@@ -1376,7 +1401,8 @@ DECL_PIOCTL(PGetFID)
  *
  * \post Changed ACL, via direct writing to the wire
  */
-int dummy_PSetAcl(char *ain, char *aout)
+int
+dummy_PSetAcl(char *ain, char *aout)
 {
     return 0;
 }
@@ -1833,16 +1859,11 @@ DECL_PIOCTL(PSetTokens)
     if (set_parent_pag) {
        afs_uint32 pag;
 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
-# if defined(AFS_DARWIN_ENV)
-       afs_proc_t *p = current_proc(); /* XXX */
-# else
-       afs_proc_t *p = curproc;        /* XXX */
-# endif
-# ifndef AFS_DARWIN80_ENV
-       uprintf("Process %d (%s) tried to change pags in PSetTokens\n",
-               p->p_pid, p->p_comm);
-# endif
-       if (!setpag(p, acred, -1, &pag, 1)) {
+       char procname[256];
+       osi_procname(procname, 256);
+       afs_warnuser("Process %d (%s) tried to change pags in PSetTokens\n",
+                    MyPidxx2Pid(MyPidxx), procname);
+       if (!setpag(osi_curproc(), acred, -1, &pag, 1)) {
 #else
        if (!setpag(acred, -1, &pag, 1)) {
 #endif
@@ -1872,6 +1893,7 @@ DECL_PIOCTL(PSetTokens)
     afs_SetPrimary(tu, flag);
     tu->tokenTime = osi_Time();
     afs_ResetUserConns(tu);
+    afs_NotifyUser(tu, UTokensObtained);
     afs_PutUser(tu, WRITE_LOCK);
 
     return 0;
@@ -2265,6 +2287,7 @@ DECL_PIOCTL(PGetTokens)
     if (((tu->states & UHasTokens) == 0)
        || (tu->ct.EndTimestamp < osi_Time())) {
        tu->states |= (UTokensBad | UNeedsReset);
+       afs_NotifyUser(tu, UTokensDropped);
        afs_PutUser(tu, READ_LOCK);
        return ENOTCONN;
     }
@@ -2343,6 +2366,7 @@ DECL_PIOCTL(PUnlog)
            memset(&tu->ct, 0, sizeof(struct ClearToken));
            tu->refCount++;
            ReleaseWriteLock(&afs_xuser);
+           afs_NotifyUser(tu, UTokensDropped);
            /* We have to drop the lock over the call to afs_ResetUserConns,
             * since it obtains the afs_xvcache lock.  We could also keep
             * the lock, and modify ResetUserConns to take parm saying we
@@ -3401,17 +3425,13 @@ DECL_PIOCTL(PFlushVolumeData)
                    goto loop;
                }
 #ifdef AFS_DARWIN80_ENV
-           if (tvc->f.states & CDeadVnode) {
-               if (!(tvc->f.states & CBulkFetching)) {
-                   ReleaseReadLock(&afs_xvcache);
-                   afs_osi_Sleep(&tvc->f.states);
-                   goto loop;
+               if (tvc->f.states & CDeadVnode) {
+                   if (!(tvc->f.states & CBulkFetching)) {
+                       ReleaseReadLock(&afs_xvcache);
+                       afs_osi_Sleep(&tvc->f.states);
+                       goto loop;
+                   }
                }
-           }
-#endif
-#if    defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)  || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV)
-               VN_HOLD(AFSTOV(tvc));
-#elif defined(AFS_DARWIN80_ENV)
                vp = AFSTOV(tvc);
                if (vnode_get(vp))
                    continue;
@@ -3426,10 +3446,8 @@ DECL_PIOCTL(PFlushVolumeData)
                    vnode_recycle(AFSTOV(tvc));
                    AFS_GLOCK();
                }
-#elif defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
-               osi_vnhold(tvc, 0);
 #else
-               VREFCOUNT_INC(tvc); /* AIX, apparently */
+               AFS_FAST_HOLD(tvc);
 #endif
                ReleaseReadLock(&afs_xvcache);
 #ifdef AFS_BOZONLOCK_ENV
@@ -3844,7 +3862,7 @@ afs_setsprefs(struct spref *sp, unsigned int num, unsigned int vlonly)
     touchedSize = 0;
     for (k = 0; k < num; sp++, k++) {
        if (debugsetsp) {
-           printf("sp host=%x, rank=%d\n", sp->host.s_addr, sp->rank);
+           afs_warn("sp host=%x, rank=%d\n", sp->host.s_addr, sp->rank);
        }
        matches = 0;
        ObtainReadLock(&afs_xserver);
@@ -3864,7 +3882,7 @@ afs_setsprefs(struct spref *sp, unsigned int num, unsigned int vlonly)
 
        if (sa && matches) {    /* found one! */
            if (debugsetsp) {
-               printf("sa ip=%x, ip_rank=%d\n", sa->sa_ip, sa->sa_iprank);
+               afs_warn("sa ip=%x, ip_rank=%d\n", sa->sa_ip, sa->sa_iprank);
            }
            sa->sa_iprank = sp->rank + afs_randomMod15();
            afs_SortOneServer(sa->server);
@@ -4466,15 +4484,15 @@ HandleClientContext(struct afs_ioctl *ablob, int *com,
     newcred->cr_groupset.gs_union.un_groups[1] = g1;
 #elif defined(AFS_LINUX26_ENV)
 # ifdef AFS_LINUX26_ONEGROUP_ENV
-    set_cr_group_info(newcred, groups_alloc(1)); /* nothing sets this */
+    afs_set_cr_group_info(newcred, groups_alloc(1)); /* nothing sets this */
     l = (((g0-0x3f00) & 0x3fff) << 14) | ((g1-0x3f00) & 0x3fff);
     h = ((g0-0x3f00) >> 14);
     h = ((g1-0x3f00) >> 14) + h + h + h;
-    GROUP_AT(cr_group_info(newcred), 0) = ((h << 28) | l);
+    GROUP_AT(afs_cr_group_info(newcred), 0) = ((h << 28) | l);
 # else
-    set_cr_group_info(newcred, groups_alloc(2));
-    GROUP_AT(cr_group_info(newcred), 0) = g0;
-    GROUP_AT(cr_group_info(newcred), 1) = g1;
+    afs_set_cr_group_info(newcred, groups_alloc(2));
+    GROUP_AT(afs_cr_group_info(newcred), 0) = g0;
+    GROUP_AT(afs_cr_group_info(newcred), 1) = g1;
 # endif
 #elif defined(AFS_SUN510_ENV)
     gids[0] = g0;
@@ -4487,7 +4505,7 @@ HandleClientContext(struct afs_ioctl *ablob, int *com,
 #ifdef AFS_AIX_ENV
     newcred->cr_ngrps = 2;
 #elif !defined(AFS_LINUX26_ENV) && !defined(AFS_SUN510_ENV)
-# if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX22_ENV)
+# if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV) || defined(AFS_LINUX22_ENV) || defined(AFS_FBSD80_ENV)
     newcred->cr_ngroups = 2;
 # else
     for (i = 2; i < NGROUPS; i++)
@@ -4987,7 +5005,7 @@ DECL_PIOCTL(PSetCachingThreshold)
 {
     afs_int32 getting = 1;
     afs_int32 setting = 1;
-    afs_int32 threshold;
+    afs_int32 threshold = AFS_CACHE_BYPASS_DISABLED;
 
     if (afs_pd_getInt(ain, &threshold) != 0)
        setting = 0;
@@ -5117,13 +5135,13 @@ DECL_PIOCTL(PCallBackAddr)
 
 DECL_PIOCTL(PDiscon)
 {
-#ifdef AFS_DISCON_ENV
     static afs_int32 mode = 1; /* Start up in 'off' */
     afs_int32 force = 0;
     int code = 0;
-    char flags[3];
+    char flags[4];
+    struct vrequest lreq;
 
-    if (afs_pd_getBytes(ain, &flags, 3) == 0) {
+    if (afs_pd_getBytes(ain, &flags, 4) == 0) {
        if (!afs_osi_suser(*acred))
            return EPERM;
 
@@ -5133,6 +5151,12 @@ DECL_PIOCTL(PDiscon)
            afs_ConflictPolicy = flags[1] - 1;
        if (flags[2])
            force = 1;
+       if (flags[3]) {
+           /* Fake InitReq support for UID override */
+           memset(&lreq, 0, sizeof(lreq));
+           lreq.uid = flags[3];
+           areq = &lreq; /* override areq we got */
+       }
 
        /*
         * All of these numbers are hard coded in fs.c. If they
@@ -5158,7 +5182,7 @@ DECL_PIOCTL(PDiscon)
            afs_in_sync = 0;
 
            if (code && !force) {
-               printf("Files not synchronized properly, still in discon state. \n"
+               afs_warnuser("Files not synchronized properly, still in discon state. \n"
                       "Please retry or use \"force\".\n");
                mode = 0;
            } else {
@@ -5168,7 +5192,7 @@ DECL_PIOCTL(PDiscon)
                afs_ClearAllStatdFlag();
                afs_is_disconnected = 0;
                afs_is_discon_rw = 0;
-               printf("\nSync succeeded. You are back online.\n");
+               afs_warnuser("\nSync succeeded. You are back online.\n");
            }
 
            ReleaseWriteLock(&afs_discon_lock);
@@ -5184,9 +5208,6 @@ DECL_PIOCTL(PDiscon)
        return code;
 
     return afs_pd_putInt(aout, mode);
-#else
-    return EINVAL;
-#endif
 }
 
 DECL_PIOCTL(PNFSNukeCreds)