diff options
author | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
---|---|---|
committer | Cameron Katri <me@cameronkatri.com> | 2021-05-09 14:20:58 -0400 |
commit | 5fd83771641d15c418f747bd343ba6738d3875f7 (patch) | |
tree | 5abf0f78f680d9837dbd93d4d4c3933bb7509599 /diskdev_cmds/setclass.tproj/setclass.c | |
download | apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.gz apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.tar.zst apple_cmds-5fd83771641d15c418f747bd343ba6738d3875f7.zip |
Import macOS userland
adv_cmds-176
basic_cmds-55
bootstrap_cmds-116.100.1
developer_cmds-66
diskdev_cmds-667.40.1
doc_cmds-53.60.1
file_cmds-321.40.3
mail_cmds-35
misc_cmds-34
network_cmds-606.40.1
patch_cmds-17
remote_cmds-63
shell_cmds-216.60.1
system_cmds-880.60.2
text_cmds-106
Diffstat (limited to 'diskdev_cmds/setclass.tproj/setclass.c')
-rw-r--r-- | diskdev_cmds/setclass.tproj/setclass.c | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/diskdev_cmds/setclass.tproj/setclass.c b/diskdev_cmds/setclass.tproj/setclass.c new file mode 100644 index 0000000..306547b --- /dev/null +++ b/diskdev_cmds/setclass.tproj/setclass.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2010-2020 Apple Inc. All rights reserved. + */ +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/attr.h> + +/* from sys/cprotect.h */ + +#define PROTECTION_CLASS_A 1 +#define PROTECTION_CLASS_B 2 +#define PROTECTION_CLASS_C 3 +#define PROTECTION_CLASS_D 4 +#define PROTECTION_CLASS_E 5 +#define PROTECTION_CLASS_F 6 + +void +usage(void) +{ + printf("usage: setclass <path> [A-F]\n"); + printf("\tsets <path> to a protection class from A to F.\n"); + printf("\tIf no class is specified, reports the current class for <path>.\n"); + exit(0); +} + +int +chartoclass(char c) +{ + switch (c) { + /* directory 'unset' operation */ + case '0': + return 0; + case 'A': + case 'a': + return PROTECTION_CLASS_A; + case 'B': + case 'b': + return PROTECTION_CLASS_B; + case 'C': + case 'c': + return PROTECTION_CLASS_C; + case 'D': + case 'd': + return PROTECTION_CLASS_D; + case 'E': + case 'e': + return PROTECTION_CLASS_E; + case 'F': + case 'f': + return PROTECTION_CLASS_F; + default: + usage(); + exit(0); + } + return 0; +} + +char +classtochar(int class) +{ + if (class < 0) { + /* negative classes are invalid */ + return -1; + } + + /* otherwise, it must be >= 0... */ + if (class == 0) { + /* Directories are allowed to be "unset" */ + return 0; + } + return 'A' + (class - 1); +} + +int +main(int argc, char **argv) +{ + int error = 0, class = 0, do_set = 0; + static struct attrlist req = { + .bitmapcount = ATTR_BIT_MAP_COUNT, + .commonattr = ATTR_CMN_DATA_PROTECT_FLAGS + }; + + if ((argc < 2) || (argc > 3)) + usage(); + + if (argv[2]) { + do_set = 1; + class = chartoclass(*argv[2]); + } + + /* + * setclass and getclass for `argv[1]` using setattrlist(2) and + * getattrlist(2) respectively. + */ + if (do_set) { + struct { + uint32_t prot_class; + } __attribute__((packed, aligned(4))) attrs = { + .prot_class = class + }; + + error = setattrlist(argv[1], (void *)&req, &attrs, sizeof(attrs), + FSOPT_NOFOLLOW); + if (error) { + char new_class = classtochar(class); + if (new_class == 0) { + warn("could not set protection class of %s to (directory none)", + argv[1]); + } + else { + warn("could not set protection class of %s to %c", argv[1], + new_class); + } + } + } + else { + req.commonattr |= ATTR_CMN_RETURNED_ATTRS; + + struct { + uint32_t len; + attribute_set_t returned; + uint32_t prot_class; + } __attribute__((packed, aligned(4))) attrs; + + error = getattrlist(argv[1], (void *)&req, &attrs, sizeof(attrs), + FSOPT_NOFOLLOW); + if (error == -1 || attrs.len != sizeof(attrs) || + attrs.returned.commonattr != req.commonattr) { + if (error == -1) { + error = errno; + } + else { + error = EINVAL; + } + err(error, "could not get protection class"); + } + else { + class = attrs.prot_class; + char new_class = classtochar(class); + if (new_class == 0) { + printf("%s is in protection class (directory none) \n", argv[1]); + } + else { + printf("%s is in protection class %c\n", argv[1], new_class); + } + } + } + + return error; +} |