afs: Properly type afs_osi_suser cred arg
[openafs.git] / src / afs / UKERNEL / afs_usrops.c
index 4d0e843..e11e281 100644 (file)
@@ -26,9 +26,8 @@
 #include "afs/auth.h"
 #include "afs/cellconfig.h"
 #include "afs/vice.h"
-#include "afs/kauth.h"
-#include "afs/kautils.h"
 #include "afs/afsutil.h"
+#include "afs/afs_bypasscache.h"
 #include "rx/rx_globals.h"
 #include "afsd/afsd.h"
 
@@ -93,16 +92,12 @@ afs_lock_t afs_ftf;
 afs_lock_t osi_flplock;
 afs_lock_t osi_fsplock;
 
-#ifndef NETSCAPE_NSAPI
-
 /*
  * Mutex and condition variable used to implement sleep
  */
 pthread_mutex_t usr_sleep_mutex;
 pthread_cond_t usr_sleep_cond;
 
-#endif /* !NETSCAPE_NSAPI */
-
 int call_syscall(long, long, long, long, long, long);
 int fork_syscall(long, long, long, long, long, long);
 
@@ -171,13 +166,13 @@ getf(int fd)
  * Every user is a super user
  */
 int
-afs_osi_suser(void *credp)
+afs_osi_suser(afs_ucred_t *credp)
 {
     return 1;
 }
 
 int
-afs_suser(void *credp)
+afs_suser(afs_ucred_t *credp)
 {
     return 1;
 }
@@ -186,12 +181,6 @@ afs_suser(void *credp)
  * These are no-ops in user space
  */
 
-void
-afs_osi_SetTime(osi_timeval_t * atv)
-{
-    return;
-}
-
 /*
  * xflock should never fall through, the only files we know
  * about are AFS files
@@ -328,7 +317,7 @@ usr_crcopy(struct usr_ucred *credp)
 {
     struct usr_ucred *newcredp;
 
-    newcredp = (struct usr_ucred *)afs_osi_Alloc(sizeof(struct usr_ucred));
+    newcredp = afs_osi_Alloc(sizeof(struct usr_ucred));
     *newcredp = *credp;
     newcredp->cr_ref = 1;
     return newcredp;
@@ -339,7 +328,7 @@ usr_crget(void)
 {
     struct usr_ucred *newcredp;
 
-    newcredp = (struct usr_ucred *)afs_osi_Alloc(sizeof(struct usr_ucred));
+    newcredp = afs_osi_Alloc(sizeof(struct usr_ucred));
     newcredp->cr_ref = 1;
     return newcredp;
 }
@@ -390,9 +379,7 @@ uafs_InitThread(void)
      * allocate the data block, so pthread_finish can free the buffer
      * when this thread terminates.
      */
-    uptr =
-       (struct usr_user *)malloc(sizeof(struct usr_user) +
-                                 sizeof(struct usr_ucred));
+    uptr = malloc(sizeof(struct usr_user) + sizeof(struct usr_ucred));
     usr_assert(uptr != NULL);
     uptr->u_error = 0;
     uptr->u_prio = 0;
