Beispiel #1
0
int
fs_incompat_renumber(int *ret)
{
    struct ViceIoctl a_params;
    unsigned char buf[1024];

    a_params.in_size = 0;
    a_params.out_size = sizeof(buf);
    a_params.in = 0;
    a_params.out = (caddr_t) buf;

    /* getcrypt or getinitparams */
    if (pioctl(NULL, _VICEIOCTL(49), &a_params, 0) < 0) {
	if (errno == EINVAL) {

	    /* not openafs or old openafs */

	    a_params.in_size = 0;
	    a_params.out_size = 4;
	    a_params.in = 0;
	    a_params.out = (caddr_t) buf;

	    if (pioctl(NULL, _VICEIOCTL(49), &a_params, 0) < 0) {
		if (errno == EINVAL) {

		    a_params.in_size = 0;
		    a_params.out_size = 4;
		    a_params.in = 0;
		    a_params.out = (caddr_t) buf;

		    /* might be new interface */

		    if (pioctl(NULL, _VICEIOCTL(55), &a_params, 0) < 0)
			return errno;	/* dunno */

		    *ret = 1;
		    return 0;
		} else {
		    return errno;
		}
	    }
	    *ret = 0;
	    return 0;
	} else
	    return errno;
    }
    *ret = 1;
    return 0;
}
Beispiel #2
0
/* Returns 0 and fills outfid and outvv with fid and version vector
   for specified Coda path.  If version vector is not accessible,
   the StoreId fields of outvv are set to -1.
   Garbage may be copied into outvv for non-replicated files
   
   Returns -1 after printing error msg on failures. */
int getfid(char *path, ViceFid *outfid, char *outrealm, ViceVersionVector *outvv)
{
    int rc;
    struct ViceIoctl vi;
    char junk[2048];

    vi.in = NULL;
    vi.in_size = 0;
    vi.out = junk;
    vi.out_size = (short) sizeof(junk);
    memset(junk, 0, (int) sizeof(junk));

    rc = pioctl(path, _VICEIOCTL(_VIOC_GETFID), &vi, 0);

    /* Easy: no conflicts */
    if (!rc) {
	memcpy(outfid, junk, sizeof(ViceFid));
	memcpy(outvv, junk+sizeof(ViceFid), sizeof(ViceVersionVector));
	strcpy(outrealm, junk+sizeof(ViceFid)+sizeof(ViceVersionVector));
	return(0);
    }

    /* if there are conflicts then can't use this object for the
       repair anyway.  A begin repair should have been done by this
       point. */
    return(-1);
}
Beispiel #3
0
/* Implements the remote setpag(2) call. Note that unlike the standard call,
 * here we also get back the new pag value; we need this so that the caller
 * can add it to its group list via setgroups() */
