diff --git a/Makefile.am b/Makefile.am
index 5865eb098e920682ed632c804faefc3cbadcbaa9..f9ebfeb8dbdb7d134abddea8ff06ce75f7da093b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,6 +21,7 @@ ACLOCAL_AMFLAGS = -I autotools
 BUILD_BASH_COMPLETION = $(top_srcdir)/autotools/build-bash-completion
 RUN_IN_TEMPDIR = $(top_srcdir)/autotools/run-in-tempdir
 CHECK_PYTHON_CODE = $(top_srcdir)/autotools/check-python-code
+CHECK_HEADER = $(top_srcdir)/autotools/check-header
 CHECK_MAN = $(top_srcdir)/autotools/check-man
 CHECK_VERSION = $(top_srcdir)/autotools/check-version
 CHECK_NEWS = $(top_srcdir)/autotools/check-news
@@ -560,6 +561,7 @@ EXTRA_DIST = \
 	pylintrc \
 	autotools/build-bash-completion \
 	autotools/build-rpc \
+	autotools/check-header \
 	autotools/check-python-code \
 	autotools/check-imports \
 	autotools/check-man \
@@ -804,6 +806,7 @@ srclink_files = \
 check_python_code = \
 	$(BUILD_BASH_COMPLETION) \
 	$(CHECK_IMPORTS) \
+	$(CHECK_HEADER) \
 	$(DOCPP) \
 	$(all_python_code)
 
@@ -815,6 +818,7 @@ lint_python_code = \
 	$(pkglib_python_scripts) \
 	$(BUILD_BASH_COMPLETION) \
 	$(CHECK_IMPORTS) \
+	$(CHECK_HEADER) \
 	$(DOCPP) \
 	$(PYTHON_BOOTSTRAP)
 
@@ -829,6 +833,7 @@ pep8_python_code = \
 	$(dist_tools_PYTHON) \
 	$(pkglib_python_scripts) \
 	$(BUILD_BASH_COMPLETION) \
+	$(CHECK_HEADER) \
 	$(DOCPP) \
 	$(PYTHON_BOOTSTRAP) \
 	qa
@@ -1124,6 +1129,7 @@ check-dirs: $(BUILT_SOURCES)
 .PHONY: check-local
 check-local: check-dirs $(BUILT_SOURCES)
 	$(CHECK_PYTHON_CODE) $(check_python_code)
+	PYTHONPATH=. $(CHECK_HEADER) $(check_python_code)
 	$(CHECK_VERSION) $(VERSION) $(top_srcdir)/NEWS
 	$(CHECK_NEWS) < $(top_srcdir)/NEWS
 	PYTHONPATH=. $(RUN_IN_TEMPDIR) $(CURDIR)/$(CHECK_IMPORTS) . $(standalone_python_modules)
diff --git a/autotools/check-header b/autotools/check-header
new file mode 100755
index 0000000000000000000000000000000000000000..8ebaef2816134f4d032269af8d5c2e645d934c1d
--- /dev/null
+++ b/autotools/check-header
@@ -0,0 +1,139 @@
+#!/usr/bin/python
+#
+
+# Copyright (C) 2011 Google Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+"""Script to verify file header.
+
+"""
+
+# pylint: disable-msg=C0103
+# [C0103] Invalid name
+
+import sys
+import re
+import itertools
+
+from ganeti import constants
+from ganeti import utils
+from ganeti import compat
+
+
+#: Assume header is always in the first 8kB of a file
+_READ_SIZE = 8 * 1024
+
+_GPLv2 = [
+  "This program is free software; you can redistribute it and/or modify",
+  "it under the terms of the GNU General Public License as published by",
+  "the Free Software Foundation; either version 2 of the License, or",
+  "(at your option) any later version.",
+  "",
+  "This program is distributed in the hope that it will be useful, but",
+  "WITHOUT ANY WARRANTY; without even the implied warranty of",
+  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU",
+  "General Public License for more details.",
+  "",
+  "You should have received a copy of the GNU General Public License",
+  "along with this program; if not, write to the Free Software",
+  "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA",
+  "02110-1301, USA.",
+  ]
+
+
+_SHEBANG = re.compile(r"^#(?:|!(?:/usr/bin/python(?:| -u)|/bin/(?:|ba)sh))$")
+_COPYRIGHT_YEAR = r"20[01][0-9]"
+_COPYRIGHT = re.compile(r"# Copyright \(C\) (%s(?:, %s)*) Google Inc\.$" %
+                        (_COPYRIGHT_YEAR, _COPYRIGHT_YEAR))
+_COPYRIGHT_DESC = "Copyright (C) <year>[, <year> ...] Google Inc."
+_AUTOGEN = "# This file is automatically generated, do not edit!"
+
+
+class HeaderError(Exception):
+  pass
+
+
+def _Fail(lineno, msg):
+  raise HeaderError("Line %s: %s" % (lineno, msg))
+
+
+def _CheckHeader(getline_fn):
+  (lineno, line) = getline_fn()
+
+  if line == _AUTOGEN:
+    return
+
+  if not _SHEBANG.match(line):
+    _Fail(lineno, ("Must contain nothing but a hash character (#) or a"
+                   " shebang line (e.g. #!/bin/bash)"))
+
+  (lineno, line) = getline_fn()
+
+  if line == _AUTOGEN:
+    return
+
+  if line != "#":
+    _Fail(lineno, "Must contain nothing but hash character (#)")
+
+  (lineno, line) = getline_fn()
+  if line:
+    _Fail(lineno, "Must be empty")
+
+  (lineno, line) = getline_fn()
+  if not _COPYRIGHT.match(line):
+    _Fail(lineno, "Must contain copyright information (%s)" % _COPYRIGHT_DESC)
+
+  (lineno, line) = getline_fn()
+  if line != "#":
+    _Fail(lineno, "Must contain nothing but hash character (#)")
+
+  for licence_line in _GPLv2:
+    (lineno, line) = getline_fn()
+    if line != ("# %s" % licence_line).rstrip():
+      _Fail(lineno, "Does not match expected licence line (%s)" % licence_line)
+
+  (lineno, line) = getline_fn()
+  if line:
+    _Fail(lineno, "Must be empty")
+
+
+def Main():
+  """Main program.
+
+  """
+  fail = False
+
+  for filename in sys.argv[1:]:
+    content = utils.ReadFile(filename, size=_READ_SIZE)
+    lines = zip(itertools.count(1), content.splitlines())
+
+    try:
+      _CheckHeader(compat.partial(lines.pop, 0))
+    except HeaderError, err:
+      report = str(err)
+      print "%s: %s" % (filename, report)
+      fail = True
+
+  if fail:
+    sys.exit(constants.EXIT_FAILURE)
+  else:
+    sys.exit(constants.EXIT_SUCCESS)
+
+
+if __name__ == "__main__":
+  Main()