summaryrefslogtreecommitdiffstats
path: root/diskdev_cmds/setclass.tproj
diff options
context:
space:
mode:
authorCameron Katri <me@cameronkatri.com>2021-05-09 14:20:58 -0400
committerCameron Katri <me@cameronkatri.com>2021-05-09 14:20:58 -0400
commit5fd83771641d15c418f747bd343ba6738d3875f7 (patch)
tree5abf0f78f680d9837dbd93d4d4c3933bb7509599 /diskdev_cmds/setclass.tproj
downloadapple_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.846
-rw-r--r--diskdev_cmds/setclass.tproj/setclass.c153
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;
+}