예제 #1
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 );
}
예제 #2
0
파일: eventlog.c 프로젝트: gojdic/samba
ELOG_TDB *elog_open_tdb( const char *logname, bool force_clear, bool read_only )
{
	TDB_CONTEXT *tdb = NULL;
	uint32_t vers_id;
	ELOG_TDB *ptr;
	char *tdbpath = NULL;
	ELOG_TDB *tdb_node = NULL;
	char *eventlogdir;
	TALLOC_CTX *ctx = talloc_tos();

	/* check for invalid options */

	if (force_clear && read_only) {
		DEBUG(1,("elog_open_tdb: Invalid flags\n"));
		return NULL;
	}

	/* first see if we have an open context */

	for ( ptr=open_elog_list; ptr; ptr=ptr->next ) {
		if ( strequal( ptr->name, logname ) ) {
			ptr->ref_count++;

			/* trick to alow clearing of the eventlog tdb.
			   The force_clear flag should imply that someone
			   has done a force close.  So make sure the tdb
			   is NULL.  If this is a normal open, then just
			   return the existing reference */

			if ( force_clear ) {
				SMB_ASSERT( ptr->tdb == NULL );
				break;
			}
			else
				return ptr;
		}
	}

	/* make sure that the eventlog dir exists */

	eventlogdir = state_path( "eventlog" );
	if ( !directory_exist( eventlogdir ) )
		mkdir( eventlogdir, 0755 );

	/* get the path on disk */

	tdbpath = elog_tdbname(ctx, logname);
	if (!tdbpath) {
		return NULL;
	}

	DEBUG(7,("elog_open_tdb: Opening %s...(force_clear == %s)\n",
		tdbpath, force_clear?"True":"False" ));

	/* the tdb wasn't already open or this is a forced clear open */

	if ( !force_clear ) {

		tdb = tdb_open_log( tdbpath, 0, TDB_DEFAULT, read_only ? O_RDONLY : O_RDWR , 0 );
		if ( tdb ) {
			vers_id = tdb_fetch_int32( tdb, EVT_VERSION );

			if ( vers_id != EVENTLOG_DATABASE_VERSION_V1 ) {
				DEBUG(1,("elog_open_tdb: Invalid version [%d] on file [%s].\n",
					vers_id, tdbpath));
				tdb_close( tdb );
				tdb = elog_init_tdb( tdbpath );
			}
		}
	}

	if ( !tdb )
		tdb = elog_init_tdb( tdbpath );

	/* if we got a valid context, then add it to the list */

	if ( tdb ) {
		/* on a forced clear, just reset the tdb context if we already
		   have an open entry in the list */

		if ( ptr ) {
			ptr->tdb = tdb;
			return ptr;
		}

		if ( !(tdb_node = TALLOC_ZERO_P( NULL, ELOG_TDB)) ) {
			DEBUG(0,("elog_open_tdb: talloc() failure!\n"));
			tdb_close( tdb );
			return NULL;
		}

		tdb_node->name = talloc_strdup( tdb_node, logname );
		tdb_node->tdb = tdb;
		tdb_node->ref_count = 1;

		DLIST_ADD( open_elog_list, tdb_node );
	}

	return tdb_node;
}
예제 #3
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 );
}