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 <afs/param.h>
19 #include "uss_fs.h" /*Interface to this module*/
20 #include <sys/types.h>
21 #include <sys/errno.h>
22 #include <sys/socket.h>
23 #include <sys/errno.h>
25 #include <sys/ioccom.h>
27 #include <netinet/in.h>
28 #include <afs/venus.h>
29 #include "uss_common.h"
34 * ---------------------- Private definitions ---------------------
40 * ------------------------ Private globals -----------------------
42 static struct ViceIoctl blob; /*Param-passing area*/
43 static struct ViceIoctl *blobP = &blob; /*Ptr to above*/
46 /*------------------------------------------------------------------------
50 * Is the given pathname in AFS?
53 * a_path : Pathname to examine.
56 * 0 if the pathname is NOT in AFS,
60 * Nothing interesting.
64 *------------------------------------------------------------------------*/
66 static int InAFS(a_path)
67 register char *a_path;
71 static char rn[] = "uss_fs:InAFS";
72 register afs_int32 code;
76 blob.out_size = USS_FS_MAX_SIZE;
77 blob.out = uss_fs_OutBuff;
79 code = pioctl(a_path, VIOC_FILE_CELL_NAME, blobP, 1);
81 if ((errno == EINVAL) || (errno == ENOENT))
89 /*------------------------------------------------------------------------
90 * static ParentAndComponent
93 * Calculate the parent directory of the given pathname, along
94 * with the final component.
97 * char *a_path : Pathname to ancestorize.
98 * char *a_parentBuff : Ptr to parent buffer to use.
99 * char **a_componentPP : Ptr to the final component.
103 * Ptr to the buffer containing the parent dir name.
106 * Nothing interesting.
110 *------------------------------------------------------------------------*/
112 static char *ParentAndComponent(a_path, a_parentBuff, a_componentPP)
115 char **a_componentPP;
117 { /*ParentAndComponent*/
119 static char rn[] = "uss_fs:Parent";
123 * Copy over the original pathname, then find the location of the
124 * rightmost slash. If there is one, we chop off the string at
125 * point. Otherwise, it is a single pathname component whose
126 * parent must be the current working directory. In this case,
127 * we cheat and return ``.''.
129 strcpy(a_parentBuff, a_path);
130 rightSlashP = (char *) rindex(a_parentBuff, '/');
133 *a_componentPP = rightSlashP+1;
136 strcpy(a_parentBuff, ".");
137 *a_componentPP = a_path;
140 return(a_parentBuff);
142 } /*ParentAndComponent*/
145 /*------------------------------------------------------------------------
146 * static CarefulPioctl
149 * Execute a pioctl(), but be careful to refresh the Cache Manager's
150 * volume mapping in case we get an ENODEV the first time.
153 * char *a_path : pioctl() pathname argument.
154 * int a_opcode : pioctl() opcode.
155 * struct ViceIoctl *a_blobP : pioctl() blob pointer.
156 * int a_sl : pioctl() symlink info.
159 * Whatever the pioctl() returned, either the after the first
160 * call if we didn't get an ENODEV, or the results of the second
164 * Nothing interesting.
168 *------------------------------------------------------------------------*/
170 static int CarefulPioctl(a_path, a_opcode, a_blobP, a_sl)
173 struct ViceIoctl *a_blobP;
178 static char rn[] = "uss_fs:CarefulPioctl";
179 register afs_int32 code;
182 * Call the pioctl() the first time, return if things worked
186 printf("%s: First pioctl call\n", rn);
187 #endif /* USS_FS_DB */
188 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
191 printf("%s: First pioctl call fails, errno is %d\n",
193 #endif /* USS_FS_DB */
194 if ((code == 0) || (code && (errno != ENODEV)))
198 * Hmm, it's possible out volume mappings are stale. Let's
199 * bring them up to date, then try again.
202 printf("%s: First pioctl got a NODEV\n", rn);
203 #endif /* USS_FS_DB */
204 code = uss_fs_CkBackups();
205 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
211 /*------------------------------------------------------------------------
212 * EXPORTED uss_fs_GetACL
215 * Nothing interesting.
219 *------------------------------------------------------------------------*/
221 afs_int32 uss_fs_GetACL(a_dirPath, a_aclBuff, a_aclBuffBytes)
224 afs_int32 a_aclBuffBytes;
228 static char rn[] = "uss_fs_GetACL"; /*Routine name*/
229 register afs_int32 code; /*pioctl() result*/
233 blob.out = a_aclBuff;
234 blob.out_size = a_aclBuffBytes;
237 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
238 rn, blob.in, blob.in_size, blob.out, blob.out_size);
239 #endif /* USS_FS_DB */
241 code = CarefulPioctl(a_dirPath, VIOCGETAL, blobP, 1);
245 printf("%s: pioctl() failed, errno %d\n", rn, errno);
246 #endif /* USS_FS_DB */
253 /*------------------------------------------------------------------------
254 * EXPORTED uss_fs_SetACL
257 * Nothing interesting.
261 *------------------------------------------------------------------------*/
263 afs_int32 uss_fs_SetACL(a_dirPath, a_aclBuff, a_aclBuffBytes)
266 afs_int32 a_aclBuffBytes;
270 static char rn[] = "uss_fs_SetACL"; /*Routine name*/
271 register afs_int32 code; /*pioctl() result*/
274 blob.in_size = a_aclBuffBytes;
275 blob.out = (char *)0;
279 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
280 rn, blob.in, blob.in_size, blob.out, blob.out_size);
281 printf("%s: ACL value for dir '%s' is '%s'\n",
282 rn, a_dirPath, a_aclBuff);
283 #endif /* USS_FS_DB */
285 code = CarefulPioctl(a_dirPath, VIOCSETAL, blobP, 1);
289 printf("%s: pioctl() failed, errno %d", rn, errno);
290 #endif /* USS_FS_DB */
297 /*------------------------------------------------------------------------
298 * EXPORTED uss_fs_GetVolStat
301 * Nothing interesting.
305 *------------------------------------------------------------------------*/
307 afs_int32 uss_fs_GetVolStat(a_mountpoint, a_volStatBuff, a_volStatBuffBytes)
310 afs_int32 a_volStatBuffBytes;
312 { /*uss_fs_GetVolStat*/
314 static char rn[] = "uss_fs_GetVolStat"; /*Routine name*/
315 register afs_int32 code; /*pioctl() result*/
319 blob.out = a_volStatBuff;
320 blob.out_size = a_volStatBuffBytes;
323 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
324 rn, blob.in, blob.in_size, blob.out, blob.out_size);
325 #endif /* USS_FS_DB */
327 code = CarefulPioctl(a_mountpoint, VIOCGETVOLSTAT, blobP, 1);
331 printf("%s: pioctl() failed, errno %d", rn, errno);
332 #endif /* USS_FS_DB */
336 } /*uss_fs_GetVolStat*/
339 /*------------------------------------------------------------------------
340 * EXPORTED uss_fs_SetVolStat
343 * Nothing interesting.
347 *------------------------------------------------------------------------*/
349 afs_int32 uss_fs_SetVolStat(a_mountpoint, a_volStatBuff, a_volStatBuffBytes)
352 afs_int32 a_volStatBuffBytes;
354 { /*uss_fs_SetVolStat*/
356 static char rn[] = "uss_fs_SetVolStat"; /*Routine name*/
357 register afs_int32 code; /*pioctl() result*/
359 blob.in = a_volStatBuff;
360 blob.in_size = a_volStatBuffBytes;
361 blob.out = a_volStatBuff;
362 blob.out_size = USS_FS_MAX_SIZE;
365 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
366 rn, blob.in, blob.in_size, blob.out, blob.out_size);
367 #endif /* USS_FS_DB */
369 code = CarefulPioctl(a_mountpoint, VIOCSETVOLSTAT, blobP, 1);
373 printf("%s: pioctl() failed, errno %d", rn, errno);
374 #endif /* USS_FS_DB */
378 } /*uss_fs_SetVolStat*/
381 /*------------------------------------------------------------------------
382 * EXPORTED uss_fs_CkBackups
385 * We are NOT careful here, since it's OK to get ENODEVs.
389 *------------------------------------------------------------------------*/
391 afs_int32 uss_fs_CkBackups()
393 { /*uss_fs_CkBackups*/
395 static char rn[] = "uss_fs_CkBackups"; /*Routine name*/
396 register afs_int32 code; /*pioctl() result*/
400 blob.out = (char *)0;
404 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
405 rn, blob.in, blob.in_size, blob.out, blob.out_size);
406 #endif /* USS_FS_DB */
408 code = pioctl((char *)0, /*No pathname needed here*/
409 VIOCCKBACK, /*CheckBackups*/
411 1); /*Symlink disposition*/
414 printf("%s: pioctl() failed, errno %d", rn, errno);
415 #endif /* USS_FS_DB */
419 } /*uss_fs_CkBackups*/
422 /*------------------------------------------------------------------------
423 * EXPORTED uss_fs_MkMountPoint
426 * Uses uss_fs_OutBuff to construct the mountpoint contents.
430 *------------------------------------------------------------------------*/
432 afs_int32 uss_fs_MkMountPoint(a_volname, a_cellname, a_rw, a_mountpoint)
438 { /*uss_fs_MkMountPoint*/
439 extern int local_Cell;
440 static char rn[] = "uss_fs_MkMountPoint"; /*Routine name*/
441 register afs_int32 code; /*pioctl() result*/
442 char *tp; /*Temporary*/
445 printf("%s: a_volname='%s', a_cellname='%s', a_rw=%d, a_mountpoint='%s'\n",
446 rn, a_volname, a_cellname, a_rw, a_mountpoint);
447 #endif /* USS_FS_DB */
450 * Make sure the parent directory is in AFS.
452 if (!InAFS(ParentAndComponent(a_mountpoint, uss_fs_OutBuff, &tp))) {
453 printf("%s: Mountpoints must be created within AFS\n", rn);
458 * Build the contents of the mountpoint we'll create. It's safe to
459 * use the uss_fs_OutBuff for this construction. Note: the last
460 * char, by convention, is a dot.
463 sprintf(uss_fs_OutBuff, "%s%s.",
467 sprintf(uss_fs_OutBuff, "%s%s:%s.",
474 * Now, create the symlink with the above value.
476 code = symlink(uss_fs_OutBuff, a_mountpoint);
479 printf("%s: Mountpoint creation (symlink) failed, errno is %d\n",
481 #endif /* USS_FS_DB */
485 } /*uss_fs_MkMountPoint*/
488 /*------------------------------------------------------------------------
489 * EXPORTED uss_fs_RmMountPoint
492 * Nothing interesting.
496 *------------------------------------------------------------------------*/
498 afs_int32 uss_fs_RmMountPoint(a_mountpoint)
501 { /*uss_fs_RmMountPoint*/
503 static char rn[] = "uss_fs_RmMountPoint"; /*Routine name*/
504 register afs_int32 code; /*pioctl() result*/
505 char *parentDirP; /*Ptr to parent*/
506 char *componentP; /*Ptr to last component*/
509 * Get the parent & final component names.
511 parentDirP = ParentAndComponent(a_mountpoint,
515 blob.in = componentP;
516 blob.in_size = strlen(componentP) + 1;
517 blob.out = uss_fs_OutBuff;
518 blob.out_size = USS_FS_MAX_SIZE;
521 printf("%s: AFS_STAT_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
522 rn, blob.in, blob.in_size, blob.out, blob.out_size);
523 #endif /* USS_FS_DB */
525 code = CarefulPioctl(parentDirP, VIOC_AFS_STAT_MT_PT, blobP, 1);
528 printf("%s: STAT_MT_PT pioctl() failed, errno %d", rn, errno);
529 #endif /* USS_FS_DB */
531 printf("%s: '%s' is not a mountpoint\n",
537 * Now that we know we have a proper mountpoint, nuke it.
539 blob.in = componentP;
540 blob.in_size = strlen(componentP) + 1;
541 blob.out = (char *)0;
546 printf("%s: AFS_DELETE_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
547 rn, blob.in, blob.in_size, blob.out, blob.out_size);
548 #endif /* USS_FS_DB */
550 code = pioctl(parentDirP, VIOC_AFS_DELETE_MT_PT, blobP, 1);
553 printf("%s: DELETE_MT_PT pioctl() failed, errno %d", rn, errno);
554 #endif /* USS_FS_DB */
557 printf("\t[Dry run - mount point '%s' NOT removed]\n", componentP);
561 } /*uss_fs_RmMountPoint*/
564 #include <afs/auth.h>
566 struct ktc_token token;
567 struct ktc_principal service;
568 struct ktc_principal client;
573 * Build a list of tokens, delete the bad ones (the ones to remove from the
574 * permissions list,) destroy all tokens, and then re-register the good ones.
575 * Ugly, but it works.
577 uss_fs_UnlogToken(celln)
580 unsigned count = 0, index, index2;
581 afs_int32 code = 0, cnt=0;
582 struct ktc_principal serviceName;
583 struct tokenInfo *tokenInfoP, *tp;
586 code = ktc_ListTokens(count, &count, &serviceName);
590 tokenInfoP = (struct tokenInfo *)malloc((sizeof(struct tokenInfo)*count));
591 for (code = index = index2= 0; (!code) && (index < count); index++) {
592 tp = tokenInfoP+index;
593 code = ktc_ListTokens(index2, &index2, &tp->service);
595 code = ktc_GetToken(&tp->service, &tp->token, sizeof(struct ktc_token),
598 tp->deleted = (!strcmp(celln, tp->client.cell) ? 1 : 0);
604 if (code = ktc_ForgetAllTokens ()) {
605 printf("uss_fs_UnlogToken: could not discard tickets, code %d\n", code);
608 for (code = index = 0; index < count ; index++) {
609 tp = tokenInfoP+index;
610 if (!(tp->deleted)) {
611 code = ktc_SetToken(&tp->service, &tp->token, &tp->client, 0);
613 printf("uss_fs_UnlogToken: Couldn't re-register token, code = %d\n",