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>
23 #include "uss_fs.h" /*Interface to this module*/
24 #include <sys/types.h>
26 #include <sys/socket.h>
28 #include <sys/ioccom.h>
30 #include <netinet/in.h>
40 #include <afs/venus.h>
41 #include "uss_common.h"
45 * ---------------------- Private definitions ---------------------
51 * ------------------------ Private globals -----------------------
53 static struct ViceIoctl blob; /*Param-passing area*/
54 static struct ViceIoctl *blobP = &blob; /*Ptr to above*/
57 /*------------------------------------------------------------------------
61 * Is the given pathname in AFS?
64 * a_path : Pathname to examine.
67 * 0 if the pathname is NOT in AFS,
71 * Nothing interesting.
75 *------------------------------------------------------------------------*/
77 static int InAFS(a_path)
78 register char *a_path;
82 static char rn[] = "uss_fs:InAFS";
83 register afs_int32 code;
87 blob.out_size = USS_FS_MAX_SIZE;
88 blob.out = uss_fs_OutBuff;
90 code = pioctl(a_path, VIOC_FILE_CELL_NAME, blobP, 1);
92 if ((errno == EINVAL) || (errno == ENOENT))
100 /*------------------------------------------------------------------------
101 * static ParentAndComponent
104 * Calculate the parent directory of the given pathname, along
105 * with the final component.
108 * char *a_path : Pathname to ancestorize.
109 * char *a_parentBuff : Ptr to parent buffer to use.
110 * char **a_componentPP : Ptr to the final component.
114 * Ptr to the buffer containing the parent dir name.
117 * Nothing interesting.
121 *------------------------------------------------------------------------*/
123 static char *ParentAndComponent(a_path, a_parentBuff, a_componentPP)
126 char **a_componentPP;
128 { /*ParentAndComponent*/
130 static char rn[] = "uss_fs:Parent";
134 * Copy over the original pathname, then find the location of the
135 * rightmost slash. If there is one, we chop off the string at
136 * point. Otherwise, it is a single pathname component whose
137 * parent must be the current working directory. In this case,
138 * we cheat and return ``.''.
140 strcpy(a_parentBuff, a_path);
141 rightSlashP = (char *) strrchr(a_parentBuff, '/');
144 *a_componentPP = rightSlashP+1;
147 strcpy(a_parentBuff, ".");
148 *a_componentPP = a_path;
151 return(a_parentBuff);
153 } /*ParentAndComponent*/
156 /*------------------------------------------------------------------------
157 * static CarefulPioctl
160 * Execute a pioctl(), but be careful to refresh the Cache Manager's
161 * volume mapping in case we get an ENODEV the first time.
164 * char *a_path : pioctl() pathname argument.
165 * int a_opcode : pioctl() opcode.
166 * struct ViceIoctl *a_blobP : pioctl() blob pointer.
167 * int a_sl : pioctl() symlink info.
170 * Whatever the pioctl() returned, either the after the first
171 * call if we didn't get an ENODEV, or the results of the second
175 * Nothing interesting.
179 *------------------------------------------------------------------------*/
181 static int CarefulPioctl(a_path, a_opcode, a_blobP, a_sl)
184 struct ViceIoctl *a_blobP;
189 static char rn[] = "uss_fs:CarefulPioctl";
190 register afs_int32 code;
193 * Call the pioctl() the first time, return if things worked
197 printf("%s: First pioctl call\n", rn);
198 #endif /* USS_FS_DB */
199 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
202 printf("%s: First pioctl call fails, errno is %d\n",
204 #endif /* USS_FS_DB */
205 if ((code == 0) || (code && (errno != ENODEV)))
209 * Hmm, it's possible out volume mappings are stale. Let's
210 * bring them up to date, then try again.
213 printf("%s: First pioctl got a NODEV\n", rn);
214 #endif /* USS_FS_DB */
215 code = uss_fs_CkBackups();
216 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
222 /*------------------------------------------------------------------------
223 * EXPORTED uss_fs_GetACL
226 * Nothing interesting.
230 *------------------------------------------------------------------------*/
232 afs_int32 uss_fs_GetACL(a_dirPath, a_aclBuff, a_aclBuffBytes)
235 afs_int32 a_aclBuffBytes;
239 static char rn[] = "uss_fs_GetACL"; /*Routine name*/
240 register afs_int32 code; /*pioctl() result*/
244 blob.out = a_aclBuff;
245 blob.out_size = a_aclBuffBytes;
248 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
249 rn, blob.in, blob.in_size, blob.out, blob.out_size);
250 #endif /* USS_FS_DB */
252 code = CarefulPioctl(a_dirPath, VIOCGETAL, blobP, 1);
256 printf("%s: pioctl() failed, errno %d\n", rn, errno);
257 #endif /* USS_FS_DB */
264 /*------------------------------------------------------------------------
265 * EXPORTED uss_fs_SetACL
268 * Nothing interesting.
272 *------------------------------------------------------------------------*/
274 afs_int32 uss_fs_SetACL(a_dirPath, a_aclBuff, a_aclBuffBytes)
277 afs_int32 a_aclBuffBytes;
281 static char rn[] = "uss_fs_SetACL"; /*Routine name*/
282 register afs_int32 code; /*pioctl() result*/
285 blob.in_size = a_aclBuffBytes;
290 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
291 rn, blob.in, blob.in_size, blob.out, blob.out_size);
292 printf("%s: ACL value for dir '%s' is '%s'\n",
293 rn, a_dirPath, a_aclBuff);
294 #endif /* USS_FS_DB */
296 code = CarefulPioctl(a_dirPath, VIOCSETAL, blobP, 1);
300 printf("%s: pioctl() failed, errno %d", rn, errno);
301 #endif /* USS_FS_DB */
308 /*------------------------------------------------------------------------
309 * EXPORTED uss_fs_GetVolStat
312 * Nothing interesting.
316 *------------------------------------------------------------------------*/
318 afs_int32 uss_fs_GetVolStat(a_mountpoint, a_volStatBuff, a_volStatBuffBytes)
321 afs_int32 a_volStatBuffBytes;
323 { /*uss_fs_GetVolStat*/
325 static char rn[] = "uss_fs_GetVolStat"; /*Routine name*/
326 register afs_int32 code; /*pioctl() result*/
330 blob.out = a_volStatBuff;
331 blob.out_size = a_volStatBuffBytes;
334 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
335 rn, blob.in, blob.in_size, blob.out, blob.out_size);
336 #endif /* USS_FS_DB */
338 code = CarefulPioctl(a_mountpoint, VIOCGETVOLSTAT, blobP, 1);
342 printf("%s: pioctl() failed, errno %d", rn, errno);
343 #endif /* USS_FS_DB */
347 } /*uss_fs_GetVolStat*/
350 /*------------------------------------------------------------------------
351 * EXPORTED uss_fs_SetVolStat
354 * Nothing interesting.
358 *------------------------------------------------------------------------*/
360 afs_int32 uss_fs_SetVolStat(a_mountpoint, a_volStatBuff, a_volStatBuffBytes)
363 afs_int32 a_volStatBuffBytes;
365 { /*uss_fs_SetVolStat*/
367 static char rn[] = "uss_fs_SetVolStat"; /*Routine name*/
368 register afs_int32 code; /*pioctl() result*/
370 blob.in = a_volStatBuff;
371 blob.in_size = a_volStatBuffBytes;
372 blob.out = a_volStatBuff;
373 blob.out_size = USS_FS_MAX_SIZE;
376 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
377 rn, blob.in, blob.in_size, blob.out, blob.out_size);
378 #endif /* USS_FS_DB */
380 code = CarefulPioctl(a_mountpoint, VIOCSETVOLSTAT, blobP, 1);
384 printf("%s: pioctl() failed, errno %d", rn, errno);
385 #endif /* USS_FS_DB */
389 } /*uss_fs_SetVolStat*/
392 /*------------------------------------------------------------------------
393 * EXPORTED uss_fs_CkBackups
396 * We are NOT careful here, since it's OK to get ENODEVs.
400 *------------------------------------------------------------------------*/
402 afs_int32 uss_fs_CkBackups()
404 { /*uss_fs_CkBackups*/
406 static char rn[] = "uss_fs_CkBackups"; /*Routine name*/
407 register afs_int32 code; /*pioctl() result*/
415 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
416 rn, blob.in, blob.in_size, blob.out, blob.out_size);
417 #endif /* USS_FS_DB */
419 code = pioctl(NULL, /*No pathname needed here*/
420 VIOCCKBACK, /*CheckBackups*/
422 1); /*Symlink disposition*/
425 printf("%s: pioctl() failed, errno %d", rn, errno);
426 #endif /* USS_FS_DB */
430 } /*uss_fs_CkBackups*/
433 /*------------------------------------------------------------------------
434 * EXPORTED uss_fs_MkMountPoint
437 * Uses uss_fs_OutBuff to construct the mountpoint contents.
441 *------------------------------------------------------------------------*/
443 afs_int32 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*/
456 printf("%s: a_volname='%s', a_cellname='%s', a_rw=%d, a_mountpoint='%s'\n",
457 rn, a_volname, a_cellname, a_rw, a_mountpoint);
458 #endif /* USS_FS_DB */
461 * Make sure the parent directory is in AFS.
463 if (!InAFS(ParentAndComponent(a_mountpoint, uss_fs_OutBuff, &tp))) {
464 printf("%s: Mountpoints must be created within AFS\n", rn);
469 * Build the contents of the mountpoint we'll create. It's safe to
470 * use the uss_fs_OutBuff for this construction. Note: the last
471 * char, by convention, is a dot.
474 sprintf(uss_fs_OutBuff, "%s%s.",
478 sprintf(uss_fs_OutBuff, "%s%s:%s.",
485 * Now, create the symlink with the above value.
487 code = symlink(uss_fs_OutBuff, a_mountpoint);
490 printf("%s: Mountpoint creation (symlink) failed, errno is %d\n",
492 #endif /* USS_FS_DB */
496 } /*uss_fs_MkMountPoint*/
499 /*------------------------------------------------------------------------
500 * EXPORTED uss_fs_RmMountPoint
503 * Nothing interesting.
507 *------------------------------------------------------------------------*/
509 afs_int32 uss_fs_RmMountPoint(a_mountpoint)
512 { /*uss_fs_RmMountPoint*/
514 static char rn[] = "uss_fs_RmMountPoint"; /*Routine name*/
515 register afs_int32 code; /*pioctl() result*/
516 char *parentDirP; /*Ptr to parent*/
517 char *componentP; /*Ptr to last component*/
520 * Get the parent & final component names.
522 parentDirP = ParentAndComponent(a_mountpoint,
526 blob.in = componentP;
527 blob.in_size = strlen(componentP) + 1;
528 blob.out = uss_fs_OutBuff;
529 blob.out_size = USS_FS_MAX_SIZE;
532 printf("%s: AFS_STAT_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
533 rn, blob.in, blob.in_size, blob.out, blob.out_size);
534 #endif /* USS_FS_DB */
536 code = CarefulPioctl(parentDirP, VIOC_AFS_STAT_MT_PT, blobP, 1);
539 printf("%s: STAT_MT_PT pioctl() failed, errno %d", rn, errno);
540 #endif /* USS_FS_DB */
542 printf("%s: '%s' is not a mountpoint\n",
548 * Now that we know we have a proper mountpoint, nuke it.
550 blob.in = componentP;
551 blob.in_size = strlen(componentP) + 1;
557 printf("%s: AFS_DELETE_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
558 rn, blob.in, blob.in_size, blob.out, blob.out_size);
559 #endif /* USS_FS_DB */
561 code = pioctl(parentDirP, VIOC_AFS_DELETE_MT_PT, blobP, 1);
564 printf("%s: DELETE_MT_PT pioctl() failed, errno %d", rn, errno);
565 #endif /* USS_FS_DB */
568 printf("\t[Dry run - mount point '%s' NOT removed]\n", componentP);
572 } /*uss_fs_RmMountPoint*/
575 #include <afs/auth.h>
577 struct ktc_token token;
578 struct ktc_principal service;
579 struct ktc_principal client;
584 * Build a list of tokens, delete the bad ones (the ones to remove from the
585 * permissions list,) destroy all tokens, and then re-register the good ones.
586 * Ugly, but it works.
588 uss_fs_UnlogToken(celln)
591 unsigned count = 0, index, index2;
592 afs_int32 code = 0, cnt=0;
593 struct ktc_principal serviceName;
594 struct tokenInfo *tokenInfoP, *tp;
597 code = ktc_ListTokens(count, &count, &serviceName);
601 tokenInfoP = (struct tokenInfo *)malloc((sizeof(struct tokenInfo)*count));
602 for (code = index = index2= 0; (!code) && (index < count); index++) {
603 tp = tokenInfoP+index;
604 code = ktc_ListTokens(index2, &index2, &tp->service);
606 code = ktc_GetToken(&tp->service, &tp->token, sizeof(struct ktc_token),
609 tp->deleted = (!strcmp(celln, tp->client.cell) ? 1 : 0);
615 if (code = ktc_ForgetAllTokens ()) {
616 printf("uss_fs_UnlogToken: could not discard tickets, code %d\n", code);
619 for (code = index = 0; index < count ; index++) {
620 tp = tokenInfoP+index;
621 if (!(tp->deleted)) {
622 code = ktc_SetToken(&tp->service, &tp->token, &tp->client, 0);
624 printf("uss_fs_UnlogToken: Couldn't re-register token, code = %d\n",