diff options
author | 2021-05-09 14:20:58 -0400 | |
---|---|---|
committer | 2021-05-09 14:20:58 -0400 | |
commit | 5fd83771641d15c418f747bd343ba6738d3875f7 (patch) | |
tree | 5abf0f78f680d9837dbd93d4d4c3933bb7509599 /diskdev_cmds/setclass.tproj | |
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')
-rw-r--r-- | diskdev_cmds/setclass.tproj/setclass.8 | 46 | ||||
-rw-r--r-- | diskdev_cmds/setclass.tproj/setclass.c | 153 |
2 files changed, 199 insertions, 0 deletions
diff --git a/diskdev_cmds/setclass.tproj/setclass.8 b/diskdev_cmds/setclass.tproj/setclass.8 new file mode 100644 index 0000000..90d0c80 --- /dev/null +++ b/diskdev_cmds/setclass.tproj/setclass.8 @@ -0,0 +1,46 @@ +.\" Copyright (c) 2010-2012 Apple Inc. All rights reserved. +.\" +.\" The contents of this file constitute Original Code as defined in and +.\" are subject to the Apple Public Source License Version 1.1 (the +.\" "License"). You may not use this file except in compliance with the +.\" License. Please obtain a copy of the License at +.\" http://www.apple.com/publicsource and read it before using this file. +.\" +.\" This Original Code and all software distributed under the License are +.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER +.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, +.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, +.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the +.\" License for the specific language governing rights and limitations +.\" under the License. +.\" +.\" @(#)setclass.8 +.Dd June 20, 2012 +.Dt SETCLASS 8 +.Os "Mac OS X" +.Sh NAME +.Nm setclass +.Nd content protection utility +.Sh SYNOPSIS +.Nm setclass +.Ar file +.Op A-E +.Sh DESCRIPTION +.Pp +The +.Nm +utility sets and gets the content protection class of a given file. +.Pp +If a class from A to E is specified, +.Nm +will attempt to set +.Ar file +to that class. +If no class is given, +.Nm +will report the current protection class of +.Ar file. +.Pp +Note that the ability to change the content protection class of a file is restricted by the +runtime status of the device in question. If the device is locked with a PIN code, then +you may not be able to modify the protection class, even as root. 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; +} |