@@ -413,11 +400,12 @@ get_user_struct(void)
 {
     struct usr_user *uptr;
     int st;
-    st = usr_getspecific(afs_global_u_key, (void **)&uptr);
+
+    st = usr_getspecific(afs_global_u_key, &uptr);
     usr_assert(st == 0);
     if (uptr == NULL) {
        uafs_InitThread();
-       st = usr_getspecific(afs_global_u_key, (void **)&uptr);
+       st = usr_getspecific(afs_global_u_key, &uptr);
        usr_assert(st == 0);
        usr_assert(uptr != NULL);
     }
@@ -446,7 +434,7 @@ afs_osi_Sleep(void *x)
     }
     index = WAITHASH(x);
     if (osi_waithash_avail == NULL) {
-       waitp = (osi_wait_t *) afs_osi_Alloc(sizeof(osi_wait_t));
+       waitp = afs_osi_Alloc(sizeof(osi_wait_t));
        usr_cond_init(&waitp->cond);
     } else {
        waitp = osi_waithash_avail;
@@ -532,7 +520,7 @@ afs_osi_Wait(afs_int32 msec, struct afs_osi_WaitHandle *handle, int intok)
        }
        index = WAITHASH((caddr_t) handle);
        if (osi_waithash_avail == NULL) {
-           waitp = (osi_wait_t *) afs_osi_Alloc(sizeof(osi_wait_t));
+           waitp = afs_osi_Alloc(sizeof(osi_wait_t));
            usr_cond_init(&waitp->cond);
        } else {
            waitp = osi_waithash_avail;
@@ -659,7 +647,7 @@ osi_UFSOpen(afs_dcache_id_t *ino)
     AFS_ASSERT_GLOCK();
 
     AFS_GUNLOCK();
-    fp = (struct osi_file *)afs_osi_Alloc(sizeof(struct osi_file));
+    fp = afs_osi_Alloc(sizeof(struct osi_file));
     usr_assert(fp != NULL);
 
     usr_assert(ino->ufs);
@@ -1054,14 +1042,12 @@ osi_Init(void)
     afs_global_procp->p_ppid = (pid_t) 1;
     afs_global_procp->p_ucred = afs_global_ucredp;
 
-#ifndef NETSCAPE_NSAPI
     /*
      * Initialize the mutex and condition variable used to implement
      * time sleeps.
      */
     pthread_mutex_init(&usr_sleep_mutex, NULL);
     pthread_cond_init(&usr_sleep_cond, NULL);
-#endif /* !NETSCAPE_NSAPI */
 
     /*
      * Initialize the hash table used for sleep/wakeup
@@ -1294,7 +1280,7 @@ uafs_mount(void) {
 }
 
 void
-uafs_mountWithDir(const char *dir)
+uafs_setMountDir(const char *dir)
 {
     if (dir) {
        int rc;
@@ -1311,8 +1297,6 @@ uafs_mountWithDir(const char *dir)
            }
        }
     }
-
-    uafs_mount();
 }
 
 int
@@ -1388,13 +1372,8 @@ struct syscallThreadArgs {
     long param4;
 };
 
-#ifdef NETSCAPE_NSAPI
-void
-syscallThread(void *argp)
-#else /* NETSCAPE_NSAPI */
 void *
 syscallThread(void *argp)
-#endif                         /* NETSCAPE_NSAPI */
 {
     int i;
     struct usr_ucred *crp;
@@ -1656,6 +1635,77 @@ uafs_RPCStatsClearPeer(void)
 }
 
 /*
+ * Lookup the target of a symbolic link
+ * Call VN_HOLD on the output vnode if successful.
+ * Returns zero on success, error code on failure.
+ * If provided, use a path for confirming we are not linked to ourself.
+ *
+ * Note: Caller must hold the AFS global lock.
+ */
+static int
+uafs_LookupLinkPath(struct usr_vnode *vp, struct usr_vnode *parentVp,
+                   char *ppathP, struct usr_vnode **vpp)
+{
+    int code;
+    int len;
+    char *pathP;
+    struct usr_vnode *linkVp;
+    struct usr_uio uio;
+    struct iovec iov[1];
+
+    AFS_ASSERT_GLOCK();
+
+    pathP = afs_osi_Alloc(MAX_OSI_PATH + 1);
+    usr_assert(pathP != NULL);
+
+    /*
+     * set up the uio buffer
+     */
+    iov[0].iov_base = pathP;
+    iov[0].iov_len = MAX_OSI_PATH + 1;
+    uio.uio_iov = &iov[0];
+    uio.uio_iovcnt = 1;
+    uio.uio_offset = 0;
+    uio.uio_segflg = 0;
+    uio.uio_fmode = FREAD;
+    uio.uio_resid = MAX_OSI_PATH + 1;
+
+    /*
+     * Read the link data
+     */
+    code = afs_readlink(VTOAFS(vp), &uio, get_user_struct()->u_cred);
+    if (code) {
+       afs_osi_Free(pathP, MAX_OSI_PATH + 1);
+       return code;
+    }
+    len = MAX_OSI_PATH + 1 - uio.uio_resid;
+    pathP[len] = '\0';
+
+    /* are we linked to ourname or ./ourname? ELOOP */
+    if (ppathP) {
+       if ((strcmp(pathP, ppathP) == 0) ||
+           ((pathP[0] == '.') &&
+            (pathP[1] == '/') &&
+            (strcmp(&(pathP[2]), ppathP) == 0))) {
+           return ELOOP;
+       }
+    }
+
+    /*
+     * Find the target of the symbolic link
+     */
+    code = uafs_LookupName(pathP, parentVp, &linkVp, 1, 0);
+    if (code) {
+       afs_osi_Free(pathP, MAX_OSI_PATH + 1);
+       return code;
+    }
+
+    afs_osi_Free(pathP, MAX_OSI_PATH + 1);
+    *vpp = linkVp;
+    return 0;
+}
+
+/*
  * Lookup a file or directory given its path.
  * Call VN_HOLD on the output vnode if successful.
  * Returns zero on success, error code on failure.
@@ -1743,16 +1793,12 @@ uafs_LookupName(char *path, struct usr_vnode *parentVp,
             */
            nextVc = NULL;
            nextVp = NULL;
-#ifdef AFS_WEB_ENHANCEMENTS
            if ((nextPathP != NULL && *nextPathP != '\0') || !no_eval_mtpt)
                code = afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred, 0);
            else
                code =
                    afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred,
                               AFS_LOOKUP_NOEVAL);
