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 <sys/ioccom.h>
27 #include <afs/venus.h>
29 #include <afs/sys_prototypes.h>
31 #include "uss_common.h"
32 #include "uss_fs.h" /*Interface to this module */
35 * ---------------------- Private definitions ---------------------
41 * ------------------------ Private globals -----------------------
43 static struct ViceIoctl blob
; /*Param-passing area */
44 static struct ViceIoctl
*blobP
= &blob
; /*Ptr to above */
47 /*------------------------------------------------------------------------
51 * Is the given pathname in AFS?
54 * a_path : Pathname to examine.
57 * 0 if the pathname is NOT in AFS,
61 * Nothing interesting.
65 *------------------------------------------------------------------------*/
74 blob
.out_size
= USS_FS_MAX_SIZE
;
75 blob
.out
= uss_fs_OutBuff
;
77 code
= pioctl(a_path
, VIOC_FILE_CELL_NAME
, blobP
, 1);
79 if ((errno
== EINVAL
) || (errno
== ENOENT
))
87 /*------------------------------------------------------------------------
88 * static ParentAndComponent
91 * Calculate the parent directory of the given pathname, along
92 * with the final component.
95 * char *a_path : Pathname to ancestorize.
96 * char *a_parentBuff : Ptr to parent buffer to use.
97 * char **a_componentPP : Ptr to the final component.
101 * Ptr to the buffer containing the parent dir name.
104 * Nothing interesting.
108 *------------------------------------------------------------------------*/
111 ParentAndComponent(char *a_path
, char *a_parentBuff
, char **a_componentPP
)
112 { /*ParentAndComponent */
116 * Copy over the original pathname, then find the location of the
117 * rightmost slash. If there is one, we chop off the string at
118 * point. Otherwise, it is a single pathname component whose
119 * parent must be the current working directory. In this case,
120 * we cheat and return ``.''.
122 strcpy(a_parentBuff
, a_path
);
123 rightSlashP
= (char *)strrchr(a_parentBuff
, '/');
126 *a_componentPP
= rightSlashP
+ 1;
128 strcpy(a_parentBuff
, ".");
129 *a_componentPP
= a_path
;
132 return (a_parentBuff
);
134 } /*ParentAndComponent */
137 /*------------------------------------------------------------------------
138 * static CarefulPioctl
141 * Execute a pioctl(), but be careful to refresh the Cache Manager's
142 * volume mapping in case we get an ENODEV the first time.
145 * char *a_path : pioctl() pathname argument.
146 * int a_opcode : pioctl() opcode.
147 * struct ViceIoctl *a_blobP : pioctl() blob pointer.
148 * int a_sl : pioctl() symlink info.
151 * Whatever the pioctl() returned, either the after the first
152 * call if we didn't get an ENODEV, or the results of the second
156 * Nothing interesting.
160 *------------------------------------------------------------------------*/
163 CarefulPioctl(char *a_path
, int a_opcode
, struct ViceIoctl
*a_blobP
, int a_sl
)
166 static char rn
[] = "uss_fs:CarefulPioctl";
171 * Call the pioctl() the first time, return if things worked
175 printf("%s: First pioctl call\n", rn
);
176 #endif /* USS_FS_DB */
177 code
= pioctl(a_path
, a_opcode
, a_blobP
, a_sl
);
180 printf("%s: First pioctl call fails, errno is %d\n", rn
, errno
);
181 #endif /* USS_FS_DB */
182 if ((code
== 0) || (code
&& (errno
!= ENODEV
)))
186 * Hmm, it's possible out volume mappings are stale. Let's
187 * bring them up to date, then try again.
190 printf("%s: First pioctl got a NODEV\n", rn
);
191 #endif /* USS_FS_DB */
192 code
= uss_fs_CkBackups();
193 code
= pioctl(a_path
, a_opcode
, a_blobP
, a_sl
);
199 /*------------------------------------------------------------------------
200 * EXPORTED uss_fs_GetACL
203 * Nothing interesting.
207 *------------------------------------------------------------------------*/
210 uss_fs_GetACL(char *a_dirPath
, char *a_aclBuff
, afs_int32 a_aclBuffBytes
)
213 static char rn
[] = "uss_fs_GetACL"; /*Routine name */
215 afs_int32 code
; /*pioctl() result */
219 blob
.out
= a_aclBuff
;
220 blob
.out_size
= a_aclBuffBytes
;
223 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn
, blob
.in
,
224 blob
.in_size
, blob
.out
, blob
.out_size
);
225 #endif /* USS_FS_DB */
227 code
= CarefulPioctl(a_dirPath
, VIOCGETAL
, blobP
, 1);
231 printf("%s: pioctl() failed, errno %d\n", rn
, errno
);
232 #endif /* USS_FS_DB */
239 /*------------------------------------------------------------------------
240 * EXPORTED uss_fs_SetACL
243 * Nothing interesting.
247 *------------------------------------------------------------------------*/
250 uss_fs_SetACL(char *a_dirPath
, char *a_aclBuff
, afs_int32 a_aclBuffBytes
)
253 static char rn
[] = "uss_fs_SetACL"; /*Routine name */
255 afs_int32 code
; /*pioctl() result */
258 blob
.in_size
= a_aclBuffBytes
;
263 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn
, blob
.in
,
264 blob
.in_size
, blob
.out
, blob
.out_size
);
265 printf("%s: ACL value for dir '%s' is '%s'\n", rn
, a_dirPath
, a_aclBuff
);
266 #endif /* USS_FS_DB */
268 code
= CarefulPioctl(a_dirPath
, VIOCSETAL
, blobP
, 1);
272 printf("%s: pioctl() failed, errno %d", rn
, errno
);
273 #endif /* USS_FS_DB */
280 /*------------------------------------------------------------------------
281 * EXPORTED uss_fs_GetVolStat
284 * Nothing interesting.
288 *------------------------------------------------------------------------*/
291 uss_fs_GetVolStat(char *a_mountpoint
, char *a_volStatBuff
,
292 afs_int32 a_volStatBuffBytes
)
293 { /*uss_fs_GetVolStat */
295 static char rn
[] = "uss_fs_GetVolStat"; /*Routine name */
297 afs_int32 code
; /*pioctl() result */
301 blob
.out
= a_volStatBuff
;
302 blob
.out_size
= a_volStatBuffBytes
;
305 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn
, blob
.in
,
306 blob
.in_size
, blob
.out
, blob
.out_size
);
307 #endif /* USS_FS_DB */
309 code
= CarefulPioctl(a_mountpoint
, VIOCGETVOLSTAT
, blobP
, 1);
313 printf("%s: pioctl() failed, errno %d", rn
, errno
);
314 #endif /* USS_FS_DB */
318 } /*uss_fs_GetVolStat */
321 /*------------------------------------------------------------------------
322 * EXPORTED uss_fs_SetVolStat
325 * Nothing interesting.
329 *------------------------------------------------------------------------*/
332 uss_fs_SetVolStat(char *a_mountpoint
, char *a_volStatBuff
,
333 afs_int32 a_volStatBuffBytes
)
334 { /*uss_fs_SetVolStat */
336 static char rn
[] = "uss_fs_SetVolStat"; /*Routine name */
338 afs_int32 code
; /*pioctl() result */
340 blob
.in
= a_volStatBuff
;
341 blob
.in_size
= a_volStatBuffBytes
;
342 blob
.out
= a_volStatBuff
;
343 blob
.out_size
= USS_FS_MAX_SIZE
;
346 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn
, blob
.in
,
347 blob
.in_size
, blob
.out
, blob
.out_size
);
348 #endif /* USS_FS_DB */
350 code
= CarefulPioctl(a_mountpoint
, VIOCSETVOLSTAT
, blobP
, 1);
354 printf("%s: pioctl() failed, errno %d", rn
, errno
);
355 #endif /* USS_FS_DB */
359 } /*uss_fs_SetVolStat */
362 /*------------------------------------------------------------------------
363 * EXPORTED uss_fs_CkBackups
366 * We are NOT careful here, since it's OK to get ENODEVs.
370 *------------------------------------------------------------------------*/
373 uss_fs_CkBackups(void)
374 { /*uss_fs_CkBackups */
376 static char rn
[] = "uss_fs_CkBackups"; /*Routine name */
378 afs_int32 code
; /*pioctl() result */
386 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn
, blob
.in
,
387 blob
.in_size
, blob
.out
, blob
.out_size
);
388 #endif /* USS_FS_DB */
390 code
= pioctl(NULL
, /*No pathname needed here */
391 VIOCCKBACK
, /*CheckBackups */
393 1); /*Symlink disposition */
396 printf("%s: pioctl() failed, errno %d", rn
, errno
);
397 #endif /* USS_FS_DB */
401 } /*uss_fs_CkBackups */
404 /*------------------------------------------------------------------------
405 * EXPORTED uss_fs_MkMountPoint
408 * Uses uss_fs_OutBuff to construct the mountpoint contents.
412 *------------------------------------------------------------------------*/
415 uss_fs_MkMountPoint(char *a_volname
, char *a_cellname
, afs_int32 a_rw
,
417 { /*uss_fs_MkMountPoint */
418 extern int local_Cell
;
419 static char rn
[] = "uss_fs_MkMountPoint"; /*Routine name */
420 afs_int32 code
; /*pioctl() result */
421 char *tp
; /*Temporary */
425 ("%s: a_volname='%s', a_cellname='%s', a_rw=%d, a_mountpoint='%s'\n",
426 rn
, a_volname
, a_cellname
, a_rw
, a_mountpoint
);
427 #endif /* USS_FS_DB */
430 * Make sure the parent directory is in AFS.
432 if (!InAFS(ParentAndComponent(a_mountpoint
, uss_fs_OutBuff
, &tp
))) {
433 printf("%s: Mountpoints must be created within AFS\n", rn
);
438 * Build the contents of the mountpoint we'll create. It's safe to
439 * use the uss_fs_OutBuff for this construction. Note: the last
440 * char, by convention, is a dot.
443 sprintf(uss_fs_OutBuff
, "%s%s.", (a_rw
? "%" : "#"), a_volname
);
445 sprintf(uss_fs_OutBuff
, "%s%s:%s.", (a_rw
? "%" : "#"), a_cellname
,
450 * Now, create the symlink with the above value.
452 code
= symlink(uss_fs_OutBuff
, a_mountpoint
);
455 printf("%s: Mountpoint creation (symlink) failed, errno is %d\n", rn
,
457 #endif /* USS_FS_DB */
461 } /*uss_fs_MkMountPoint */
464 /*------------------------------------------------------------------------
465 * EXPORTED uss_fs_RmMountPoint
468 * Nothing interesting.
472 *------------------------------------------------------------------------*/
475 uss_fs_RmMountPoint(char *a_mountpoint
)
476 { /*uss_fs_RmMountPoint */
477 static char rn
[] = "uss_fs_RmMountPoint"; /*Routine name */
478 afs_int32 code
; /*pioctl() result */
479 char *parentDirP
; /*Ptr to parent */
480 char *componentP
; /*Ptr to last component */
483 * Get the parent & final component names.
485 parentDirP
= ParentAndComponent(a_mountpoint
, uss_fs_InBuff
, &componentP
);
487 blob
.in
= componentP
;
488 blob
.in_size
= strlen(componentP
) + 1;
489 blob
.out
= uss_fs_OutBuff
;
490 blob
.out_size
= USS_FS_MAX_SIZE
;
493 printf("%s: AFS_STAT_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
494 rn
, blob
.in
, blob
.in_size
, blob
.out
, blob
.out_size
);
495 #endif /* USS_FS_DB */
497 code
= CarefulPioctl(parentDirP
, VIOC_AFS_STAT_MT_PT
, blobP
, 1);
500 printf("%s: STAT_MT_PT pioctl() failed, errno %d", rn
, errno
);
501 #endif /* USS_FS_DB */
503 printf("%s: '%s' is not a mountpoint\n", rn
, a_mountpoint
);
508 * Now that we know we have a proper mountpoint, nuke it.
510 blob
.in
= componentP
;
511 blob
.in_size
= strlen(componentP
) + 1;
518 ("%s: AFS_DELETE_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
519 rn
, blob
.in
, blob
.in_size
, blob
.out
, blob
.out_size
);
520 #endif /* USS_FS_DB */
522 code
= pioctl(parentDirP
, VIOC_AFS_DELETE_MT_PT
, blobP
, 1);
525 printf("%s: DELETE_MT_PT pioctl() failed, errno %d", rn
, errno
);
526 #endif /* USS_FS_DB */
529 printf("\t[Dry run - mount point '%s' NOT removed]\n", componentP
);
533 } /*uss_fs_RmMountPoint */
536 #include <afs/auth.h>
538 struct ktc_token token
;
539 struct ktc_principal service
;
540 struct ktc_principal client
;
545 * Build a list of tokens, delete the bad ones (the ones to remove from the
546 * permissions list,) destroy all tokens, and then re-register the good ones.
547 * Ugly, but it works.
550 uss_fs_UnlogToken(char *celln
)
552 int count
= 0, index
, index2
;
553 afs_int32 code
= 0, cnt
= 0;
554 struct ktc_principal serviceName
;
555 struct tokenInfo
*tokenInfoP
, *tp
;
558 code
= ktc_ListTokens(count
, &count
, &serviceName
);
562 tokenInfoP
= malloc((sizeof(struct tokenInfo
) * count
));
563 for (code
= index
= index2
= 0; (!code
) && (index
< count
); index
++) {
564 tp
= tokenInfoP
+ index
;
565 code
= ktc_ListTokens(index2
, &index2
, &tp
->service
);
568 ktc_GetToken(&tp
->service
, &tp
->token
,
569 sizeof(struct ktc_token
), &tp
->client
);
571 tp
->deleted
= (!strcmp(celln
, tp
->client
.cell
) ? 1 : 0);
577 if ((code
= ktc_ForgetAllTokens())) {
578 printf("uss_fs_UnlogToken: could not discard tickets, code %d\n",
582 for (index
= 0; index
< count
; index
++) {
583 tp
= tokenInfoP
+ index
;
584 if (!(tp
->deleted
)) {
585 code
= ktc_SetToken(&tp
->service
, &tp
->token
, &tp
->client
, 0);
588 ("uss_fs_UnlogToken: Couldn't re-register token, code = %d\n",