afs_int32
SRMTSYS_SetPag(struct rx_call *call, clientcred *creds, afs_int32 *newpag,
	       afs_int32 *errornumber)
{
    afs_uint32 blob[PIOCTL_HEADER];
    struct ViceIoctl data;
    afs_int32 error;

    *errornumber = 0;
    SETCLIENTCONTEXT(blob, rx_HostOf(rx_PeerOf(rx_ConnectionOf(call))), creds->uid,
		     creds->group0, creds->group1, PSETPAG, NFS_EXPORTER);
    data.in = (caddr_t) blob;
    data.in_size = sizeof(blob);
    data.out = (caddr_t) blob;
    data.out_size = sizeof(blob);
    /* force local pioctl call */
    error = lpioctl(0, _VICEIOCTL(PSetClientContext), &data, 1);
    if (error) {
	if (errno == PSETPAG) {
	    *newpag = blob[0];	/* new pag value */
	} else
	    *errornumber = errno;
    }
    return 0;
}
Beispiel #4
0
static int
NFSUnlog(afs_int32 ahost, afs_int32 auid)
{
    afs_int32 code;
    afs_int32 pheader[6];
    char space[1200];
    struct ViceIoctl blob;

    /* otherwise we've got the token, now prepare to build the pioctl args */
    pheader[0] = ahost;
    pheader[1] = auid;
    pheader[2] = 0;		/* group low */
    pheader[3] = 0;		/* group high */
    pheader[4] = 9;		/* unlog pioctl index */
    pheader[5] = 1;		/* NFS protocol exporter # */

    /* copy stuff in */
    memcpy(space, pheader, sizeof(pheader));

    /* finally setup the pioctl call's parameters */
    blob.in_size = sizeof(pheader);
    blob.in = space;
    blob.out_size = 0;
    blob.out = NULL;
    code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
    if (code) {
	code = errno;
    }
    return code;
}
Beispiel #5
0
int main(int argc, char **argv) 
{
    ViceFid fid;
    char realm[MAXHOSTNAMELEN+1];
    char tmpfname[80];
    int fd;
    struct ViceIoctl vioc;
    char space[2048];
    int rc;

    if (argc != 2) {
	fprintf(stderr, "Usage: %s <inc-file-name>\n", argv[0]);
	exit(-1);
    }
    
    /* make sure object is inconsistent */
    if (!IsObjInc(argv[1], &fid, realm)) {
	fprintf(stderr, "%s isn't inconsistent\n", argv[1]);
	exit(0);
    }
    
    /* get fid and make sure it is a file */
    if (ISDIR(fid) && !FID_IsLocalDir(&fid)) {
	fprintf(stderr, "%s is a directory - must be removed manually\n", argv[1]);
	exit(-1);
    }

    /* create an empty file /tmp/REPAIR.XXXXXX */
    strcpy(tmpfname, "/tmp/RMINC.XXXXXX");
    if ((fd = mkstemp(tmpfname)) < 0) {
	fprintf(stderr, "Couldn't create /tmp file\n");
	exit(-1);
    }
    close(fd);

    /* dorepair on the fid with an empty file */
    vioc.in_size = (short)(1+strlen(tmpfname)); 
    vioc.in = tmpfname;
    vioc.out_size = (short) sizeof(space);
    vioc.out = space;
    memset(space, 0, (int) sizeof(space));
    rc = pioctl(argv[1], _VICEIOCTL(_VIOC_REPAIR), &vioc, 0);
    if (rc < 0 && errno != ETOOMANYREFS) {
	fprintf(stderr, "Error %d for repair\n", errno);
	unlink(tmpfname);
	exit(-1);
    }
    unlink(tmpfname);

    /* remove the repaired file */
    if (unlink(argv[1])) {
	fprintf(stderr, "Couldn't remove %s\n", argv[1]);
	exit(-1);
    }
    exit(0);
}
Beispiel #6
0
int IsObjInc(char *name, ViceFid *fid, char *realm) 
{
    struct GetFid {
	ViceFid fid;
	ViceVersionVector vv;
	char realm[MAXHOSTNAMELEN+1];
    } out;
    struct ViceIoctl vio;
    struct stat statbuf;
    char symval[MAXPATHLEN];
    int rc, n;

    memset(fid, 0, sizeof(ViceFid));
    realm[0] = '\0';

    /* what if the begin repair has been done already */
    rc = stat(name, &statbuf);
    if (rc) {
	/* is it a sym link */
	symval[0] = 0;
	rc = readlink(name, symval, MAXPATHLEN);
	if (rc < 0) return(0);

	/* it's a sym link, alright */
	n = sscanf(symval, "@%x.%x.%x@%s",
		   &fid->Volume, &fid->Vnode, &fid->Unique, realm);

	return(n == 4);
    }

    memset(&out, 0, sizeof(out));
    vio.in = NULL;
    vio.in_size = 0;
    vio.out = (char *)&out;
    vio.out_size = sizeof(out);

    rc = pioctl(name, _VICEIOCTL(_VIOC_GETFID), &vio, 0);
    if (rc < 0 && errno != ETOOMANYREFS) {
	fprintf(stderr, "Error %d for Getfid\n", errno);
	return(0);
    }
    memcpy(fid, &out.fid, sizeof(ViceFid));
    strcpy(realm, out.realm);

    if (!ISDIR(out.fid) && (statbuf.st_mode & S_IFDIR))
	return(1);

    if (out.vv.StoreId.Host == -1) 
	return(1);

    return(0);
}
Beispiel #7
0
int main(int argc, char **argv) {
    struct stat statbuf;
    int rc;
    ViceFid fixfid;
    char fixrealm[MAXHOSTNAMELEN];
    vv_t fixvv;
    char fixpath[MAXPATHLEN];
    struct ViceIoctl vioc;
    char space[2048];

    if (argc != 3) {
	fprintf(stderr, "Usage: %s <inc-file-name> <merged-file-name>\n", argv[0]);
	exit(-1);
    }

    /*  make sure repair file exists  */
    rc = stat(argv[2], &statbuf);
    if (rc != 0) {
	fprintf(stderr, "Couldn't find %s(errno = %d)\n", argv[2], errno);
	exit(-1);
    }
    if (!(statbuf.st_mode & S_IFREG)) {
	fprintf(stderr, "File %s cannot be used for repair\n", argv[2]);
	exit(-1);
    }

    if (!getfid(argv[2], &fixfid, fixrealm, &fixvv))
	sprintf(fixpath, "@%08x.%08x.%08x@%s", fixfid.Volume, fixfid.Vnode, fixfid.Unique, fixrealm);
    else strcpy(fixpath, argv[2]);
	
    /* do the repair */
    vioc.in_size = (short)(1+strlen(fixpath));
    vioc.in = fixpath;
    vioc.out_size = (short)sizeof(space);
    vioc.out = space;
    memset(space, 0, sizeof(space));
    rc = pioctl(argv[1], _VICEIOCTL(_VIOC_REPAIR), &vioc, 0);
    if (rc < 0 && errno != ETOOMANYREFS) {
	fprintf(stderr, "Error %d for repair\n", errno);
	exit(-1);
    }
	
    if (stat(argv[1], &statbuf)) 
	exit(-1);
    exit(0);
}
Beispiel #8
0
/* Implements the remote pioctl(2) call */
afs_int32
SRMTSYS_Pioctl(struct rx_call *call, clientcred *creds, char *path,
	       afs_int32 cmd, afs_int32 follow, rmtbulk *InData,
	       rmtbulk *OutData, afs_int32 *errornumber)
{
    afs_int32 error;
    struct ViceIoctl data;
    char *pathp = path;
    afs_uint32 blob[PIOCTL_HEADER];

    *errornumber = 0;
    SETCLIENTCONTEXT(blob, rx_HostOf(call->conn->peer), creds->uid,
		     creds->group0, creds->group1, cmd, NFS_EXPORTER);
    data.in =
	(char *)malloc(InData->rmtbulk_len +
		       PIOCTL_HEADER * sizeof(afs_int32));
    if (!data.in)
	return (-1);		/* helpless here */
    if (!strcmp(path, NIL_PATHP))
	pathp = (char *)0;	/* It meant to be NIL */
    memcpy(data.in, blob, sizeof(blob));
    inparam_conversion(cmd, InData->rmtbulk_val, 1);
    memcpy(data.in + sizeof(blob), InData->rmtbulk_val, InData->rmtbulk_len);
    data.in_size = InData->rmtbulk_len + PIOCTL_HEADER * sizeof(afs_int32);
    data.out = OutData->rmtbulk_val;
    data.out_size = OutData->rmtbulk_len;
    /* force local pioctl call */
    error = lpioctl(pathp, _VICEIOCTL(PSetClientContext), &data, follow);
    if (error) {
	*errornumber = errno;
    } else {
	/* Send the results back in network order */
	outparam_conversion(cmd, data.out, 0);
    }
    free(data.in);
    /* Note that we return success (i.e. 0) even when pioctl fails; that's
     * because the actual errno is passed back via 'errornumber' and this call
     * MUST return success error in order to get that OUT params back (YUCK!)
     */
    return (0);
}
Beispiel #9
0
static int
SetSysname(afs_int32 ahost, afs_int32 auid, char *sysname)
{
    afs_int32 code;
    afs_int32 pheader[6];
    char space[1200], *tp;
    struct ViceIoctl blob;
    afs_int32 setp = 1;

    /* otherwise we've got the token, now prepare to build the pioctl args */
    pheader[0] = ahost;
    pheader[1] = auid;
    pheader[2] = 0;		/* group low */
    pheader[3] = 0;		/* group high */
    pheader[4] = 38 /*VIOC_AFS_SYSNAME */ ;	/* sysname pioctl index */
    pheader[5] = 1;		/* NFS protocol exporter # */

    /* copy stuff in */
    memcpy(space, pheader, sizeof(pheader));
    tp = space + sizeof(pheader);

    /* finally setup the pioctl call's parameters */
    blob.in_size = sizeof(pheader);
    blob.in = space;
    blob.out_size = 0;
    blob.out = NULL;
    memcpy(tp, &setp, sizeof(afs_int32));
    tp += sizeof(afs_int32);
    strcpy(tp, sysname);
    blob.in_size += sizeof(afs_int32) + strlen(sysname) + 1;
    tp += strlen(sysname);
    *(tp++) = '\0';
    code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
    if (code) {
	code = errno;
    }
    return code;
}
Beispiel #10
0
/*
 * Copy
 * 	This does the bulk of the work of the program.  Handle one file,
 *	possibly copying subfiles if this is a directory
 */