-#else
-           code = afs_lookup(VTOAFS(vp), pathP, &nextVc, get_user_struct()->u_cred, 0);
-#endif /* AFS_WEB_ENHANCEMENTS */
            if (nextVc)
                nextVp=AFSTOV(nextVc);
            if (code != 0) {
@@ -1775,7 +1821,7 @@ uafs_LookupName(char *path, struct usr_vnode *parentVp,
                    afs_osi_Free(tmpPath, strlen(path) + 1);
                    return code;
                }
-               code = uafs_LookupLink(nextVp, vp, &linkVp);
+               code = uafs_LookupLinkPath(nextVp, vp, NULL, &linkVp);
                if (code) {
                    VN_RELE(vp);
                    VN_RELE(nextVp);
@@ -1806,64 +1852,11 @@ uafs_LookupName(char *path, struct usr_vnode *parentVp,
     return 0;
 }
 
-/*
- * Lookup the target of a symbolic link
- * Call VN_HOLD on the output vnode if successful.
- * Returns zero on success, error code on failure.
- *
- * Note: Caller must hold the AFS global lock.
- */
 int
 uafs_LookupLink(struct usr_vnode *vp, struct usr_vnode *parentVp,
                struct usr_vnode **vpp)
 {
-    int code;
-    int len;
-    char *pathP;
-    struct usr_vnode *linkVp;
-    struct usr_uio uio;
-    struct iovec iov[1];
-
-    AFS_ASSERT_GLOCK();
-
-    pathP = afs_osi_Alloc(MAX_OSI_PATH + 1);
-    usr_assert(pathP != NULL);
-
-    /*
-     * set up the uio buffer
-     */
-    iov[0].iov_base = pathP;
-    iov[0].iov_len = MAX_OSI_PATH + 1;
-    uio.uio_iov = &iov[0];
-    uio.uio_iovcnt = 1;
-    uio.uio_offset = 0;
-    uio.uio_segflg = 0;
-    uio.uio_fmode = FREAD;
-    uio.uio_resid = MAX_OSI_PATH + 1;
-
-    /*
-     * Read the link data
-     */
-    code = afs_readlink(VTOAFS(vp), &uio, get_user_struct()->u_cred);
-    if (code) {
-       afs_osi_Free(pathP, MAX_OSI_PATH + 1);
-       return code;
-    }
-    len = MAX_OSI_PATH + 1 - uio.uio_resid;
-    pathP[len] = '\0';
-
-    /*
-     * Find the target of the symbolic link
-     */
-    code = uafs_LookupName(pathP, parentVp, &linkVp, 1, 0);
-    if (code) {
-       afs_osi_Free(pathP, MAX_OSI_PATH + 1);
-       return code;
-    }
-
-    afs_osi_Free(pathP, MAX_OSI_PATH + 1);
-    *vpp = linkVp;
-    return 0;
+    return uafs_LookupLinkPath(vp, parentVp, NULL, vpp);
 }
 
 /*
@@ -2377,6 +2370,76 @@ uafs_read(int fd, char *buf, int len)
 }
 
 int
+uafs_pread_nocache(int fd, char *buf, int len, off_t offset)
+{
+    int retval;
+    AFS_GLOCK();
+    retval = uafs_pread_nocache_r(fd, buf, len, offset);
+    AFS_GUNLOCK();
+    return retval;
+}
+
+int
+uafs_pread_nocache_r(int fd, char *buf, int len, off_t offset)
+{
+    int code;
+    struct iovec iov[1];
+    struct usr_vnode *fileP;
+    struct nocache_read_request *bparms;
+    struct usr_uio uio;
+
+    /*
+     * Make sure this is an open file
+     */
+    fileP = afs_FileTable[fd];
+    if (fileP == NULL) {
+       errno = EBADF;
+       return -1;
+    }
+
+    /* these get freed in PrefetchNoCache, so... */
+    bparms = afs_osi_Alloc(sizeof(struct nocache_read_request));
+
+    code = afs_CreateReq(&bparms->areq, get_user_struct()->u_cred);
+    if (code) {
+       afs_DestroyReq(bparms->areq);
+       afs_osi_Free(bparms, sizeof(struct nocache_read_request));
+       errno = code;
+       return -1;
+    }
+
+    bparms->auio = &uio;
+    bparms->offset = offset;
+    bparms->length = len;
+
+    /*
+     * set up the uio buffer
+     */
+    iov[0].iov_base = buf;
+    iov[0].iov_len = len;
+    uio.uio_iov = &iov[0];
+    uio.uio_iovcnt = 1;
+    uio.uio_offset = offset;
+    uio.uio_segflg = 0;
+    uio.uio_fmode = FREAD;
+    uio.uio_resid = len;
+
+    /*
+     * do the read
+     */
+    code = afs_PrefetchNoCache(VTOAFS(fileP), get_user_struct()->u_cred,
+                              bparms);
+
+    if (code) {
+       errno = code;
+       return -1;
+    }
+
+    afs_FileOffsets[fd] = uio.uio_offset;
+    return (len - uio.uio_resid);
+}
+
+int
 uafs_pread(int fd, char *buf, int len, off_t offset)
 {
     int retval;
@@ -2393,7 +2456,6 @@ uafs_pread_r(int fd, char *buf, int len, off_t offset)
     struct usr_uio uio;
     struct iovec iov[1];
     struct usr_vnode *fileP;
-    struct usr_buf *bufP;
 
     /*
      * Make sure this is an open file
@@ -2419,7 +2481,7 @@ uafs_pread_r(int fd, char *buf, int len, off_t offset)
     /*
      * do the read
      */
-    code = afs_read(VTOAFS(fileP), &uio, get_user_struct()->u_cred, 0, &bufP, 0);
+    code = afs_read(VTOAFS(fileP), &uio, get_user_struct()->u_cred, 0);
     if (code) {
        errno = code;
        return -1;
@@ -2465,6 +2527,16 @@ uafs_GetAttr(struct usr_vnode *vp, struct stat *stats)
     stats->st_atime = attrs.va_atime.tv_sec;
     stats->st_mtime = attrs.va_mtime.tv_sec;
     stats->st_ctime = attrs.va_ctime.tv_sec;
+    /* preserve dv if possible */
+#if defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
+    stats->st_atimespec.tv_nsec = attrs.va_atime.tv_usec * 1000;
+    stats->st_mtimespec.tv_nsec = attrs.va_mtime.tv_usec * 1000;
+    stats->st_ctimespec.tv_nsec = attrs.va_ctime.tv_usec * 1000;
+#elif defined(HAVE_STRUCT_STAT_ST_CTIMENSEC)
+    stats->st_atimensec = attrs.va_atime.tv_usec * 1000;
+    stats->st_mtimensec = attrs.va_mtime.tv_usec * 1000;
+    stats->st_ctimensec = attrs.va_ctime.tv_usec * 1000;
+#endif
     stats->st_blksize = attrs.va_blocksize;
     stats->st_blocks = attrs.va_blocks;
 
@@ -2973,7 +3045,8 @@ uafs_symlink_r(char *target, char *source)
     attrs.va_mode = 0777;
     attrs.va_uid = afs_cr_uid(get_user_struct()->u_cred);
     attrs.va_gid = afs_cr_gid(get_user_struct()->u_cred);
-    code = afs_symlink(VTOAFS(dirP), nameP, &attrs, target, get_user_struct()->u_cred);
+    code = afs_symlink(VTOAFS(dirP), nameP, &attrs, target, NULL,
+                      get_user_struct()->u_cred);
     VN_RELE(dirP);
     if (code != 0) {
        errno = code;
@@ -3324,9 +3397,8 @@ uafs_opendir_r(char *path)
     /*
      * Set up the directory structures
      */
-    dirp =
-       (usr_DIR *) afs_osi_Alloc(sizeof(usr_DIR) + USR_DIRSIZE +
-                                 sizeof(struct usr_dirent));
+    dirp = afs_osi_Alloc(sizeof(usr_DIR) + USR_DIRSIZE +
+                        sizeof(struct usr_dirent));
     usr_assert(dirp != NULL);
     dirp->dd_buf = (char *)(dirp + 1);
     dirp->dd_fd = fd;
@@ -3524,34 +3596,6 @@ uafs_closedir_r(usr_DIR * dirp)
 }
 
 /*
- * Do AFS authentication
- */
-int
-uafs_klog(char *user, char *cell, char *passwd, char **reason)
-{
-    int code;
-    afs_int32 password_expires = -1;
-
-    usr_mutex_lock(&osi_authenticate_lock);
-    code =
-       ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION +
-                                  KA_USERAUTH_DOSETPAG2, user, NULL, cell,
-                                  passwd, 0, &password_expires, 0, reason);
-    usr_mutex_unlock(&osi_authenticate_lock);
-    return code;
-}
-
-int
-uafs_klog_r(char *user, char *cell, char *passwd, char **reason)
-{
-    int retval;
-    AFS_GUNLOCK();
-    retval = uafs_klog(user, cell, passwd, reason);
-    AFS_GLOCK();
-    return retval;
-}
-
-/*
  * Destroy AFS credentials from the kernel cache
  */
 int
@@ -3614,26 +3658,6 @@ uafs_afsPathName(char *path)
     return NULL;
 }
 
-#ifdef AFS_WEB_ENHANCEMENTS
-/*
- * uafs_klog_nopag
- * klog but don't allocate a new pag
- */
-int
-uafs_klog_nopag(char *user, char *cell, char *passwd, char **reason)
-{
-    int code;
-    afs_int32 password_expires = -1;
-
-    usr_mutex_lock(&osi_authenticate_lock);
-    code = ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION
-                                     /*+KA_USERAUTH_DOSETPAG2 */ , user,
-                                     NULL, cell, passwd, 0,
-                                     &password_expires, 0, reason);
-    usr_mutex_unlock(&osi_authenticate_lock);
-    return code;
-}
-
 /*
  * uafs_getcellstatus
  * get the cell status
@@ -3670,13 +3694,12 @@ uafs_getvolquota(char *path, afs_int32 * BlocksInUse, afs_int32 * MaxQuota)
 {
     int rc;
     struct afs_ioctl iob;
-    VolumeStatus *status;
-    char buf[1024];
+    VolumeStatus status;
 
     iob.in = 0;
     iob.in_size = 0;
-    iob.out = buf;
-    iob.out_size = 1024;
+    iob.out = (char *)&status;
+    iob.out_size = sizeof status;
 
     rc = call_syscall(AFSCALL_PIOCTL, (long)path, _VICEIOCTL(4), (long)&iob,
                      0, 0);
@@ -3686,9 +3709,8 @@ uafs_getvolquota(char *path, afs_int32 * BlocksInUse, afs_int32 * MaxQuota)
        return -1;
     }
 
-    status = (VolumeStatus *) buf;
-    *BlocksInUse = status->BlocksInUse;
-    *MaxQuota = status->MaxQuota;
+    *BlocksInUse = status.BlocksInUse;
+    *MaxQuota = status.MaxQuota;
     return 0;
 }
 
@@ -3701,18 +3723,15 @@ uafs_setvolquota(char *path, afs_int32 MaxQuota)
 {
     int rc;
     struct afs_ioctl iob;
-    VolumeStatus *status;
-    char buf[1024];
+    VolumeStatus status = { 0 };
 
-    iob.in = buf;
-    iob.in_size = 1024;
+    iob.in = (char *)&status;
+    iob.in_size = sizeof status;
     iob.out = 0;
     iob.out_size = 0;
 
-    memset(buf, 0, sizeof(VolumeStatus));
-    status = (VolumeStatus *) buf;
-    status->MaxQuota = MaxQuota;
-    status->MinQuota = -1;
+    status.MaxQuota = MaxQuota;
+    status.MinQuota = -1;
 
     rc = call_syscall(AFSCALL_PIOCTL, (long)path, _VICEIOCTL(5), (long)&iob,
                      0, 0);
@@ -3767,6 +3786,45 @@ uafs_statmountpoint_r(char *path)
  * Get a list of rights for the current user on path.
  */
 int
