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>
25 #include <sys/errno.h>
26 #include <sys/socket.h>
27 #include <sys/errno.h>
29 #include <sys/ioccom.h>
31 #include <netinet/in.h>
41 #include <afs/venus.h>
42 #include "uss_common.h"
47 * ---------------------- Private definitions ---------------------
53 * ------------------------ Private globals -----------------------
55 static struct ViceIoctl blob; /*Param-passing area*/
56 static struct ViceIoctl *blobP = &blob; /*Ptr to above*/
59 /*------------------------------------------------------------------------
63 * Is the given pathname in AFS?
66 * a_path : Pathname to examine.
69 * 0 if the pathname is NOT in AFS,
73 * Nothing interesting.
77 *------------------------------------------------------------------------*/
79 static int InAFS(a_path)
80 register char *a_path;
84 static char rn[] = "uss_fs:InAFS";
85 register afs_int32 code;
89 blob.out_size = USS_FS_MAX_SIZE;
90 blob.out = uss_fs_OutBuff;
92 code = pioctl(a_path, VIOC_FILE_CELL_NAME, blobP, 1);
94 if ((errno == EINVAL) || (errno == ENOENT))
102 /*------------------------------------------------------------------------
103 * static ParentAndComponent
106 * Calculate the parent directory of the given pathname, along
107 * with the final component.
110 * char *a_path : Pathname to ancestorize.
111 * char *a_parentBuff : Ptr to parent buffer to use.
112 * char **a_componentPP : Ptr to the final component.
116 * Ptr to the buffer containing the parent dir name.
119 * Nothing interesting.
123 *------------------------------------------------------------------------*/
125 static char *ParentAndComponent(a_path, a_parentBuff, a_componentPP)
128 char **a_componentPP;
130 { /*ParentAndComponent*/
132 static char rn[] = "uss_fs:Parent";
136 * Copy over the original pathname, then find the location of the
137 * rightmost slash. If there is one, we chop off the string at
138 * point. Otherwise, it is a single pathname component whose
139 * parent must be the current working directory. In this case,
140 * we cheat and return ``.''.
142 strcpy(a_parentBuff, a_path);
143 rightSlashP = (char *) strrchr(a_parentBuff, '/');
146 *a_componentPP = rightSlashP+1;
149 strcpy(a_parentBuff, ".");
150 *a_componentPP = a_path;
153 return(a_parentBuff);
155 } /*ParentAndComponent*/
158 /*------------------------------------------------------------------------
159 * static CarefulPioctl
162 * Execute a pioctl(), but be careful to refresh the Cache Manager's
163 * volume mapping in case we get an ENODEV the first time.
166 * char *a_path : pioctl() pathname argument.
167 * int a_opcode : pioctl() opcode.
168 * struct ViceIoctl *a_blobP : pioctl() blob pointer.
169 * int a_sl : pioctl() symlink info.
172 * Whatever the pioctl() returned, either the after the first
173 * call if we didn't get an ENODEV, or the results of the second
177 * Nothing interesting.
181 *------------------------------------------------------------------------*/
183 static int CarefulPioctl(a_path, a_opcode, a_blobP, a_sl)
186 struct ViceIoctl *a_blobP;
191 static char rn[] = "uss_fs:CarefulPioctl";
192 register afs_int32 code;
195 * Call the pioctl() the first time, return if things worked
199 printf("%s: First pioctl call\n", rn);
200 #endif /* USS_FS_DB */
201 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
204 printf("%s: First pioctl call fails, errno is %d\n",
206 #endif /* USS_FS_DB */
207 if ((code == 0) || (code && (errno != ENODEV)))
211 * Hmm, it's possible out volume mappings are stale. Let's
212 * bring them up to date, then try again.
215 printf("%s: First pioctl got a NODEV\n", rn);
216 #endif /* USS_FS_DB */
217 code = uss_fs_CkBackups();
218 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
224 /*------------------------------------------------------------------------
225 * EXPORTED uss_fs_GetACL
228 * Nothing interesting.
232 *------------------------------------------------------------------------*/
234 afs_int32 uss_fs_GetACL(a_dirPath, a_aclBuff, a_aclBuffBytes)
237 afs_int32 a_aclBuffBytes;
241 static char rn[] = "uss_fs_GetACL"; /*Routine name*/
242 register afs_int32 code; /*pioctl() result*/
246 blob.out = a_aclBuff;
247 blob.out_size = a_aclBuffBytes;
250 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
251 rn, blob.in, blob.in_size, blob.out, blob.out_size);
252 #endif /* USS_FS_DB */
254 code = CarefulPioctl(a_dirPath, VIOCGETAL, blobP, 1);
258 printf("%s: pioctl() failed, errno %d\n", rn, errno);
259 #endif /* USS_FS_DB */
266 /*------------------------------------------------------------------------
267 * EXPORTED uss_fs_SetACL
270 * Nothing interesting.
274 *------------------------------------------------------------------------*/
276 afs_int32 uss_fs_SetACL(a_dirPath, a_aclBuff, a_aclBuffBytes)
279 afs_int32 a_aclBuffBytes;
283 static char rn[] = "uss_fs_SetACL"; /*Routine name*/
284 register afs_int32 code; /*pioctl() result*/
287 blob.in_size = a_aclBuffBytes;
292 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
293 rn, blob.in, blob.in_size, blob.out, blob.out_size);
294 printf("%s: ACL value for dir '%s' is '%s'\n",
295 rn, a_dirPath, a_aclBuff);
296 #endif /* USS_FS_DB */
298 code = CarefulPioctl(a_dirPath, VIOCSETAL, blobP, 1);
302 printf("%s: pioctl() failed, errno %d", rn, errno);
303 #endif /* USS_FS_DB */
310 /*------------------------------------------------------------------------
311 * EXPORTED uss_fs_GetVolStat
314 * Nothing interesting.
318 *------------------------------------------------------------------------*/
320 afs_int32 uss_fs_GetVolStat(a_mountpoint, a_volStatBuff, a_volStatBuffBytes)
323 afs_int32 a_volStatBuffBytes;
325 { /*uss_fs_GetVolStat*/
327 static char rn[] = "uss_fs_GetVolStat"; /*Routine name*/
328 register afs_int32 code; /*pioctl() result*/
332 blob.out = a_volStatBuff;
333 blob.out_size = a_volStatBuffBytes;
336 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
337 rn, blob.in, blob.in_size, blob.out, blob.out_size);
338 #endif /* USS_FS_DB */
340 code = CarefulPioctl(a_mountpoint, VIOCGETVOLSTAT, blobP, 1);
344 printf("%s: pioctl() failed, errno %d", rn, errno);
345 #endif /* USS_FS_DB */
349 } /*uss_fs_GetVolStat*/
352 /*------------------------------------------------------------------------
353 * EXPORTED uss_fs_SetVolStat
356 * Nothing interesting.
360 *------------------------------------------------------------------------*/
362 afs_int32 uss_fs_SetVolStat(a_mountpoint, a_volStatBuff, a_volStatBuffBytes)
365 afs_int32 a_volStatBuffBytes;
367 { /*uss_fs_SetVolStat*/
369 static char rn[] = "uss_fs_SetVolStat"; /*Routine name*/
370 register afs_int32 code; /*pioctl() result*/
372 blob.in = a_volStatBuff;
373 blob.in_size = a_volStatBuffBytes;
374 blob.out = a_volStatBuff;
375 blob.out_size = USS_FS_MAX_SIZE;
378 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
379 rn, blob.in, blob.in_size, blob.out, blob.out_size);
380 #endif /* USS_FS_DB */
382 code = CarefulPioctl(a_mountpoint, VIOCSETVOLSTAT, blobP, 1);
386 printf("%s: pioctl() failed, errno %d", rn, errno);
387 #endif /* USS_FS_DB */
391 } /*uss_fs_SetVolStat*/
394 /*------------------------------------------------------------------------
395 * EXPORTED uss_fs_CkBackups
398 * We are NOT careful here, since it's OK to get ENODEVs.
402 *------------------------------------------------------------------------*/
404 afs_int32 uss_fs_CkBackups()
406 { /*uss_fs_CkBackups*/
408 static char rn[] = "uss_fs_CkBackups"; /*Routine name*/
409 register afs_int32 code; /*pioctl() result*/
417 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
418 rn, blob.in, blob.in_size, blob.out, blob.out_size);
419 #endif /* USS_FS_DB */
421 code = pioctl(NULL, /*No pathname needed here*/
422 VIOCCKBACK, /*CheckBackups*/
424 1); /*Symlink disposition*/
427 printf("%s: pioctl() failed, errno %d", rn, errno);
428 #endif /* USS_FS_DB */
432 } /*uss_fs_CkBackups*/
435 /*------------------------------------------------------------------------
436 * EXPORTED uss_fs_MkMountPoint
439 * Uses uss_fs_OutBuff to construct the mountpoint contents.
443 *------------------------------------------------------------------------*/
445 afs_int32 uss_fs_MkMountPoint(a_volname, a_cellname, a_rw, a_mountpoint)
451 { /*uss_fs_MkMountPoint*/
452 extern int local_Cell;
453 static char rn[] = "uss_fs_MkMountPoint"; /*Routine name*/
454 register afs_int32 code; /*pioctl() result*/
455 char *tp; /*Temporary*/
458 printf("%s: a_volname='%s', a_cellname='%s', a_rw=%d, a_mountpoint='%s'\n",
459 rn, a_volname, a_cellname, a_rw, a_mountpoint);
460 #endif /* USS_FS_DB */
463 * Make sure the parent directory is in AFS.
465 if (!InAFS(ParentAndComponent(a_mountpoint, uss_fs_OutBuff, &tp))) {
466 printf("%s: Mountpoints must be created within AFS\n", rn);
471 * Build the contents of the mountpoint we'll create. It's safe to
472 * use the uss_fs_OutBuff for this construction. Note: the last
473 * char, by convention, is a dot.
476 sprintf(uss_fs_OutBuff, "%s%s.",
480 sprintf(uss_fs_OutBuff, "%s%s:%s.",
487 * Now, create the symlink with the above value.
489 code = symlink(uss_fs_OutBuff, a_mountpoint);
492 printf("%s: Mountpoint creation (symlink) failed, errno is %d\n",
494 #endif /* USS_FS_DB */
498 } /*uss_fs_MkMountPoint*/
501 /*------------------------------------------------------------------------
502 * EXPORTED uss_fs_RmMountPoint
505 * Nothing interesting.
509 *------------------------------------------------------------------------*/
511 afs_int32 uss_fs_RmMountPoint(a_mountpoint)
514 { /*uss_fs_RmMountPoint*/
516 static char rn[] = "uss_fs_RmMountPoint"; /*Routine name*/
517 register afs_int32 code; /*pioctl() result*/
518 char *parentDirP; /*Ptr to parent*/
519 char *componentP; /*Ptr to last component*/
522 * Get the parent & final component names.
524 parentDirP = ParentAndComponent(a_mountpoint,
528 blob.in = componentP;
529 blob.in_size = strlen(componentP) + 1;
530 blob.out = uss_fs_OutBuff;
531 blob.out_size = USS_FS_MAX_SIZE;
534 printf("%s: AFS_STAT_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
535 rn, blob.in, blob.in_size, blob.out, blob.out_size);
536 #endif /* USS_FS_DB */
538 code = CarefulPioctl(parentDirP, VIOC_AFS_STAT_MT_PT, blobP, 1);
541 printf("%s: STAT_MT_PT pioctl() failed, errno %d", rn, errno);
542 #endif /* USS_FS_DB */
544 printf("%s: '%s' is not a mountpoint\n",
550 * Now that we know we have a proper mountpoint, nuke it.
552 blob.in = componentP;
553 blob.in_size = strlen(componentP) + 1;
559 printf("%s: AFS_DELETE_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
560 rn, blob.in, blob.in_size, blob.out, blob.out_size);
561 #endif /* USS_FS_DB */
563 code = pioctl(parentDirP, VIOC_AFS_DELETE_MT_PT, blobP, 1);
566 printf("%s: DELETE_MT_PT pioctl() failed, errno %d", rn, errno);
567 #endif /* USS_FS_DB */
570 printf("\t[Dry run - mount point '%s' NOT removed]\n", componentP);
574 } /*uss_fs_RmMountPoint*/
577 #include <afs/auth.h>
579 struct ktc_token token;
580 struct ktc_principal service;
581 struct ktc_principal client;
586 * Build a list of tokens, delete the bad ones (the ones to remove from the
587 * permissions list,) destroy all tokens, and then re-register the good ones.
588 * Ugly, but it works.
590 uss_fs_UnlogToken(celln)
593 unsigned count = 0, index, index2;
594 afs_int32 code = 0, cnt=0;
595 struct ktc_principal serviceName;
596 struct tokenInfo *tokenInfoP, *tp;
599 code = ktc_ListTokens(count, &count, &serviceName);
603 tokenInfoP = (struct tokenInfo *)malloc((sizeof(struct tokenInfo)*count));
604 for (code = index = index2= 0; (!code) && (index < count); index++) {
605 tp = tokenInfoP+index;
606 code = ktc_ListTokens(index2, &index2, &tp->service);
608 code = ktc_GetToken(&tp->service, &tp->token, sizeof(struct ktc_token),
611 tp->deleted = (!strcmp(celln, tp->client.cell) ? 1 : 0);
617 if (code = ktc_ForgetAllTokens ()) {
618 printf("uss_fs_UnlogToken: could not discard tickets, code %d\n", code);
621 for (code = index = 0; index < count ; index++) {
622 tp = tokenInfoP+index;
623 if (!(tp->deleted)) {
624 code = ktc_SetToken(&tp->service, &tp->token, &tp->client, 0);
626 printf("uss_fs_UnlogToken: Couldn't re-register token, code = %d\n",