void *_policy_handle_find(struct pipes_struct *p, const struct policy_handle *hnd, uint32_t access_required, uint32_t *paccess_granted, const char *name, const char *location, NTSTATUS *pstatus) { struct dcesrv_handle *rpc_hnd; void *data; rpc_hnd = find_policy_by_hnd_internal(p, hnd, &data); if (rpc_hnd == NULL) { *pstatus = NT_STATUS_INVALID_HANDLE; return NULL; } if (strcmp(name, talloc_get_name(data)) != 0) { DEBUG(10, ("expected %s, got %s\n", name, talloc_get_name(data))); *pstatus = NT_STATUS_INVALID_HANDLE; return NULL; } if ((access_required & rpc_hnd->access_granted) != access_required) { if (root_mode()) { DEBUG(4, ("%s: ACCESS should be DENIED (granted: " "%#010x; required: %#010x)\n", location, rpc_hnd->access_granted, access_required)); DEBUGADD(4,("but overwritten by euid == 0\n")); goto okay; } DEBUG(2,("%s: ACCESS DENIED (granted: %#010x; required: " "%#010x)\n", location, rpc_hnd->access_granted, access_required)); *pstatus = NT_STATUS_ACCESS_DENIED; return NULL; } okay: DEBUG(10, ("found handle of type %s\n", talloc_get_name(data))); if (paccess_granted != NULL) { *paccess_granted = rpc_hnd->access_granted; } *pstatus = NT_STATUS_OK; return data; }
bool regkey_access_check(struct registry_key_handle *key, uint32_t requested, uint32_t *granted, const struct security_token *token ) { struct security_descriptor *sec_desc; NTSTATUS status; WERROR err; /* root free-pass, like we have on all other pipes like samr, lsa, etc. */ if (root_mode()) { *granted = REG_KEY_ALL; return true; } /* use the default security check if the backend has not defined its * own */ if (key->ops && key->ops->reg_access_check) { return key->ops->reg_access_check(key->name, requested, granted, token); } err = regkey_get_secdesc(talloc_tos(), key, &sec_desc); if (!W_ERROR_IS_OK(err)) { return false; } se_map_generic( &requested, ®_generic_map ); status =se_access_check(sec_desc, token, requested, granted); TALLOC_FREE(sec_desc); if (!NT_STATUS_IS_OK(status)) { return false; } return NT_STATUS_IS_OK(status); }
NTSTATUS access_check_object( struct security_descriptor *psd, struct security_token *token, enum sec_privilege needed_priv_1, enum sec_privilege needed_priv_2, uint32 rights_mask, uint32 des_access, uint32 *acc_granted, const char *debug ) { NTSTATUS status = NT_STATUS_ACCESS_DENIED; uint32 saved_mask = 0; bool priv_granted = false; bool is_system = false; bool is_root = false; /* Check if we are are the system token */ if (security_token_is_system(token) && security_token_system_privilege(token)) { is_system = true; } /* Check if we are root */ if (root_mode()) { is_root = true; } /* Check if we are root */ /* check privileges; certain SAM access bits should be overridden by privileges (mostly having to do with creating/modifying/deleting users and groups) */ if ((needed_priv_1 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_1)) || (needed_priv_2 != SEC_PRIV_INVALID && security_token_has_privilege(token, needed_priv_2))) { priv_granted = true; saved_mask = (des_access & rights_mask); des_access &= ~saved_mask; DEBUG(4,("access_check_object: user rights access mask [0x%x]\n", rights_mask)); } /* check the security descriptor first */ status = se_access_check(psd, token, des_access, acc_granted); if (NT_STATUS_IS_OK(status)) { goto done; } if (is_system || is_root) { DEBUG(4,("%s: ACCESS should be DENIED (requested: %#010x)\n", debug, des_access)); DEBUGADD(4,("but overritten by %s\n", is_root ? "euid == initial uid" : "system token")); priv_granted = true; *acc_granted = des_access; status = NT_STATUS_OK; goto done; } done: if (priv_granted) { /* add in any bits saved during the privilege check (only matters if status is ok) */ *acc_granted |= rights_mask; } DEBUG(4,("%s: access %s (requested: 0x%08x, granted: 0x%08x)\n", debug, NT_STATUS_IS_OK(status) ? "GRANTED" : "DENIED", des_access, *acc_granted)); return status; }