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>
22 #include "uss_fs.h" /*Interface to this module */
23 #include <sys/types.h>
25 #include <sys/socket.h>
27 #include <sys/ioccom.h>
29 #include <netinet/in.h>
34 #include <afs/venus.h>
36 #include <afs/sys_prototypes.h>
37 #include "uss_common.h"
41 * ---------------------- Private definitions ---------------------
47 * ------------------------ Private globals -----------------------
49 static struct ViceIoctl blob; /*Param-passing area */
50 static struct ViceIoctl *blobP = &blob; /*Ptr to above */
53 /*------------------------------------------------------------------------
57 * Is the given pathname in AFS?
60 * a_path : Pathname to examine.
63 * 0 if the pathname is NOT in AFS,
67 * Nothing interesting.
71 *------------------------------------------------------------------------*/
80 blob.out_size = USS_FS_MAX_SIZE;
81 blob.out = uss_fs_OutBuff;
83 code = pioctl(a_path, VIOC_FILE_CELL_NAME, blobP, 1);
85 if ((errno == EINVAL) || (errno == ENOENT))
93 /*------------------------------------------------------------------------
94 * static ParentAndComponent
97 * Calculate the parent directory of the given pathname, along
98 * with the final component.
101 * char *a_path : Pathname to ancestorize.
102 * char *a_parentBuff : Ptr to parent buffer to use.
103 * char **a_componentPP : Ptr to the final component.
107 * Ptr to the buffer containing the parent dir name.
110 * Nothing interesting.
114 *------------------------------------------------------------------------*/
117 ParentAndComponent(char *a_path, char *a_parentBuff, char **a_componentPP)
118 { /*ParentAndComponent */
122 * Copy over the original pathname, then find the location of the
123 * rightmost slash. If there is one, we chop off the string at
124 * point. Otherwise, it is a single pathname component whose
125 * parent must be the current working directory. In this case,
126 * we cheat and return ``.''.
128 strcpy(a_parentBuff, a_path);
129 rightSlashP = (char *)strrchr(a_parentBuff, '/');
132 *a_componentPP = rightSlashP + 1;
134 strcpy(a_parentBuff, ".");
135 *a_componentPP = a_path;
138 return (a_parentBuff);
140 } /*ParentAndComponent */
143 /*------------------------------------------------------------------------
144 * static CarefulPioctl
147 * Execute a pioctl(), but be careful to refresh the Cache Manager's
148 * volume mapping in case we get an ENODEV the first time.
151 * char *a_path : pioctl() pathname argument.
152 * int a_opcode : pioctl() opcode.
153 * struct ViceIoctl *a_blobP : pioctl() blob pointer.
154 * int a_sl : pioctl() symlink info.
157 * Whatever the pioctl() returned, either the after the first
158 * call if we didn't get an ENODEV, or the results of the second
162 * Nothing interesting.
166 *------------------------------------------------------------------------*/
169 CarefulPioctl(char *a_path, int a_opcode, struct ViceIoctl *a_blobP, int a_sl)
172 static char rn[] = "uss_fs:CarefulPioctl";
177 * Call the pioctl() the first time, return if things worked
181 printf("%s: First pioctl call\n", rn);
182 #endif /* USS_FS_DB */
183 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
186 printf("%s: First pioctl call fails, errno is %d\n", rn, errno);
187 #endif /* USS_FS_DB */
188 if ((code == 0) || (code && (errno != ENODEV)))
192 * Hmm, it's possible out volume mappings are stale. Let's
193 * bring them up to date, then try again.
196 printf("%s: First pioctl got a NODEV\n", rn);
197 #endif /* USS_FS_DB */
198 code = uss_fs_CkBackups();
199 code = pioctl(a_path, a_opcode, a_blobP, a_sl);
205 /*------------------------------------------------------------------------
206 * EXPORTED uss_fs_GetACL
209 * Nothing interesting.
213 *------------------------------------------------------------------------*/
216 uss_fs_GetACL(char *a_dirPath, char *a_aclBuff, afs_int32 a_aclBuffBytes)
219 static char rn[] = "uss_fs_GetACL"; /*Routine name */
221 afs_int32 code; /*pioctl() result */
225 blob.out = a_aclBuff;
226 blob.out_size = a_aclBuffBytes;
229 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
230 blob.in_size, blob.out, blob.out_size);
231 #endif /* USS_FS_DB */
233 code = CarefulPioctl(a_dirPath, VIOCGETAL, blobP, 1);
237 printf("%s: pioctl() failed, errno %d\n", rn, errno);
238 #endif /* USS_FS_DB */
245 /*------------------------------------------------------------------------
246 * EXPORTED uss_fs_SetACL
249 * Nothing interesting.
253 *------------------------------------------------------------------------*/
256 uss_fs_SetACL(char *a_dirPath, char *a_aclBuff, afs_int32 a_aclBuffBytes)
259 static char rn[] = "uss_fs_SetACL"; /*Routine name */
261 afs_int32 code; /*pioctl() result */
264 blob.in_size = a_aclBuffBytes;
269 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
270 blob.in_size, blob.out, blob.out_size);
271 printf("%s: ACL value for dir '%s' is '%s'\n", rn, a_dirPath, a_aclBuff);
272 #endif /* USS_FS_DB */
274 code = CarefulPioctl(a_dirPath, VIOCSETAL, blobP, 1);
278 printf("%s: pioctl() failed, errno %d", rn, errno);
279 #endif /* USS_FS_DB */
286 /*------------------------------------------------------------------------
287 * EXPORTED uss_fs_GetVolStat
290 * Nothing interesting.
294 *------------------------------------------------------------------------*/
297 uss_fs_GetVolStat(char *a_mountpoint, char *a_volStatBuff,
298 afs_int32 a_volStatBuffBytes)
299 { /*uss_fs_GetVolStat */
301 static char rn[] = "uss_fs_GetVolStat"; /*Routine name */
303 afs_int32 code; /*pioctl() result */
307 blob.out = a_volStatBuff;
308 blob.out_size = a_volStatBuffBytes;
311 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
312 blob.in_size, blob.out, blob.out_size);
313 #endif /* USS_FS_DB */
315 code = CarefulPioctl(a_mountpoint, VIOCGETVOLSTAT, blobP, 1);
319 printf("%s: pioctl() failed, errno %d", rn, errno);
320 #endif /* USS_FS_DB */
324 } /*uss_fs_GetVolStat */
327 /*------------------------------------------------------------------------
328 * EXPORTED uss_fs_SetVolStat
331 * Nothing interesting.
335 *------------------------------------------------------------------------*/
338 uss_fs_SetVolStat(char *a_mountpoint, char *a_volStatBuff,
339 afs_int32 a_volStatBuffBytes)
340 { /*uss_fs_SetVolStat */
342 static char rn[] = "uss_fs_SetVolStat"; /*Routine name */
344 afs_int32 code; /*pioctl() result */
346 blob.in = a_volStatBuff;
347 blob.in_size = a_volStatBuffBytes;
348 blob.out = a_volStatBuff;
349 blob.out_size = USS_FS_MAX_SIZE;
352 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
353 blob.in_size, blob.out, blob.out_size);
354 #endif /* USS_FS_DB */
356 code = CarefulPioctl(a_mountpoint, VIOCSETVOLSTAT, blobP, 1);
360 printf("%s: pioctl() failed, errno %d", rn, errno);
361 #endif /* USS_FS_DB */
365 } /*uss_fs_SetVolStat */
368 /*------------------------------------------------------------------------
369 * EXPORTED uss_fs_CkBackups
372 * We are NOT careful here, since it's OK to get ENODEVs.
376 *------------------------------------------------------------------------*/
379 uss_fs_CkBackups(void)
380 { /*uss_fs_CkBackups */
382 static char rn[] = "uss_fs_CkBackups"; /*Routine name */
384 afs_int32 code; /*pioctl() result */
392 printf("%s: in 0x%x (%d bytes), out 0x%x, (%d bytes)\n", rn, blob.in,
393 blob.in_size, blob.out, blob.out_size);
394 #endif /* USS_FS_DB */
396 code = pioctl(NULL, /*No pathname needed here */
397 VIOCCKBACK, /*CheckBackups */
399 1); /*Symlink disposition */
402 printf("%s: pioctl() failed, errno %d", rn, errno);
403 #endif /* USS_FS_DB */
407 } /*uss_fs_CkBackups */
410 /*------------------------------------------------------------------------
411 * EXPORTED uss_fs_MkMountPoint
414 * Uses uss_fs_OutBuff to construct the mountpoint contents.
418 *------------------------------------------------------------------------*/
421 uss_fs_MkMountPoint(char *a_volname, char *a_cellname, afs_int32 a_rw,
423 { /*uss_fs_MkMountPoint */
424 extern int local_Cell;
425 static char rn[] = "uss_fs_MkMountPoint"; /*Routine name */
426 afs_int32 code; /*pioctl() result */
427 char *tp; /*Temporary */
431 ("%s: a_volname='%s', a_cellname='%s', a_rw=%d, a_mountpoint='%s'\n",
432 rn, a_volname, a_cellname, a_rw, a_mountpoint);
433 #endif /* USS_FS_DB */
436 * Make sure the parent directory is in AFS.
438 if (!InAFS(ParentAndComponent(a_mountpoint, uss_fs_OutBuff, &tp))) {
439 printf("%s: Mountpoints must be created within AFS\n", rn);
444 * Build the contents of the mountpoint we'll create. It's safe to
445 * use the uss_fs_OutBuff for this construction. Note: the last
446 * char, by convention, is a dot.
449 sprintf(uss_fs_OutBuff, "%s%s.", (a_rw ? "%" : "#"), a_volname);
451 sprintf(uss_fs_OutBuff, "%s%s:%s.", (a_rw ? "%" : "#"), a_cellname,
456 * Now, create the symlink with the above value.
458 code = symlink(uss_fs_OutBuff, a_mountpoint);
461 printf("%s: Mountpoint creation (symlink) failed, errno is %d\n", rn,
463 #endif /* USS_FS_DB */
467 } /*uss_fs_MkMountPoint */
470 /*------------------------------------------------------------------------
471 * EXPORTED uss_fs_RmMountPoint
474 * Nothing interesting.
478 *------------------------------------------------------------------------*/
481 uss_fs_RmMountPoint(char *a_mountpoint)
482 { /*uss_fs_RmMountPoint */
483 static char rn[] = "uss_fs_RmMountPoint"; /*Routine name */
484 afs_int32 code; /*pioctl() result */
485 char *parentDirP; /*Ptr to parent */
486 char *componentP; /*Ptr to last component */
489 * Get the parent & final component names.
491 parentDirP = ParentAndComponent(a_mountpoint, uss_fs_InBuff, &componentP);
493 blob.in = componentP;
494 blob.in_size = strlen(componentP) + 1;
495 blob.out = uss_fs_OutBuff;
496 blob.out_size = USS_FS_MAX_SIZE;
499 printf("%s: AFS_STAT_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
500 rn, blob.in, blob.in_size, blob.out, blob.out_size);
501 #endif /* USS_FS_DB */
503 code = CarefulPioctl(parentDirP, VIOC_AFS_STAT_MT_PT, blobP, 1);
506 printf("%s: STAT_MT_PT pioctl() failed, errno %d", rn, errno);
507 #endif /* USS_FS_DB */
509 printf("%s: '%s' is not a mountpoint\n", rn, a_mountpoint);
514 * Now that we know we have a proper mountpoint, nuke it.
516 blob.in = componentP;
517 blob.in_size = strlen(componentP) + 1;
524 ("%s: AFS_DELETE_MT_PT, in 0x%x (%d bytes), out 0x%x, (%d bytes)\n",
525 rn, blob.in, blob.in_size, blob.out, blob.out_size);
526 #endif /* USS_FS_DB */
528 code = pioctl(parentDirP, VIOC_AFS_DELETE_MT_PT, blobP, 1);
531 printf("%s: DELETE_MT_PT pioctl() failed, errno %d", rn, errno);
532 #endif /* USS_FS_DB */
535 printf("\t[Dry run - mount point '%s' NOT removed]\n", componentP);
539 } /*uss_fs_RmMountPoint */
542 #include <afs/auth.h>
544 struct ktc_token token;
545 struct ktc_principal service;
546 struct ktc_principal client;
551 * Build a list of tokens, delete the bad ones (the ones to remove from the
552 * permissions list,) destroy all tokens, and then re-register the good ones.
553 * Ugly, but it works.
556 uss_fs_UnlogToken(char *celln)
558 int count = 0, index, index2;
559 afs_int32 code = 0, cnt = 0;
560 struct ktc_principal serviceName;
561 struct tokenInfo *tokenInfoP, *tp;
564 code = ktc_ListTokens(count, &count, &serviceName);
569 (struct tokenInfo *)malloc((sizeof(struct tokenInfo) * count));
570 for (code = index = index2 = 0; (!code) && (index < count); index++) {
571 tp = tokenInfoP + index;
572 code = ktc_ListTokens(index2, &index2, &tp->service);
575 ktc_GetToken(&tp->service, &tp->token,
576 sizeof(struct ktc_token), &tp->client);
578 tp->deleted = (!strcmp(celln, tp->client.cell) ? 1 : 0);
584 if ((code = ktc_ForgetAllTokens())) {
585 printf("uss_fs_UnlogToken: could not discard tickets, code %d\n",
589 for (code = index = 0; index < count; index++) {
590 tp = tokenInfoP + index;
591 if (!(tp->deleted)) {
592 code = ktc_SetToken(&tp->service, &tp->token, &tp->client, 0);
595 ("uss_fs_UnlogToken: Couldn't re-register token, code = %d\n",