+uafs_access(char *path, int flags)
+{
+    int code;
+    struct vnode *vp;
+    int fileMode = 0;
+
+    if (flags & R_OK) {
+       fileMode |= VREAD;
+    }
+    if (flags & W_OK) {
+       fileMode |= VWRITE;
+    }
+    if (flags & X_OK) {
+       fileMode |= VEXEC;
+    }
+
+    AFS_GLOCK();
+    code = uafs_LookupName(path, afs_CurrentDir, &vp, 1, 0);
+    if (code != 0) {
+       errno = code;
+       AFS_GUNLOCK();
+       return -1;
+    }
+
+    code = afs_access(VTOAFS(vp), fileMode, get_user_struct()->u_cred);
+    VN_RELE(vp);
+
+    if (code != 0)
+       errno = code;
+
+    AFS_GUNLOCK();
+    return code ? -1 : 0;
+}
+
+/*
+ * uafs_getRights
+ * Get a list of rights for the current user on path.
+ */
+int
 uafs_getRights(char *path)
 {
     int code;
@@ -3790,6 +3848,4 @@ uafs_getRights(char *path)
     AFS_GUNLOCK();
     return afs_rights;
 }
-#endif /* AFS_WEB_ENHANCEMENTS */
-
 #endif /* UKERNEL */