Line data Source code
1 : /* 2 : * Unix SMB/CIFS implementation. 3 : * Group Policy Object Support 4 : * Copyright (C) Guenther Deschner 2007 5 : * 6 : * This program is free software; you can redistribute it and/or modify 7 : * it under the terms of the GNU General Public License as published by 8 : * the Free Software Foundation; either version 3 of the License, or 9 : * (at your option) any later version. 10 : * 11 : * This program is distributed in the hope that it will be useful, 12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : * GNU General Public License for more details. 15 : * 16 : * You should have received a copy of the GNU General Public License 17 : * along with this program; if not, see <http://www.gnu.org/licenses/>. 18 : */ 19 : 20 : #include "includes.h" 21 : #include "libcli/security/security.h" 22 : #include "../libgpo/gpo.h" 23 : #include "auth.h" 24 : #include "../librpc/ndr/libndr.h" 25 : 26 : /**************************************************************** 27 : ****************************************************************/ 28 : 29 4 : static bool gpo_sd_check_agp_object_guid(const struct security_ace_object *object) 30 : { 31 0 : struct GUID ext_right_apg_guid; 32 0 : NTSTATUS status; 33 : 34 4 : if (!object) { 35 0 : return false; 36 : } 37 : 38 4 : status = GUID_from_string(ADS_EXTENDED_RIGHT_APPLY_GROUP_POLICY, 39 : &ext_right_apg_guid); 40 4 : if (!NT_STATUS_IS_OK(status)) { 41 0 : return false; 42 : } 43 : 44 4 : switch (object->flags) { 45 4 : case SEC_ACE_OBJECT_TYPE_PRESENT: 46 4 : if (GUID_equal(&object->type.type, 47 : &ext_right_apg_guid)) { 48 4 : return true; 49 : } 50 : 51 0 : FALL_THROUGH; 52 : case SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT: 53 0 : if (GUID_equal(&object->inherited_type.inherited_type, 54 : &ext_right_apg_guid)) { 55 0 : return true; 56 : } 57 : 58 : FALL_THROUGH; 59 : default: 60 0 : break; 61 : } 62 : 63 0 : return false; 64 : } 65 : 66 : /**************************************************************** 67 : ****************************************************************/ 68 : 69 4 : static bool gpo_sd_check_agp_object(const struct security_ace *ace) 70 : { 71 4 : if (!sec_ace_object(ace->type)) { 72 0 : return false; 73 : } 74 : 75 4 : return gpo_sd_check_agp_object_guid(&ace->object.object); 76 : } 77 : 78 : /**************************************************************** 79 : ****************************************************************/ 80 : 81 4 : static bool gpo_sd_check_agp_access_bits(uint32_t access_mask) 82 : { 83 4 : return (access_mask & SEC_ADS_CONTROL_ACCESS); 84 : } 85 : 86 : #if 0 87 : /**************************************************************** 88 : ****************************************************************/ 89 : 90 : static bool gpo_sd_check_read_access_bits(uint32_t access_mask) 91 : { 92 : uint32_t read_bits = SEC_RIGHTS_LIST_CONTENTS | 93 : SEC_RIGHTS_READ_ALL_PROP | 94 : SEC_RIGHTS_READ_PERMS; 95 : 96 : return (read_bits == (access_mask & read_bits)); 97 : } 98 : #endif 99 : 100 : /**************************************************************** 101 : ****************************************************************/ 102 : 103 0 : static NTSTATUS gpo_sd_check_ace_denied_object(const struct security_ace *ace, 104 : const struct security_token *token) 105 : { 106 0 : if (gpo_sd_check_agp_object(ace) && 107 0 : gpo_sd_check_agp_access_bits(ace->access_mask) && 108 0 : security_token_has_sid(token, &ace->trustee)) { 109 0 : struct dom_sid_buf sid_str; 110 0 : DEBUG(10,("gpo_sd_check_ace_denied_object: " 111 : "Access denied as of ace for %s\n", 112 : dom_sid_str_buf(&ace->trustee, &sid_str))); 113 0 : return NT_STATUS_ACCESS_DENIED; 114 : } 115 : 116 0 : return STATUS_MORE_ENTRIES; 117 : } 118 : 119 : /**************************************************************** 120 : ****************************************************************/ 121 : 122 4 : static NTSTATUS gpo_sd_check_ace_allowed_object(const struct security_ace *ace, 123 : const struct security_token *token) 124 : { 125 8 : if (gpo_sd_check_agp_object(ace) && 126 8 : gpo_sd_check_agp_access_bits(ace->access_mask) && 127 4 : security_token_has_sid(token, &ace->trustee)) { 128 0 : struct dom_sid_buf sid_str; 129 4 : DEBUG(10,("gpo_sd_check_ace_allowed_object: " 130 : "Access granted as of ace for %s\n", 131 : dom_sid_str_buf(&ace->trustee, &sid_str))); 132 4 : return NT_STATUS_OK; 133 : } 134 : 135 0 : return STATUS_MORE_ENTRIES; 136 : } 137 : 138 : /**************************************************************** 139 : ****************************************************************/ 140 : 141 28 : static NTSTATUS gpo_sd_check_ace(const struct security_ace *ace, 142 : const struct security_token *token) 143 : { 144 28 : switch (ace->type) { 145 0 : case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: 146 0 : return gpo_sd_check_ace_denied_object(ace, token); 147 4 : case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: 148 4 : return gpo_sd_check_ace_allowed_object(ace, token); 149 24 : default: 150 24 : return STATUS_MORE_ENTRIES; 151 : } 152 : } 153 : 154 : /**************************************************************** 155 : ****************************************************************/ 156 : 157 4 : NTSTATUS gpo_apply_security_filtering(const struct GROUP_POLICY_OBJECT *gpo, 158 : const struct security_token *token) 159 24 : { 160 4 : struct security_descriptor *sd = gpo->security_descriptor; 161 4 : struct security_acl *dacl = NULL; 162 4 : NTSTATUS status = NT_STATUS_ACCESS_DENIED; 163 0 : int i; 164 : 165 4 : if (!token) { 166 0 : return NT_STATUS_INVALID_USER_BUFFER; 167 : } 168 : 169 4 : if (!sd) { 170 0 : return NT_STATUS_INVALID_SECURITY_DESCR; 171 : } 172 : 173 4 : dacl = sd->dacl; 174 4 : if (!dacl) { 175 0 : return NT_STATUS_INVALID_SECURITY_DESCR; 176 : } 177 : 178 : /* check all aces and only return NT_STATUS_OK (== Access granted) or 179 : * NT_STATUS_ACCESS_DENIED ( == Access denied) - the default is to 180 : * deny access */ 181 : 182 28 : for (i = 0; i < dacl->num_aces; i ++) { 183 : 184 28 : status = gpo_sd_check_ace(&dacl->aces[i], token); 185 : 186 28 : if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { 187 4 : return status; 188 28 : } else if (NT_STATUS_IS_OK(status)) { 189 4 : return status; 190 : } 191 : 192 24 : continue; 193 : } 194 : 195 0 : return NT_STATUS_ACCESS_DENIED; 196 : }