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