Пример #1
0
/**
 * Security descriptor / NT Token level access check function.
 */
bool can_access_file_acl(struct connection_struct *conn,
				const char * fname,
				uint32_t access_mask)
{
	NTSTATUS status;
	uint32_t access_granted;
	struct security_descriptor *secdesc = NULL;

	if (conn->server_info->utok.uid == 0 || conn->admin_user) {
		/* I'm sorry sir, I didn't know you were root... */
		return true;
	}

	status = SMB_VFS_GET_NT_ACL(conn, fname,
				    (OWNER_SECURITY_INFORMATION |
				     GROUP_SECURITY_INFORMATION |
				     DACL_SECURITY_INFORMATION),
				    &secdesc);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(5, ("Could not get acl: %s\n", nt_errstr(status)));
		return false;
	}

	status = se_access_check(secdesc, conn->server_info->ptok,
				 access_mask, &access_granted);
	TALLOC_FREE(secdesc);
	return NT_STATUS_IS_OK(status);
}
Пример #2
0
bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
			  const struct nt_user_token *token )
{
	SEC_DESC *sec_desc;
	NTSTATUS status;
	WERROR err;

	/* 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, &reg_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);
}
Пример #3
0
BOOL share_access_check(const NT_USER_TOKEN *token, const char *sharename,
			uint32 desired_access)
{
	uint32 granted;
	NTSTATUS status;
	TALLOC_CTX *mem_ctx = NULL;
	SEC_DESC *psd = NULL;
	size_t sd_size;
	BOOL ret = True;

	if (!(mem_ctx = talloc_init("share_access_check"))) {
		return False;
	}

	psd = get_share_security(mem_ctx, sharename, &sd_size);

	if (!psd) {
		TALLOC_FREE(mem_ctx);
		return True;
	}

	ret = se_access_check(psd, token, desired_access, &granted, &status);

	talloc_destroy(mem_ctx);
	return ret;
}
Пример #4
0
bool share_access_check(const struct security_token *token,
			const char *sharename,
			uint32 desired_access,
			uint32_t *pgranted)
{
	uint32 granted;
	NTSTATUS status;
	struct security_descriptor *psd = NULL;
	size_t sd_size;

	psd = get_share_security(talloc_tos(), sharename, &sd_size);

	if (!psd) {
		if (pgranted != NULL) {
			*pgranted = desired_access;
		}
		return false;
	}

	status = se_access_check(psd, token, desired_access, &granted);

	TALLOC_FREE(psd);

	if (pgranted != NULL) {
		*pgranted = granted;
	}

	return NT_STATUS_IS_OK(status);
}
Пример #5
0
BOOL emptysd_check(struct passwd *pw, int ngroups, gid_t *groups)
{
	uint32 acc_granted, status;
	BOOL result;

	/* For no DACL, access is allowed and the desired access mask is
	   returned */

	result = se_access_check(sd, pw->pw_uid, pw->pw_gid,
				 ngroups, groups, 
				 SEC_RIGHTS_MAXIMUM_ALLOWED,
				 &acc_granted, &status);
	
	if (!result || !(acc_granted == SEC_RIGHTS_MAXIMUM_ALLOWED)) {
		printf("FAIL: no dacl for %s (%d/%d)\n", pw->pw_name,
		       pw->pw_uid, pw->pw_gid);
		failed = True;
	}

	result = se_access_check(sd, pw->pw_uid, pw->pw_gid,
				 ngroups, groups, 0x1234,
				 &acc_granted, &status);
	
	if (!result || !(acc_granted == 0x1234)) {
		printf("FAIL: no dacl2 for %s (%d/%d)\n", pw->pw_name,
		       pw->pw_uid, pw->pw_gid);
		failed = True;
	}

	/* If desired access mask is empty then no access is allowed */

	result = se_access_check(sd, pw->pw_uid, pw->pw_gid,
				 ngroups, groups, 0,
				 &acc_granted, &status);
	
	if (result) {
		printf("FAIL: zero desired access for %s (%d/%d)\n",
		       pw->pw_name, pw->pw_uid, pw->pw_gid);
		failed = True;
	}
	
	return True;
}
Пример #6
0
BOOL test_user(char *username, uint32 acc_desired, uint32 *acc_granted)
{
	struct passwd *pw;
	uint32 status;

	if (!(pw = getpwnam(username))) {
		printf("FAIL: could not lookup user info for %s\n",
		       username);
		exit(1);
	}

	return se_access_check(sd, pw->pw_uid, pw->pw_gid, 0, NULL,
			       acc_desired, acc_granted, &status);
}
Пример #7
0
static bool elog_check_access( EVENTLOG_INFO *info, NT_USER_TOKEN *token )
{
	char *tdbname = elog_tdbname(talloc_tos(), info->logname );
	SEC_DESC *sec_desc;
	NTSTATUS status;

	if ( !tdbname )
		return False;

	/* get the security descriptor for the file */

	sec_desc = get_nt_acl_no_snum( info, tdbname );
	TALLOC_FREE( tdbname );

	if ( !sec_desc ) {
		DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
			tdbname));
		return False;
	}

	/* root free pass */

	if ( geteuid() == sec_initial_uid() ) {
		DEBUG(5,("elog_check_access: using root's token\n"));
		token = get_root_nt_token();
	}

	/* run the check, try for the max allowed */

	status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
		&info->access_granted);

	if ( sec_desc )
		TALLOC_FREE( sec_desc );

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(8,("elog_check_access: se_access_check() return %s\n",
			nt_errstr(status)));
		return False;
	}

	/* we have to have READ permission for a successful open */

	return ( info->access_granted & SA_RIGHT_FILE_READ_DATA );
}
bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
			  const struct nt_user_token *token )
{
	SEC_DESC *sec_desc;
	NTSTATUS status;
	WERROR err;
	TALLOC_CTX *mem_ctx;

	/* 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);
	}

	/*
	 * The secdesc routines can't yet cope with a NULL talloc ctx sanely.
	 */

	if (!(mem_ctx = talloc_init("regkey_access_check"))) {
		return false;
	}

	err = regkey_get_secdesc(mem_ctx, key, &sec_desc);

	if (!W_ERROR_IS_OK(err)) {
		TALLOC_FREE(mem_ctx);
		return false;
	}

	se_map_generic( &requested, &reg_generic_map );

	status =se_access_check(sec_desc, token, requested, granted);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(mem_ctx);
		return false;
	}

	TALLOC_FREE(mem_ctx);
	return NT_STATUS_IS_OK(status);
}
Пример #9
0
bool share_access_check(const NT_USER_TOKEN *token, const char *sharename,
			uint32 desired_access)
{
	uint32 granted;
	NTSTATUS status;
	SEC_DESC *psd = NULL;
	size_t sd_size;

	psd = get_share_security(talloc_tos(), sharename, &sd_size);

	if (!psd) {
		return True;
	}

	status = se_access_check(psd, token, desired_access, &granted);

	TALLOC_FREE(psd);

	return NT_STATUS_IS_OK(status);
}
Пример #10
0
bool regkey_access_check(struct registry_key_handle *key, uint32 requested,
			 uint32 *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 (geteuid() == sec_initial_uid()) {
		*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, &reg_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);
}
Пример #11
0
BOOL denysome_check(struct passwd *pw, int ngroups, gid_t *groups)
{
	uint32 acc_granted, status;
	fstring name;
	BOOL result;
	int len1, len2;

	/* Check only user1 and user3 denied access */

	result = se_access_check(sd, pw->pw_uid, pw->pw_gid,
				 ngroups, groups, 
				 SEC_RIGHTS_MAXIMUM_ALLOWED,
				 &acc_granted, &status);
	
	len1 = (int)strlen(pw->pw_name) - strlen("user1");
	len2 = (int)strlen(pw->pw_name) - strlen("user3");

	if ((strncmp("user1", &pw->pw_name[MAX(len1, 0)], 
		     strlen("user1")) == 0) ||
	    (strncmp("user3", &pw->pw_name[MAX(len2, 0)], 
		     strlen("user3")) == 0)) {
		if (result || acc_granted != 0) {
			printf("FAIL: access not denied for %s\n",
			       pw->pw_name);
		}
	} else {
		if (!result || acc_granted != GENERIC_ALL_ACCESS) {
			printf("FAIL: access denied for %s\n", pw->pw_name);
		}
	}

	printf("result %s for user %s\n", result ? "allowed" : "denied",
	       pw->pw_name);

	return True;
}
/*
  The main entry point for access checking FOR THE FILE SERVER ONLY !
  If returning ACCESS_DENIED this function returns the denied bits in
  the uint32_t pointed to by the access_granted pointer.
*/
NTSTATUS se_file_access_check(const struct security_descriptor *sd,
			  const struct security_token *token,
			  bool priv_open_requested,
			  uint32_t access_desired,
			  uint32_t *access_granted)
{
	uint32_t bits_remaining;
	NTSTATUS status;

	if (!priv_open_requested) {
		/* Fall back to generic se_access_check(). */
		return se_access_check(sd,
				token,
				access_desired,
				access_granted);
	}

	/*
	 * We need to handle the maximum allowed flag
	 * outside of se_access_check(), as we need to
	 * add in the access allowed by the privileges
	 * as well.
	 */

	if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
		uint32_t orig_access_desired = access_desired;

		access_desired |= access_check_max_allowed(sd, token);
		access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;

		if (security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
			access_desired |= SEC_RIGHTS_PRIV_BACKUP;
		}

		if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
			access_desired |= SEC_RIGHTS_PRIV_RESTORE;
		}

		DEBUG(10,("se_file_access_check: MAX desired = 0x%x "
			"mapped to 0x%x\n",
			orig_access_desired,
			access_desired));
	}

	status = se_access_check(sd,
				token,
				access_desired,
				access_granted);

	if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
		return status;
	}

	bits_remaining = *access_granted;

	/* Check if we should override with privileges. */
	if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
	    security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
		bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
	}
	if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
	    security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
		bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
	}
	if (bits_remaining != 0) {
		*access_granted = bits_remaining;
		return NT_STATUS_ACCESS_DENIED;
	}

	return NT_STATUS_OK;
}
Пример #13
0
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;

	/* 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;
	}

	/* give root a free pass */

	if ( geteuid() == sec_initial_uid() ) {

		DEBUG(4,("%s: ACCESS should be DENIED  (requested: %#010x)\n", debug, des_access));
		DEBUGADD(4,("but overritten by euid == sec_initial_uid()\n"));

		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;
}
Пример #14
0
static bool elog_check_access( EVENTLOG_INFO *info, const struct security_token *token )
{
	char *tdbname = elog_tdbname(talloc_tos(), info->logname );
	struct security_descriptor *sec_desc;
	struct security_ace *ace;
	NTSTATUS status;

	if ( !tdbname )
		return False;

	/* get the security descriptor for the file */

	sec_desc = get_nt_acl_no_snum( info, tdbname );
	TALLOC_FREE( tdbname );

	if ( !sec_desc ) {
		DEBUG(5,("elog_check_access: Unable to get NT ACL for %s\n",
			tdbname));
		return False;
	}

	ace = talloc_zero(sec_desc, struct security_ace);
	if (ace == NULL) {
		TALLOC_FREE(sec_desc);
		return false;
	}

	ace->type		= SEC_ACE_TYPE_ACCESS_ALLOWED;
	ace->flags		= 0;
	ace->access_mask	= REG_KEY_ALL;
	ace->trustee		= global_sid_System;

	status = security_descriptor_dacl_add(sec_desc, ace);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(sec_desc);
		return false;
	}

	/* root free pass */

	if ( geteuid() == sec_initial_uid() ) {
		DEBUG(5,("elog_check_access: running as root, using system token\n"));
		token = get_system_token();
	}

	/* run the check, try for the max allowed */

	status = se_access_check( sec_desc, token, MAXIMUM_ALLOWED_ACCESS,
		&info->access_granted);

	TALLOC_FREE(sec_desc);

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(8,("elog_check_access: se_access_check() return %s\n",
			nt_errstr(status)));
		return False;
	}

	/* we have to have READ permission for a successful open */

	return ( info->access_granted & SEC_FILE_READ_DATA );
}
Пример #15
0
NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call,
				     TALLOC_CTX *mem_ctx,
				     uint32_t access_desired,
				     struct lsa_policy_state **_state)
{
	struct auth_session_info *session_info = dce_call->conn->auth_state.session_info;
	enum security_user_level security_level;
	struct lsa_policy_state *state;
	struct ldb_result *dom_res;
	const char *dom_attrs[] = {
		"objectSid", 
		"objectGUID", 
		"nTMixedDomain",
		"fSMORoleOwner",
		NULL
	};
	char *p;
	int ret;