static int
Copy(char *file1, char *file2, short recursive, int level)
{
    struct stat s1, s2;		/*Stat blocks */
    struct ViceIoctl blob;
    char aclspace[MAXACL];
    afs_int32 rcode = 0, code;
    int goods2 = 1;

    code = lstat(file1, &s1);
    if (code < 0) {
	fprintf(stderr, "Can't find %s\n", file1);
	return 1;
    }

    code = lstat(file2, &s2);
    if (code < 0) {
	if (!MakeParent(file2, s1.st_uid))
	    return 0;
	goods2 = 0;
    }

    if ((s1.st_mode & S_IFMT) == S_IFREG) {
	/*
	 * -------------------- Copy regular file --------------------
	 */
	int f1, f2, n;
	char buf[4096];		/* Must be bigger than sizeof (*head) */
	struct timeval tv[2];
	char tmpfile[MAXPATHLEN], newName[MAXPATHLEN];

	if (verbose) {
	    printf("Level %d: File %s to %s\n", level, file1, file2);
	    fflush(stdout);
	}

	/* Wonder if there is a security hole */
	if (((s1.st_mode & 04002) == 04002) || ((s1.st_mode & 04020) == 04020)
	    || ((s1.st_mode & 02002) == 02002)) {
	    fprintf(stderr,
		    "WARNING: Mode-bits security hole in files %s and %s\n",
		    file1, file2);
	}

	if (!goods2 || (s1.st_mtime != s2.st_mtime) || (s1.st_size != s2.st_size)) {	/*c */
	    /* Don't ovewrite a write protected file (unless force: -f) */
	    if (!forceOverwrite && goods2 && (s2.st_mode & 0200) == 0) {
		fprintf(stderr,
			"File %s is write protected against its owner; not changed\n",
			file2);
		return 1;
	    }

	    if (verbose) {
		printf("  Copy file %s to %s (%u Bytes)\n", file1, file2,
		       (unsigned int) s1.st_size);
		fflush(stdout);
	    }

	    strlcpy(tmpfile, file2, sizeof tmpfile);	/* Name of temporary file */
	    strlcat(tmpfile, ".UPD", sizeof tmpfile);

	    /* open file1 for input */
	    f1 = open(file1, O_RDONLY);
	    if (f1 < 0) {
		fprintf(stderr, "Unable to open input file %s: %s\n",
			file1, strerror(errno));
		return 1;
	    }

	    /* open temporary output file */
	    f2 = open(tmpfile, (O_WRONLY | O_CREAT | O_TRUNC), s1.st_mode);
	    if (f2 < 0) {
		fprintf(stderr, "Unable to open output file %s: %s\n",
			tmpfile, strerror(errno));
		fflush(stdout);
		close(f1);
		return 1;
	    }

	    /* Copy file1 to temporary file */
	    while ((n = read(f1, buf, sizeof(buf))) > 0) {
		if (write(f2, buf, n) != n) {
		    fprintf(stderr,
			    "Write failed, file %s must be copied again.\n",
			    file2);
		}
	    }

	    /* preserve access and modification times: ("-x" disables) */
	    if (preserveDate) {
		tv[0].tv_sec = s1.st_atime;
		tv[0].tv_usec = 0;
		tv[1].tv_sec = s1.st_mtime;
		tv[1].tv_usec = 0;
		utimes(tmpfile, tv);
	    }

	    /* Close the files */
	    code = close(f1);
	    code = close(f2);
	    if (code < 0) {
		perror("close ");
		rcode = 1;
	    }

	    /* Rename file2 to file2.old. [-r] */
	    if (renameTargets && goods2) {
		strlcpy(newName, file2, sizeof newName);
		strlcat(newName, ".old", sizeof newName);
		if (verbose) {
		    printf("  Renaming %s to %s\n", file2, newName);
		    fflush(stdout);
		}
		if (rename(file2, newName) < 0) {
		    fprintf(stderr, "Rename of %s to %s failed.\n", file2,
			    newName);
		}
	    }

	    /* Rename temporary file to file2 */
	    code = rename(tmpfile, file2);
	    if (code < 0) {
		fprintf(stderr, "Rename of %s to %s failed.\n", tmpfile,
			file2);
		return 1;
	    }

	    /* Re-stat file2 and compare file sizes */
	    code = lstat(file2, &s2);
	    if (code < 0) {
		fprintf(stderr, "WARNING: Unable to stat new file %s\n",
			file2);
		return 1;
	    }
	    if (s1.st_size != s2.st_size) {
		fprintf(stderr,
			"WARNING: New file %s is %u bytes long; should be %u\n",
			file2, (unsigned int) s2.st_size, 
			(unsigned int) s1.st_size);
	    }
	}

	/*c */
	/* Set the user-id */
	if (s2.st_uid != s1.st_uid) {
	    if (verbose) {
		printf("  Set owner-id for %s to %d\n", file2, s1.st_uid);
		fflush(stdout);
	    }
	    code = chown(file2, s1.st_uid, -1);
	    if (code) {
		fprintf(stderr, "Unable to set owner-id for %s to %d\n",
			file2, s1.st_uid);
		fflush(stdout);
		rcode = 1;
		s1.st_mode &= ~04000;	/* Don't set suid bit */
	    }
	}

	/* Set the group-id */
	if (s2.st_gid != s1.st_gid) {
	    if (verbose) {
		printf("  Set group-id for %s to %d\n", file2, s1.st_gid);
		fflush(stdout);
	    }
	    code = chown(file2, -1, s1.st_gid);
	    if (code) {
		fprintf(stderr, "Unable to set group-id for %s to %d\n",
			file2, s1.st_gid);
		fflush(stdout);
		rcode = 1;
		s1.st_mode &= ~02000;	/* Don't set sgid bit */
	    }
	}

	/* Set the mode bits */
	if (s1.st_mode != s2.st_mode) {
	    if (verbose) {
		printf("  Set mode-bit for %s to %o\n", file2,
		       (s1.st_mode & 07777));
		fflush(stdout);
	    }
	    code = chmod(file2, s1.st_mode);
	    if (code) {
		fprintf(stderr, "Unable to set mode-bits for %s to %d\n",
			file2, s1.st_mode);
		rcode = 1;
	    }
	}
    }
    /* regular file */
    else if ((s1.st_mode & S_IFMT) == S_IFLNK) {
	/*
	 * --------------------- Copy symlink  --------------------
	 */
	char linkvalue[MAXPATHLEN + 1];
	int n;

	if (verbose) {
	    printf("Level %d: Symbolic link %s to %s\n", level, file1, file2);
	    fflush(stdout);
	}

	/* Don't ovewrite a write protected directory (unless force: -f) */
	if (!forceOverwrite && goods2 && (s2.st_mode & 0200) == 0) {
	    fprintf(stderr,
		    "Link %s is write protected against its owner; not changed\n",
		    file2);
	    return 1;
	}

	if (verbose) {
	    printf("  Copy symbolic link %s->%s to %s\n", file1, linkvalue,
		   file2);
	    fflush(stdout);
	}

	n = readlink(file1, linkvalue, sizeof(linkvalue));
	if (n == -1) {
	    fprintf(stderr, "Could not read symbolic link %s\n", file1);
	    perror("read link ");
	    return 1;
	}
	linkvalue[n] = 0;

	unlink(file2);		/* Always make the new link (it was easier) */

	code = symlink(linkvalue, file2);
	if (code == -1) {
	    fprintf(stderr, "Could not create symbolic link %s\n", file2);
	    perror("create link ");
	    return 1;
	}
    }
    /*Dealing with symlink */
    else if (preserveMountPoints && (code = isMountPoint(file1, &blob))) {
	/*
	 * --------------------- Copy mount point  --------------------
	 */

	if (code > 1) {
	    perror("checking for mount point ");
	    return 1;
	}
	if (verbose) {
	    printf("Level %d: Mount point %s to %s\n", level, file1, file2);
	    fflush(stdout);
	}

	/* Don't ovewrite a write protected directory (unless force: -f) */
	if (!forceOverwrite && goods2 && (s2.st_mode & 0200) == 0) {
	    fprintf(stderr,
		    "Target %s is write protected against its owner; not changed\n",
		    file2);
	    return 1;
	}

	if (verbose) {
	    printf("  Copy mount point %s for vol %s to %s\n", file1,
		   blob.out, file2);
	    fflush(stdout);
	}

	unlink(file2);		/* Always make the new link (it was easier) */

	strcat(blob.out, ".");	/* stupid convention; these end with a period */
	code = symlink(blob.out, file2);
	if (code == -1) {
	    fprintf(stderr, "Could not create mount point %s for vol %s\n",
		    file2, blob.out);
	    perror("create mount point ");
	    return 1;
	}

    }
    /*Dealing with mount point */
    else if (((s1.st_mode & S_IFMT) == S_IFDIR)
	     && (recursive || (level == 0))) {
	/*
	 * ----------------------- Copy directory -----------------------
	 */
	DIR *dir;
	int tfd, code, i;
	struct OldAcl *oacl;
	char tacl[MAXACL];
	char f1[MAXPATHLEN], f2[MAXPATHLEN];
	char *p1, *p2;
	struct dirent *d;
	struct timeval tv[2];

	if (verbose) {
	    printf("Level %d: Directory %s to %s\n", level, file1, file2);
	    fflush(stdout);
	}

	/* Don't ovewrite a write protected directory (unless force: -f) */
	if (!forceOverwrite && goods2 && (s2.st_mode & 0200) == 0) {
	    fprintf(stderr,
		    "Directory %s is write protected against its owner; not changed\n",
		    file2);
	    return 1;
	}

	strlcpy(f1, file1, sizeof f1);
	strlcpy(f2, file2, sizeof f2);
	p1 = f1 + strlen(f1);
	p2 = f2 + strlen(f2);
	if (p1 == f1 || p1[-1] != '/')
	    *p1++ = '/';
	if (p2 == f2 || p2[-1] != '/')
	    *p2++ = '/';

	dir = opendir(file1);
	if (dir == NULL) {
	    fprintf(stderr, "Couldn't open %s\n", file1);
	    return 1;
	}

	while ((d = readdir(dir)) != NULL) {
	    if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0)
		continue;
	    strlcpy(p1, d->d_name, sizeof f1 - (p1 - f1));
	    strlcpy(p2, d->d_name, sizeof f2 - (p2 - f2));
	    code = Copy(f1, f2, recursive, level + 1);
	    if (code && !rcode)
		rcode = 1;	/* remember errors */
	}

	closedir(dir);

	if (verbose) {
	    printf("Level %d: Copied directory %s to %s\n", level, file1,
		   file2);
	    fflush(stdout);
	}

	mkdir(file2, 0777);	/* Handle case where MakeParent not invoked. */

	if (verbose) {
	    printf("  Set owner-id for %s to %d\n", file2, s1.st_uid);
	    fflush(stdout);
	}
	code = chown(file2, s1.st_uid, -1);
	if (code) {
	    fprintf(stderr, "Unable to set owner-id for %s to %d\n", file2,
		    s1.st_uid);
	    fflush(stdout);
	    s1.st_mode &= ~04000;	/* Don't set suid bit */
	}

	if (verbose) {
	    printf("  Set group-id for %s to %d\n", file2, s1.st_gid);
	    fflush(stdout);
	}
	code = chown(file2, -1, s1.st_gid);
	if (code) {
	    fprintf(stderr, "Unable to set group-id for %s to %d\n", file2,
		    s1.st_gid);
	    fflush(stdout);
	    s1.st_mode &= ~02000;	/* Don't set sgid bit */
	}

	if (verbose) {
	    printf("  Set mode-bit for %s to %o\n", file2,
		   (s1.st_mode & 07777));
	    fflush(stdout);
	}
	code = chmod(file2, s1.st_mode);
	if (code) {
	    fprintf(stderr, "Unable to set mode-bits for %s to %d\n", file2,
		    s1.st_mode);
	    fflush(stdout);
	    rcode = 1;
	}

	if (setacl == 1) {
	    if (verbose) {
		printf("  Set acls for %s\n", file2);
		fflush(stdout);
	    }

	    blob.in = aclspace;
	    blob.out = aclspace;
	    blob.in_size = 0;
	    blob.out_size = MAXACL;

	    if (oldAcl) {
		/* Get an old-style ACL and convert it */
                if (verbose) {
                    printf("  Getting old style acl\n");
                    fflush(stdout);
                }

		for (i = 1; i < strlen(file1); i++)
		    if (file1[i] == '/')
			break;
		strlcpy(aclspace, &file1[i], sizeof aclspace);

		blob.in_size = 1 + strlen(aclspace);
		tfd = open(file1, O_RDONLY, 0);
		if (tfd < 0) {
		    perror("old-acl open ");
		    return 1;
		}
		code = ioctl(tfd, _VICEIOCTL(4), &blob);
		close(tfd);
		if (code < 0) {
		    if (errno == EINVAL) {
			setacl = 0;
                        if (verbose) {
                            printf("  _VICEIOCTL(4) returns EINVAL\n");
                            fflush(stdout);
                        }
		    } else {
			return 1;
		    }
		}
		/* Now convert the thing. */
		oacl = (struct OldAcl *)(aclspace + 4);
		sprintf(tacl, "%d\n%d\n", oacl->nplus, oacl->nminus);
		strlcat(tacl, oacl->data, sizeof tacl);
		strlcpy(aclspace, tacl, sizeof aclspace);
	    } /*Grab and convert old-style ACL */
	    else {
		/* Get a new-style ACL */
                if (verbose) {
                    printf("  Getting new style acl\n");
                    fflush(stdout);
                }

		code = pioctl(file1, _VICEIOCTL(2), &blob, 1);
		if (code < 0) {
		    if (errno == EINVAL) {
			setacl = 0;
                        if (verbose) {
                            printf("  _VICEIOCTL(2) returns EINVAL\n");
                            fflush(stdout);
                        }
		    } else {
			perror("getacl ");
			return 1;
		    }
		}
	    }			/*Grab new-style ACL */

	    /*
	     * Now, set the new-style ACL.
	     */
	    if (setacl == 1) {
                if (verbose) {
                    printf("  Setting new style acl\n");
                    fflush(stdout);
                }
		blob.out = aclspace;
		blob.in = aclspace;
		blob.out_size = 0;
		blob.in_size = 1 + strlen(aclspace);
		code = pioctl(file2, _VICEIOCTL(1), &blob, 1);
		if (code) {
		    if (errno == EINVAL) {
			setacl = 0;
                        if (verbose) {
                            printf("  _VICEIOCTL(1) returns EINVAL\n");
                            fflush(stdout);
                        }
		    } else {
			fprintf(stderr, "Couldn't set acls for %s\n", file2);
			return 1;
		    }
		}
	    }

	    if (setacl == 0) {
		printf("Not setting acls\n");
	    }
	}

        /* preserve access and modification times: ("-x" disables) */
        if (preserveDate) {
            tv[0].tv_sec = s1.st_atime;
            tv[0].tv_usec = 0;
            tv[1].tv_sec = s1.st_mtime;
            tv[1].tv_usec = 0;
            utimes(file2, tv);
        }
    }

    return rcode;
}				/*Copy */
Beispiel #11
0
static int
GetTokens(afs_int32 ahost, afs_int32 auid)
{
    struct ViceIoctl iob;
    afs_int32 pheader[6];
    char tbuffer[1024];
    afs_int32 code = 0;
    int index, newIndex;
    char *stp;			/* secret token ptr */
    struct ClearToken ct;
    char *tp;
    afs_int32 temp, gotit = 0;
    int maxLen;			/* biggest ticket we can copy */
    int tktLen;			/* server ticket length */
    time_t tokenExpireTime;
    char UserName[MAXKTCNAMELEN + MAXKTCNAMELEN];
    struct ktc_token token;
    struct ktc_principal clientName;
    time_t current_time;
    char *expireString;

    current_time = time(0);

    /* otherwise we've got the token, now prepare to build the pioctl args */
    pheader[0] = ahost;
    pheader[1] = auid;
    pheader[2] = 0;		/* group low */
    pheader[3] = 0;		/* group high */
    pheader[4] = 8;		/* gettoken pioctl index */
    pheader[5] = 1;		/* NFS protocol exporter # */

    for (index = 0; index < 200; index++) {	/* sanity check in case pioctl fails */
	code = ktc_ListTokens(index, &newIndex, &clientName);
	if (code) {
	    if (code == KTC_NOENT) {
		/* all done */
		if (!gotit)
		    printf("knfs: there are no tokens here.\n");
		code = 0;
	    }
	    break;		/* done, but failed */
	}
	if (strcmp(clientName.name, "afs") != 0)
	    continue;		/* wrong ticket service */

	/* copy stuff in */
	memcpy(tbuffer, pheader, sizeof(pheader));
	tp = tbuffer + sizeof(pheader);
	memcpy(tp, &index, sizeof(afs_int32));
	tp += sizeof(afs_int32);
	iob.in = tbuffer;
	iob.in_size = sizeof(afs_int32) + sizeof(pheader);
	iob.out = tbuffer;
	iob.out_size = sizeof(tbuffer);
	code = pioctl(NULL, _VICEIOCTL(99), &iob, 0);
	if (code < 0 && errno == EDOM)
	    return KTC_NOENT;
	else if (code == 0) {
	    /* check to see if this is the right cell/realm */
	    tp = tbuffer;
	    memcpy(&temp, tp, sizeof(afs_int32));	/* get size of secret token */
	    tktLen = temp;	/* remember size of ticket */
	    tp += sizeof(afs_int32);
	    stp = tp;		/* remember where ticket is, for later */
	    tp += temp;		/* skip ticket for now */
	    memcpy(&temp, tp, sizeof(afs_int32));	/* get size of clear token */
	    if (temp != sizeof(struct ClearToken))
		return KTC_ERROR;
	    tp += sizeof(afs_int32);	/* skip length */
	    memcpy(&ct, tp, temp);	/* copy token for later use */
	    tp += temp;		/* skip clear token itself */
	    tp += sizeof(afs_int32);	/* skip primary flag */
	    /* tp now points to the cell name */
	    if (strcmp(tp, clientName.cell) == 0) {
		/* closing in now, we've got the right cell */
		gotit = 1;
		maxLen =
		    sizeof(token) - sizeof(struct ktc_token) +
		    MAXKTCTICKETLEN;
		if (maxLen < tktLen)
		    return KTC_TOOBIG;
		memcpy(token.ticket, stp, tktLen);
		token.startTime = ct.BeginTimestamp;
		token.endTime = ct.EndTimestamp;
		if (ct.AuthHandle == -1)
		    ct.AuthHandle = 999;
		token.kvno = ct.AuthHandle;
		memcpy(&token.sessionKey, ct.HandShakeKey,
		       sizeof(struct ktc_encryptionKey));
		token.ticketLen = tktLen;
		if ((token.kvno == 999) ||	/* old style bcrypt ticket */
		    (ct.BeginTimestamp &&	/* new w/ prserver lookup */
		     (((ct.EndTimestamp - ct.BeginTimestamp) & 1) == 1))) {
		    sprintf(clientName.name, "AFS ID %d", ct.ViceId);
		    clientName.instance[0] = 0;
		} else {
		    sprintf(clientName.name, "Unix UID %d", ct.ViceId);
		    clientName.instance[0] = 0;
		}
		strlcpy(clientName.cell, tp, sizeof(clientName.cell));

		tokenExpireTime = token.endTime;
		strlcpy(UserName, clientName.name, sizeof(UserName));
		if (clientName.instance[0] != 0) {
		    strlcat(UserName, ".", sizeof(UserName));
		    strlcat(UserName, clientName.instance, sizeof(UserName));
		}
		if (UserName[0] == 0)
		    printf("Tokens");
		else if (strncmp(UserName, "AFS ID", 6) == 0) {
		    printf("User's (%s) tokens", UserName);
		} else if (strncmp(UserName, "Unix UID", 8) == 0) {
		    printf("Tokens");
		} else
		    printf("User %s's tokens", UserName);
		printf(" for %s%s%s@%s ", clientName.name,
		       clientName.instance[0] ? "." : "", clientName.instance,
		       clientName.cell);
		if (tokenExpireTime <= current_time)
		    printf("[>> Expired <<]\n");
		else {
		    expireString = ctime(&tokenExpireTime);
		    expireString += 4;	/*Move past the day of week */
		    expireString[12] = '\0';
		    printf("[Expires %s]\n", expireString);
		}

	    }
	}
    }
    return code;
}
Beispiel #12
0
/* Copy the AFS service token into the kernel for a particular host and user */
static int
NFSCopyToken(afs_int32 ahost, afs_int32 auid)
{
    struct ktc_principal client, server;
    struct ktc_token theTicket;
    afs_int32 code;
    afs_int32 pheader[6];
    char space[1200];
    struct ClearToken ct;
    afs_int32 index, newIndex;
    afs_int32 temp;		/* for bcopy */
    char *tp;
    struct ViceIoctl blob;

    for (index = 0;; index = newIndex) {
	code = ktc_ListTokens(index, &newIndex, &server);
	if (code) {
	    if (code == KTC_NOENT) {
		/* all done */
		code = 0;
	    }
	    break;		/* done, but failed */
	}
	if (strcmp(server.name, "afs") != 0)
	    continue;		/* wrong ticket service */
	code = ktc_GetToken(&server, &theTicket, sizeof(theTicket), &client);
	if (code)
	    return code;

	/* otherwise we've got the token, now prepare to build the pioctl args */
	pheader[0] = ahost;
	pheader[1] = auid;
	pheader[2] = 0;		/* group low */
	pheader[3] = 0;		/* group high */
	pheader[4] = 3;		/* set token pioctl index */
	pheader[5] = 1;		/* NFS protocol exporter # */

	/* copy in the header */
	memcpy(space, pheader, sizeof(pheader));
	tp = space + sizeof(pheader);
	/* copy in the size of the encrypted part */
	memcpy(tp, &theTicket.ticketLen, sizeof(afs_int32));
	tp += sizeof(afs_int32);
	/* copy in the ticket itself */
	memcpy(tp, theTicket.ticket, theTicket.ticketLen);
	tp += theTicket.ticketLen;
	/* copy in "clear token"'s size */
	temp = sizeof(struct ClearToken);
	memcpy(tp, &temp, sizeof(afs_int32));
	tp += sizeof(afs_int32);
	/* create the clear token and copy *it* in */
	ct.AuthHandle = theTicket.kvno;	/* where we hide the key version # */
	memcpy(ct.HandShakeKey, &theTicket.sessionKey,
	       sizeof(ct.HandShakeKey));

	ct.ViceId = auid;
	ct.BeginTimestamp = theTicket.startTime;
	ct.EndTimestamp = theTicket.endTime;
	memcpy(tp, &ct, sizeof(ct));
	tp += sizeof(ct);
	/* copy in obsolete primary flag */
	temp = 0;
	memcpy(tp, &temp, sizeof(afs_int32));
	tp += sizeof(afs_int32);
	/* copy in cell name, null terminated */
	strcpy(tp, server.cell);
	tp += strlen(server.cell) + 1;

	/* finally setup the pioctl call's parameters */
	blob.in_size = tp - space;
	blob.in = space;
	blob.out_size = 0;
	blob.out = NULL;
	code = pioctl(NULL, _VICEIOCTL(99), &blob, 0);
	if (code) {
	    code = errno;
	    break;
	}
    }
    return code;
}