2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * Implementation of the AFS system operations exported by the
16 * --------------------- Required definitions ---------------------
18 #include <afsconfig.h>
19 #include <afs/param.h>
24 #include "uss_fs.h" /*Interface to this module */
25 #include <sys/types.h>
27 #include <sys/socket.h>
29 #include <sys/ioccom.h>
31 #include <netinet/in.h>
35 #include <afs/venus.h>
36 #include "uss_common.h"
40 * ---------------------- Private definitions ---------------------
46 * ------------------------ Private globals -----------------------
48 static struct ViceIoctl blob; /*Param-passing area */
49 static struct ViceIoctl *blobP = &blob; /*Ptr to above */
52 /*------------------------------------------------------------------------
56 * Is the given pathname in AFS?
59 * a_path : Pathname to examine.
62 * 0 if the pathname is NOT in AFS,
66 * Nothing interesting.
70 *------------------------------------------------------------------------*/
74 register char *a_path;
78 static char rn[] = "uss_fs:InAFS";
79 register afs_int32 code;
83 blob.out_size = USS_FS_MAX_SIZE;
84 blob.out = uss_fs_OutBuff;
86 code = pioctl(a_path, VIOC_FILE_CELL_NAME, blobP, 1);
88 if ((errno == EINVAL) || (errno == ENOENT))
96 /*------------------------------------------------------------------------
97 * static ParentAndComponent
100 * Calculate the parent directory of the given pathname, along
101 * with the final component.
104 * char *a_path : Pathname to ancestorize.
105 * char *a_parentBuff : Ptr to parent buffer to use.
106 * char **a_componentPP : Ptr to the final component.
110 * Ptr to the buffer containing the parent dir name.
113 * Nothing interesting.
117 *------------------------------------------------------------------------*/
120 ParentAndComponent(a_path, a_parentBuff, a_componentPP)
123 char **a_componentPP;
125 { /*ParentAndComponent */
127 static char rn[] = "uss_fs:Parent";
131 * Copy over the original pathname, then find the location of the
132 * rightmost slash. If there is one, we chop off the string at
133 * point. Otherwise, it is a single pathname component whose
134 * parent must be the current working directory. In this case,
135 * we cheat and return ``.''.
137 strcpy(a_parentBuff, a_path);
138 rightSlashP = (char *)strrchr(a_parentBuff, '/');
141 *a_componentPP = rightSlashP + 1;
143 strcpy(a_parentBuff, ".");
144 *a_componentPP = a_path;
147 return (a_parentBuff);
149 } /*ParentAndComponent */
152 /*------------------------------------------------------------------------
153 * static CarefulPioctl
156 * Execute a pioctl(), but be careful to refresh the Cache Manager's
157 * volume mapping in case we get an ENODEV the first time.
160 * char *a_path : pioctl() pathname argument.
161 * int a_opcode : pioctl() opcode.
162 * struct ViceIoctl *a_blobP : pioctl() blob pointer.
163 * int a_sl : pioctl() symlink info.
166 * Whatever the pioctl() returned, either the after the first
167 * call if we didn't get an ENODEV, or the results of the second
171 * Nothing interesting.
175 *------------------------------------------------------------------------*/
178 CarefulPioctl(a_path, a_opcode, a_blobP, a_sl)
181 struct ViceIoctl *a_blobP;
186 static char rn[] = "uss_fs:CarefulPioctl";
187 register afs_int32 code;
190 * Call the pioctl() the first time, return if things worked
194 printf("%s: First pioctl call\n", rn);
195 #endif /* USS_FS_DB */
196 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
199 printf("%s: First pioctl call fails, errno is %d\n", rn, errno);
200 #endif /* USS_FS_DB */
201 if ((code == 0) || (code && (errno != ENODEV)))
205 * Hmm, it's possible out volume mappings are stale. Let's
206 * bring them up to date, then try again.
209 printf("%s: First pioctl got a NODEV\n", rn);
210 #endif /* USS_FS_DB */
211 code = uss_fs_CkBackups();
212 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
218 /*------------------------------------------------------------------------
219 * EXPORTED uss_fs_GetACL
222 * Nothing interesting.
226 *------------------------------------------------------------------------*/
229 uss_fs_GetACL(a_dirPath, a_aclBuff, a_aclBuffBytes)
232 afs_int32 a_aclBuffBytes;
236 static char rn[] = "uss_fs_GetACL"; /*Routine name */
237 register afs_int32 code; /*pioctl() result */
241 blob.out = a_aclBuff;
242 blob.out_size = a_aclBuffBytes;
245 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
246 blob.in_size, blob.out, blob.out_size);
247 #endif /* USS_FS_DB */
249 code = CarefulPioctl(a_dirPath, VIOCGETAL, blobP, 1);
253 printf("%s: pioctl() failed, errno %d\n", rn, errno);
254 #endif /* USS_FS_DB */
261 /*------------------------------------------------------------------------
262 * EXPORTED uss_fs_SetACL
265 * Nothing interesting.
269 *------------------------------------------------------------------------*/
272 uss_fs_SetACL(a_dirPath, a_aclBuff, a_aclBuffBytes)
275 afs_int32 a_aclBuffBytes;
279 static char rn[] = "uss_fs_SetACL"; /*Routine name */
280 register afs_int32 code; /*pioctl() result */
283 blob.in_size = a_aclBuffBytes;
288 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
289 blob.in_size, blob.out, blob.out_size);
290 printf("%s: ACL value for dir '%s' is '%s'\n", rn, a_dirPath, a_aclBuff);
291 #endif /* USS_FS_DB */
293 code = CarefulPioctl(a_dirPath, VIOCSETAL, blobP, 1);
297 printf("%s: pioctl() failed, errno %d", rn, errno);
298 #endif /* USS_FS_DB */
305 /*------------------------------------------------------------------------
306 * EXPORTED uss_fs_GetVolStat
309 * Nothing interesting.
313 *------------------------------------------------------------------------*/
316 uss_fs_GetVolStat(a_mountpoint, a_volStatBuff, a_volStatBuffBytes)
319 afs_int32 a_volStatBuffBytes;
321 { /*uss_fs_GetVolStat */
323 static char rn[] = "uss_fs_GetVolStat"; /*Routine name */
324 register afs_int32 code; /*pioctl() result */
328 blob.out = a_volStatBuff;
329 blob.out_size = a_volStatBuffBytes;
332 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
333 blob.in_size, blob.out, blob.out_size);
334 #endif /* USS_FS_DB */
336 code = CarefulPioctl(a_mountpoint, VIOCGETVOLSTAT, blobP, 1);
340 printf("%s: pioctl() failed, errno %d", rn, errno);
341 #endif /* USS_FS_DB */
345 } /*uss_fs_GetVolStat */
348 /*------------------------------------------------------------------------
349 * EXPORTED uss_fs_SetVolStat
352 * Nothing interesting.
356 *------------------------------------------------------------------------*/
359 uss_fs_SetVolStat(a_mountpoint, a_volStatBuff, a_volStatBuffBytes)
362 afs_int32 a_volStatBuffBytes;
364 { /*uss_fs_SetVolStat */
366 static char rn[] = "uss_fs_SetVolStat"; /*Routine name */
367 register afs_int32 code; /*pioctl() result */
369 blob.in = a_volStatBuff;
370 blob.in_size = a_volStatBuffBytes;
371 blob.out = a_volStatBuff;
372 blob.out_size = USS_FS_MAX_SIZE;
375 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
376 blob.in_size, blob.out, blob.out_size);
377 #endif /* USS_FS_DB */
379 code = CarefulPioctl(a_mountpoint, VIOCSETVOLSTAT, blobP, 1);
383 printf("%s: pioctl() failed, errno %d", rn, errno);
384 #endif /* USS_FS_DB */
388 } /*uss_fs_SetVolStat */
391 /*------------------------------------------------------------------------
392 * EXPORTED uss_fs_CkBackups
395 * We are NOT careful here, since it's OK to get ENODEVs.
399 *------------------------------------------------------------------------*/
403 { /*uss_fs_CkBackups */
405 static char rn[] = "uss_fs_CkBackups"; /*Routine name */
406 register afs_int32 code; /*pioctl() result */
414 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
415 blob.in_size, blob.out, blob.out_size);
416 #endif /* USS_FS_DB */
418 code = pioctl(NULL, /*No pathname needed here */
419 VIOCCKBACK, /*CheckBackups */
421 1); /*Symlink disposition */
424 printf("%s: pioctl() failed, errno %d", rn, errno);
425 #endif /* USS_FS_DB */
429 } /*uss_fs_CkBackups */
432 /*------------------------------------------------------------------------
433 * EXPORTED uss_fs_MkMountPoint
436 * Uses uss_fs_OutBuff to construct the mountpoint contents.
440 *------------------------------------------------------------------------*/
443 uss_fs_MkMountPoint(a_volname, a_cellname, a_rw, a_mountpoint)
449 { /*uss_fs_MkMountPoint */
450 extern int local_Cell;
451 static char rn[] = "uss_fs_MkMountPoint"; /*Routine name */
452 register afs_int32 code; /*pioctl() result */
453 char *tp; /*Temporary */
457 ("%s: a_volname='%s', a_cellname='%s', a_rw=%d, a_mountpoint='%s'\n",
458 rn, a_volname, a_cellname, a_rw, a_mountpoint);
459 #endif /* USS_FS_DB */
462 * Make sure the parent directory is in AFS.
464 if (!InAFS(ParentAndComponent(a_mountpoint, uss_fs_OutBuff, &tp))) {
465 printf("%s: Mountpoints must be created within AFS\n", rn);
470 * Build the contents of the mountpoint we'll create. It's safe to
471 * use the uss_fs_OutBuff for this construction. Note: the last
472 * char, by convention, is a dot.
475 sprintf(uss_fs_OutBuff, "%s%s.", (a_rw ? "%" : "#"), a_volname);
477 sprintf(uss_fs_OutBuff, "%s%s:%s.", (a_rw ? "%" : "#"), a_cellname,
482 * Now, create the symlink with the above value.
484 code = symlink(uss_fs_OutBuff, a_mountpoint);
487 printf("%s: Mountpoint creation (symlink) failed, errno is %d\n", rn,
489 #endif /* USS_FS_DB */
493 } /*uss_fs_MkMountPoint */
496 /*------------------------------------------------------------------------
497 * EXPORTED uss_fs_RmMountPoint
500 * Nothing interesting.
504 *------------------------------------------------------------------------*/
507 uss_fs_RmMountPoint(a_mountpoint)
510 { /*uss_fs_RmMountPoint */
512 static char rn[] = "uss_fs_RmMountPoint"; /*Routine name */
513 register afs_int32 code; /*pioctl() result */
514 char *parentDirP; /*Ptr to parent */
515 char *componentP; /*Ptr to last component */
518 * Get the parent & final component names.
520 parentDirP = ParentAndComponent(a_mountpoint, uss_fs_InBuff, &componentP);
522 blob.in = componentP;
523 blob.in_size = strlen(componentP) + 1;
524 blob.out = uss_fs_OutBuff;
525 blob.out_size = USS_FS_MAX_SIZE;
528 printf("%s: AFS_STAT_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
529 rn, blob.in, blob.in_size, blob.out, blob.out_size);
530 #endif /* USS_FS_DB */
532 code = CarefulPioctl(parentDirP, VIOC_AFS_STAT_MT_PT, blobP, 1);
535 printf("%s: STAT_MT_PT pioctl() failed, errno %d", rn, errno);
536 #endif /* USS_FS_DB */
538 printf("%s: '%s' is not a mountpoint\n", rn, a_mountpoint);
543 * Now that we know we have a proper mountpoint, nuke it.
545 blob.in = componentP;
546 blob.in_size = strlen(componentP) + 1;
553 ("%s: AFS_DELETE_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
554 rn, blob.in, blob.in_size, blob.out, blob.out_size);
555 #endif /* USS_FS_DB */
557 code = pioctl(parentDirP, VIOC_AFS_DELETE_MT_PT, blobP, 1);
560 printf("%s: DELETE_MT_PT pioctl() failed, errno %d", rn, errno);
561 #endif /* USS_FS_DB */
564 printf("\t[Dry run - mount point '%s' NOT removed]\n", componentP);
568 } /*uss_fs_RmMountPoint */
571 #include <afs/auth.h>
573 struct ktc_token token;
574 struct ktc_principal service;
575 struct ktc_principal client;
580 * Build a list of tokens, delete the bad ones (the ones to remove from the
581 * permissions list,) destroy all tokens, and then re-register the good ones.
582 * Ugly, but it works.
584 uss_fs_UnlogToken(celln)
587 unsigned count = 0, index, index2;
588 afs_int32 code = 0, cnt = 0;
589 struct ktc_principal serviceName;
590 struct tokenInfo *tokenInfoP, *tp;
593 code = ktc_ListTokens(count, &count, &serviceName);
598 (struct tokenInfo *)malloc((sizeof(struct tokenInfo) * count));
599 for (code = index = index2 = 0; (!code) && (index < count); index++) {
600 tp = tokenInfoP + index;
601 code = ktc_ListTokens(index2, &index2, &tp->service);
604 ktc_GetToken(&tp->service, &tp->token,
605 sizeof(struct ktc_token), &tp->client);
607 tp->deleted = (!strcmp(celln, tp->client.cell) ? 1 : 0);
613 if (code = ktc_ForgetAllTokens()) {
614 printf("uss_fs_UnlogToken: could not discard tickets, code %d\n",
618 for (code = index = 0; index < count; index++) {
619 tp = tokenInfoP + index;
620 if (!(tp->deleted)) {
621 code = ktc_SetToken(&tp->service, &tp->token, &tp->client, 0);
624 ("uss_fs_UnlogToken: Couldn't re-register token, code = %d\n",