File indexing completed on 2025-01-05 04:35:35

0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0002 // SPDX-FileCopyrightText: 2020-2022 Harald Sitter <sitter@kde.org>
0003 
0004 #include "debug.h"
0005 
0006 
0007 #include <QDebug>
0008 
0009 #include "acccrtl.h"
0010 #include "ace.h"
0011 #include "winnt.h"
0012 
0013 // Various helpful resources:
0014 // https://docs.microsoft.com/en-us/windows/win32/secauthz/access-control-entries
0015 // https://docs.microsoft.com/en-us/windows/win32/secauthz/access-rights-and-access-masks
0016 // https://docs.microsoft.com/en-us/windows/win32/secauthz/directory-services-access-rights
0017 // https://docs.microsoft.com/en-us/windows/win32/ad/example-code-for-setting-an-ace-on-a-directory-object
0018 // https://docs.microsoft.com/en-us/windows/win32/ad/control-access-rights
0019 // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/628ebb1d-c509-4ea0-a10f-77ef97ca4586
0020 // https://docs.microsoft.com/en-us/archive/blogs/openspecification/about-the-access_mask-structure
0021 // https://cpp.hotexamples.com/examples/-/-/GetAce/cpp-getace-function-examples.html
0022 // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-access_allowed_ace
0023 // https://docs.microsoft.com/en-us/windows/win32/secauthz/authorization-data-types
0024 
0025 void fprintf_binary(FILE *o, uint32_t v, bool newline)
0026 {
0027     uint32_t mask = 1 << ((sizeof(uint32_t) << 3) - 1);
0028     while (mask) {
0029         (void)fprintf(o, "%d", (v & mask ? 1 : 0));
0030         mask >>= 1;
0031     }
0032     if (newline) {
0033         (void)fprintf(o, "\n");
0034     }
0035 }
0036 
0037 void printType(const ACE &ace)
0038 {
0039     (void)fprintf(stderr, "ACE TYPE: %d :: ", ace.type);
0040     fprintf_binary(stderr, ace.type);
0041 
0042     switch (ace.type) {
0043     case ACCESS_ALLOWED_ACE_TYPE:
0044         qDebug() << "ACCESS_ALLOWED_ACE_TYPE";
0045         break;
0046     case ACCESS_DENIED_ACE_TYPE:
0047         qDebug() << "ACCESS_DENIED_ACE_TYPE";
0048         break;
0049     case SYSTEM_AUDIT_ACE_TYPE:
0050         qDebug() << "SYSTEM_AUDIT_ACE_TYPE";
0051         break;
0052     case SYSTEM_ALARM_ACE_TYPE:
0053         qDebug() << "SYSTEM_ALARM_ACE_TYPE";
0054         break;
0055     case SYSTEM_MANDATORY_LABEL_ACE_TYPE:
0056         qDebug() << "SYSTEM_MANDATORY_LABEL_ACE_TYPE";
0057         break;
0058     }
0059 
0060     // There's actually more, albeit not in winnt.h
0061     // Unclear if modeled inside samba.
0062     // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
0063 }
0064 
0065 QString check(unsigned int value)
0066 {
0067     if (value){
0068         return QStringLiteral("☒");
0069     }
0070     return QStringLiteral("☐");
0071 }
0072 
0073 void printMaskValue(const std::string_view name, unsigned int value)
0074 {
0075     qDebug() << qUtf8Printable(check(value)) << name.data();
0076 }
0077 
0078 #define MASK_VALUE(name) printMaskValue(#name, (m & name))
0079 
0080 void printFlags(const ACE &ace)
0081 {
0082     (void)fprintf(stderr, "ACE FLAGS: %d :: ", ace.flags);
0083     fprintf_binary(stderr, ace.flags);
0084 
0085     // https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-ace_header
0086     // https://docs.microsoft.com/en-us/windows/win32/wmisdk/namespace-ace-flag-constants
0087     // https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-inheritance-rules
0088     const auto m = ace.flags;
0089     MASK_VALUE(OBJECT_INHERIT_ACE);
0090     MASK_VALUE(CONTAINER_INHERIT_ACE);
0091     MASK_VALUE(FAILED_ACCESS_ACE_FLAG);
0092     MASK_VALUE(INHERIT_ONLY_ACE);
0093     MASK_VALUE(INHERITED_ACE);
0094     MASK_VALUE(NO_PROPAGATE_INHERIT_ACE);
0095     MASK_VALUE(SUCCESSFUL_ACCESS_ACE_FLAG);
0096 }
0097 
0098 void printMask(const ACE &ace)
0099 {
0100     (void)fprintf(stderr, "ACE MASK: %d :: ", ace.mask);
0101     fprintf_binary(stderr, ace.mask);
0102 
0103     const auto m = ace.mask;
0104 
0105     // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/945c4df5-4969-49c5-b1ce-59c1b3f35024
0106     MASK_VALUE(DELETE);
0107     MASK_VALUE(READ_CONTROL);
0108     MASK_VALUE(WRITE_DAC);
0109     MASK_VALUE(WRITE_OWNER);
0110     MASK_VALUE(SYNCHRONIZE);
0111     MASK_VALUE(STANDARD_RIGHTS_REQUIRED);
0112     MASK_VALUE(STANDARD_RIGHTS_READ);
0113     MASK_VALUE(STANDARD_RIGHTS_WRITE);
0114     MASK_VALUE(STANDARD_RIGHTS_EXECUTE);
0115     MASK_VALUE(STANDARD_RIGHTS_ALL);
0116     MASK_VALUE(SPECIFIC_RIGHTS_ALL);
0117     MASK_VALUE(GENERIC_READ);
0118     MASK_VALUE(GENERIC_WRITE);
0119     MASK_VALUE(GENERIC_EXECUTE);
0120     MASK_VALUE(GENERIC_ALL);
0121     MASK_VALUE(MAXIMUM_ALLOWED);
0122     MASK_VALUE(ACCESS_SYSTEM_SECURITY);
0123 
0124     // -------------------------------------------------
0125 
0126     // https://docs.microsoft.com/en-us/windows/win32/api/iaccess/nf-iaccess-iaccesscontrol-isaccessallowed
0127     MASK_VALUE(ACTRL_ACCESS_ALLOWED);
0128     MASK_VALUE(ACTRL_ACCESS_DENIED);
0129     MASK_VALUE(ACTRL_AUDIT_SUCCESS);
0130     MASK_VALUE(ACTRL_AUDIT_FAILURE);
0131     MASK_VALUE(ACTRL_ACCESS_PROTECTED);
0132     MASK_VALUE(ACTRL_SYSTEM_ACCESS);
0133     MASK_VALUE(ACTRL_DELETE);
0134     MASK_VALUE(ACTRL_READ_CONTROL);
0135     MASK_VALUE(ACTRL_CHANGE_ACCESS);
0136     MASK_VALUE(ACTRL_CHANGE_OWNER);
0137     MASK_VALUE(ACTRL_SYNCHRONIZE);
0138     MASK_VALUE(ACTRL_STD_RIGHTS_ALL);
0139     MASK_VALUE(ACTRL_STD_RIGHT_REQUIRED);
0140 
0141     MASK_VALUE(ACTRL_DS_OPEN);
0142     MASK_VALUE(ACTRL_DS_CREATE_CHILD);
0143     MASK_VALUE(ACTRL_DS_DELETE_CHILD);
0144     MASK_VALUE(ACTRL_DS_LIST);
0145     MASK_VALUE(ACTRL_DS_SELF);
0146     MASK_VALUE(ACTRL_DS_READ_PROP);
0147     MASK_VALUE(ACTRL_DS_WRITE_PROP);
0148     MASK_VALUE(ACTRL_DS_DELETE_TREE);
0149     MASK_VALUE(ACTRL_DS_LIST_OBJECT);
0150     MASK_VALUE(ACTRL_DS_CONTROL_ACCESS);
0151 
0152     MASK_VALUE(ACTRL_FILE_READ);
0153     MASK_VALUE(ACTRL_FILE_WRITE);
0154     MASK_VALUE(ACTRL_FILE_APPEND);
0155     MASK_VALUE(ACTRL_FILE_READ_PROP);
0156     MASK_VALUE(ACTRL_FILE_WRITE_PROP);
0157     MASK_VALUE(ACTRL_FILE_EXECUTE);
0158     MASK_VALUE(ACTRL_FILE_READ_ATTRIB);
0159     MASK_VALUE(ACTRL_FILE_WRITE_ATTRIB);
0160     MASK_VALUE(ACTRL_FILE_CREATE_PIPE);
0161 
0162     MASK_VALUE(ACTRL_DIR_LIST);
0163     MASK_VALUE(ACTRL_DIR_CREATE_OBJECT);
0164     MASK_VALUE(ACTRL_DIR_CREATE_CHILD);
0165     MASK_VALUE(ACTRL_DIR_DELETE_CHILD);
0166     MASK_VALUE(ACTRL_DIR_TRAVERSE);
0167 
0168     // -------------------------------------------------
0169 
0170     // NOTE: samba/librpc/idl/security.idl has also values but they seem duplicates
0171     //  of the windows ones. We should probably make a decision on what to use,
0172     //  wine is probably smarter from a code reuse perspective, the samba stuff
0173     //  isn't available in headers.
0174 }
0175 
0176 void printACE(const ACE &ace)
0177 {
0178     printType(ace);
0179     printFlags(ace);
0180     printMask(ace);
0181 }