	state = talloc_zero(mem_ctx, struct lsa_policy_state);
	if (!state) {
		return NT_STATUS_NO_MEMORY;
	}

	/* make sure the sam database is accessible */
	state->sam_ldb = samdb_connect(state,
				       dce_call->event_ctx,
				       dce_call->conn->dce_ctx->lp_ctx,
				       dce_call->conn->auth_state.session_info,
				       dce_call->conn->remote_address,
				       0);
	if (state->sam_ldb == NULL) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	/* and the privilege database */
	state->pdb = privilege_connect(state, dce_call->conn->dce_ctx->lp_ctx);
	if (state->pdb == NULL) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	/* work out the domain_dn - useful for so many calls its worth
	   fetching here */
	state->domain_dn = ldb_get_default_basedn(state->sam_ldb);
	if (!state->domain_dn) {
		return NT_STATUS_NO_MEMORY;		
	}

	/* work out the forest root_dn - useful for so many calls its worth
	   fetching here */
	state->forest_dn = ldb_get_root_basedn(state->sam_ldb);
	if (!state->forest_dn) {
		return NT_STATUS_NO_MEMORY;		
	}

	ret = ldb_search(state->sam_ldb, mem_ctx, &dom_res,
			 state->domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
	if (ret != LDB_SUCCESS) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}
	if (dom_res->count != 1) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
	if (!state->domain_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");

	state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
	
	talloc_free(dom_res);

	state->domain_name = lpcfg_sam_name(dce_call->conn->dce_ctx->lp_ctx);

	state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
	if (!state->domain_dns) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}
	p = strchr(state->domain_dns, '/');
	if (p) {
		*p = '\0';
	}

	state->forest_dns = ldb_dn_canonical_string(state, state->forest_dn);
	if (!state->forest_dns) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}
	p = strchr(state->forest_dns, '/');
	if (p) {
		*p = '\0';
	}

	/* work out the builtin_dn - useful for so many calls its worth
	   fetching here */
	state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
	if (!state->builtin_dn) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	/* work out the system_dn - useful for so many calls its worth
	   fetching here */
	state->system_dn = samdb_search_dn(state->sam_ldb, state,
					   state->domain_dn, "(&(objectClass=container)(cn=System))");
	if (!state->system_dn) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
	if (!state->builtin_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->nt_authority_sid = dom_sid_parse_talloc(state, SID_NT_AUTHORITY);
	if (!state->nt_authority_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->creator_owner_domain_sid = dom_sid_parse_talloc(state, SID_CREATOR_OWNER_DOMAIN);
	if (!state->creator_owner_domain_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->world_domain_sid = dom_sid_parse_talloc(state, SID_WORLD_DOMAIN);
	if (!state->world_domain_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->sd = sddl_decode(state, DCESRV_LSA_POLICY_SD_SDDL,
				state->domain_sid);
	if (state->sd == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	state->sd->dacl->revision = SECURITY_ACL_REVISION_NT4;

	se_map_generic(&access_desired, &dcesrv_lsa_policy_mapping);
	security_acl_map_generic(state->sd->dacl, &dcesrv_lsa_policy_mapping);

	security_level = security_session_user_level(session_info, NULL);
	if (security_level >= SECURITY_SYSTEM) {
		/*
		 * The security descriptor doesn't allow system,
		 * but we want to allow system via ncalrpc as root.
		 */
		state->access_mask = access_desired;
		if (state->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
			state->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
			state->access_mask |= LSA_POLICY_ALL_ACCESS;
		}
	} else {
		NTSTATUS status;

		status = se_access_check(state->sd,
					 session_info->security_token,
					 access_desired,
					 &state->access_mask);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(2,("%s: access desired[0x%08X] rejected[0x%08X] - %s\n",
				 __func__,
				 (unsigned)access_desired,
				 (unsigned)state->access_mask,
				 nt_errstr(status)));
			return status;
		}
	}

	DEBUG(10,("%s: access desired[0x%08X] granted[0x%08X] - success.\n",
		  __func__,
		 (unsigned)access_desired,
		 (unsigned)state->access_mask));

	*_state = state;

	return NT_STATUS_OK;
}